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
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"
54 #include "sched-int.h"
56 #include "tree-flow.h"
59 #include "tm-constrs.h"
61 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
64 #include "gstab.h" /* for N_SLINE */
67 #ifndef TARGET_NO_PROTOTYPE
68 #define TARGET_NO_PROTOTYPE 0
71 #define min(A,B) ((A) < (B) ? (A) : (B))
72 #define max(A,B) ((A) > (B) ? (A) : (B))
74 /* Structure used to define the rs6000 stack */
75 typedef struct rs6000_stack
{
76 int first_gp_reg_save
; /* first callee saved GP register used */
77 int first_fp_reg_save
; /* first callee saved FP register used */
78 int first_altivec_reg_save
; /* first callee saved AltiVec register used */
79 int lr_save_p
; /* true if the link reg needs to be saved */
80 int cr_save_p
; /* true if the CR reg needs to be saved */
81 unsigned int vrsave_mask
; /* mask of vec registers to save */
82 int push_p
; /* true if we need to allocate stack space */
83 int calls_p
; /* true if the function makes any calls */
84 int world_save_p
; /* true if we're saving *everything*:
85 r13-r31, cr, f14-f31, vrsave, v20-v31 */
86 enum rs6000_abi abi
; /* which ABI to use */
87 int gp_save_offset
; /* offset to save GP regs from initial SP */
88 int fp_save_offset
; /* offset to save FP regs from initial SP */
89 int altivec_save_offset
; /* offset to save AltiVec regs from initial SP */
90 int lr_save_offset
; /* offset to save LR from initial SP */
91 int cr_save_offset
; /* offset to save CR from initial SP */
92 int vrsave_save_offset
; /* offset to save VRSAVE from initial SP */
93 int spe_gp_save_offset
; /* offset to save spe 64-bit gprs */
94 int varargs_save_offset
; /* offset to save the varargs registers */
95 int ehrd_offset
; /* offset to EH return data */
96 int reg_size
; /* register size (4 or 8) */
97 HOST_WIDE_INT vars_size
; /* variable save area size */
98 int parm_size
; /* outgoing parameter size */
99 int save_size
; /* save area size */
100 int fixed_size
; /* fixed size of stack frame */
101 int gp_size
; /* size of saved GP registers */
102 int fp_size
; /* size of saved FP registers */
103 int altivec_size
; /* size of saved AltiVec registers */
104 int cr_size
; /* size to hold CR if not in save_size */
105 int vrsave_size
; /* size to hold VRSAVE if not in save_size */
106 int altivec_padding_size
; /* size of altivec alignment padding if
108 int spe_gp_size
; /* size of 64-bit GPR save size for SPE */
109 int spe_padding_size
;
110 HOST_WIDE_INT total_size
; /* total bytes allocated for stack */
111 int spe_64bit_regs_used
;
114 /* A C structure for machine-specific, per-function data.
115 This is added to the cfun structure. */
116 typedef struct GTY(()) machine_function
118 /* Some local-dynamic symbol. */
119 const char *some_ld_name
;
120 /* Whether the instruction chain has been scanned already. */
121 int insn_chain_scanned_p
;
122 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
123 int ra_needs_full_frame
;
124 /* Flags if __builtin_return_address (0) was used. */
126 /* Cache lr_save_p after expansion of builtin_eh_return. */
128 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
129 varargs save area. */
130 HOST_WIDE_INT varargs_save_offset
;
131 /* Temporary stack slot to use for SDmode copies. This slot is
132 64-bits wide and is allocated early enough so that the offset
133 does not overflow the 16-bit load/store offset field. */
134 rtx sdmode_stack_slot
;
137 /* Target cpu type */
139 enum processor_type rs6000_cpu
;
140 struct rs6000_cpu_select rs6000_select
[3] =
142 /* switch name, tune arch */
143 { (const char *)0, "--with-cpu=", 1, 1 },
144 { (const char *)0, "-mcpu=", 1, 1 },
145 { (const char *)0, "-mtune=", 1, 0 },
148 /* Always emit branch hint bits. */
149 static GTY(()) bool rs6000_always_hint
;
151 /* Schedule instructions for group formation. */
152 static GTY(()) bool rs6000_sched_groups
;
154 /* Align branch targets. */
155 static GTY(()) bool rs6000_align_branch_targets
;
157 /* Support for -msched-costly-dep option. */
158 const char *rs6000_sched_costly_dep_str
;
159 enum rs6000_dependence_cost rs6000_sched_costly_dep
;
161 /* Support for -minsert-sched-nops option. */
162 const char *rs6000_sched_insert_nops_str
;
163 enum rs6000_nop_insertion rs6000_sched_insert_nops
;
165 /* Support targetm.vectorize.builtin_mask_for_load. */
166 static GTY(()) tree altivec_builtin_mask_for_load
;
168 /* Size of long double. */
169 int rs6000_long_double_type_size
;
171 /* IEEE quad extended precision long double. */
174 /* Nonzero to use AltiVec ABI. */
175 int rs6000_altivec_abi
;
177 /* Nonzero if we want SPE SIMD instructions. */
180 /* Nonzero if we want SPE ABI extensions. */
183 /* Nonzero if floating point operations are done in the GPRs. */
184 int rs6000_float_gprs
= 0;
186 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
187 int rs6000_darwin64_abi
;
189 /* Set to nonzero once AIX common-mode calls have been defined. */
190 static GTY(()) int common_mode_defined
;
192 /* Label number of label created for -mrelocatable, to call to so we can
193 get the address of the GOT section */
194 int rs6000_pic_labelno
;
197 /* Which abi to adhere to */
198 const char *rs6000_abi_name
;
200 /* Semantics of the small data area */
201 enum rs6000_sdata_type rs6000_sdata
= SDATA_DATA
;
203 /* Which small data model to use */
204 const char *rs6000_sdata_name
= (char *)0;
206 /* Counter for labels which are to be placed in .fixup. */
207 int fixuplabelno
= 0;
210 /* Bit size of immediate TLS offsets and string from which it is decoded. */
211 int rs6000_tls_size
= 32;
212 const char *rs6000_tls_size_string
;
214 /* ABI enumeration available for subtarget to use. */
215 enum rs6000_abi rs6000_current_abi
;
217 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
221 const char *rs6000_debug_name
;
222 int rs6000_debug_stack
; /* debug stack applications */
223 int rs6000_debug_arg
; /* debug argument handling */
224 int rs6000_debug_reg
; /* debug register classes */
225 int rs6000_debug_addr
; /* debug memory addressing */
226 int rs6000_debug_cost
; /* debug rtx_costs */
228 /* Specify the machine mode that pointers have. After generation of rtl, the
229 compiler makes no further distinction between pointers and any other objects
230 of this machine mode. The type is unsigned since not all things that
231 include rs6000.h also include machmode.h. */
232 unsigned rs6000_pmode
;
234 /* Width in bits of a pointer. */
235 unsigned rs6000_pointer_size
;
238 /* Value is TRUE if register/mode pair is acceptable. */
239 bool rs6000_hard_regno_mode_ok_p
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
241 /* Maximum number of registers needed for a given register class and mode. */
242 unsigned char rs6000_class_max_nregs
[NUM_MACHINE_MODES
][LIM_REG_CLASSES
];
244 /* How many registers are needed for a given register and mode. */
245 unsigned char rs6000_hard_regno_nregs
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
247 /* Map register number to register class. */
248 enum reg_class rs6000_regno_regclass
[FIRST_PSEUDO_REGISTER
];
250 /* Reload functions based on the type and the vector unit. */
251 static enum insn_code rs6000_vector_reload
[NUM_MACHINE_MODES
][2];
253 /* Built in types. */
254 tree rs6000_builtin_types
[RS6000_BTI_MAX
];
255 tree rs6000_builtin_decls
[RS6000_BUILTIN_COUNT
];
257 const char *rs6000_traceback_name
;
259 traceback_default
= 0,
265 /* Flag to say the TOC is initialized */
267 char toc_label_name
[10];
269 /* Cached value of rs6000_variable_issue. This is cached in
270 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
271 static short cached_can_issue_more
;
273 static GTY(()) section
*read_only_data_section
;
274 static GTY(()) section
*private_data_section
;
275 static GTY(()) section
*read_only_private_data_section
;
276 static GTY(()) section
*sdata2_section
;
277 static GTY(()) section
*toc_section
;
279 /* Control alignment for fields within structures. */
280 /* String from -malign-XXXXX. */
281 int rs6000_alignment_flags
;
283 /* Code model for 64-bit linux. */
284 enum rs6000_cmodel cmodel
;
286 /* True for any options that were explicitly set. */
288 bool aix_struct_ret
; /* True if -maix-struct-ret was used. */
289 bool alignment
; /* True if -malign- was used. */
290 bool spe_abi
; /* True if -mabi=spe/no-spe was used. */
291 bool altivec_abi
; /* True if -mabi=altivec/no-altivec used. */
292 bool spe
; /* True if -mspe= was used. */
293 bool float_gprs
; /* True if -mfloat-gprs= was used. */
294 bool long_double
; /* True if -mlong-double- was used. */
295 bool ieee
; /* True if -mabi=ieee/ibmlongdouble used. */
296 bool vrsave
; /* True if -mvrsave was used. */
297 bool cmodel
; /* True if -mcmodel was used. */
298 } rs6000_explicit_options
;
300 struct builtin_description
302 /* mask is not const because we're going to alter it below. This
303 nonsense will go away when we rewrite the -march infrastructure
304 to give us more target flag bits. */
306 const enum insn_code icode
;
307 const char *const name
;
308 const enum rs6000_builtins code
;
311 /* Describe the vector unit used for modes. */
312 enum rs6000_vector rs6000_vector_unit
[NUM_MACHINE_MODES
];
313 enum rs6000_vector rs6000_vector_mem
[NUM_MACHINE_MODES
];
315 /* Register classes for various constraints that are based on the target
317 enum reg_class rs6000_constraints
[RS6000_CONSTRAINT_MAX
];
319 /* Describe the alignment of a vector. */
320 int rs6000_vector_align
[NUM_MACHINE_MODES
];
322 /* Map selected modes to types for builtins. */
323 static GTY(()) tree builtin_mode_to_type
[MAX_MACHINE_MODE
][2];
325 /* What modes to automatically generate reciprocal divide estimate (fre) and
326 reciprocal sqrt (frsqrte) for. */
327 unsigned char rs6000_recip_bits
[MAX_MACHINE_MODE
];
329 /* Masks to determine which reciprocal esitmate instructions to generate
331 enum rs6000_recip_mask
{
332 RECIP_SF_DIV
= 0x001, /* Use divide estimate */
333 RECIP_DF_DIV
= 0x002,
334 RECIP_V4SF_DIV
= 0x004,
335 RECIP_V2DF_DIV
= 0x008,
337 RECIP_SF_RSQRT
= 0x010, /* Use reciprocal sqrt estimate. */
338 RECIP_DF_RSQRT
= 0x020,
339 RECIP_V4SF_RSQRT
= 0x040,
340 RECIP_V2DF_RSQRT
= 0x080,
342 /* Various combination of flags for -mrecip=xxx. */
344 RECIP_ALL
= (RECIP_SF_DIV
| RECIP_DF_DIV
| RECIP_V4SF_DIV
345 | RECIP_V2DF_DIV
| RECIP_SF_RSQRT
| RECIP_DF_RSQRT
346 | RECIP_V4SF_RSQRT
| RECIP_V2DF_RSQRT
),
348 RECIP_HIGH_PRECISION
= RECIP_ALL
,
350 /* On low precision machines like the power5, don't enable double precision
351 reciprocal square root estimate, since it isn't accurate enough. */
352 RECIP_LOW_PRECISION
= (RECIP_ALL
& ~(RECIP_DF_RSQRT
| RECIP_V2DF_RSQRT
))
355 static unsigned int rs6000_recip_control
;
356 static const char *rs6000_recip_name
;
358 /* -mrecip options. */
361 const char *string
; /* option name */
362 unsigned int mask
; /* mask bits to set */
363 } recip_options
[] = {
364 { "all", RECIP_ALL
},
365 { "none", RECIP_NONE
},
366 { "div", (RECIP_SF_DIV
| RECIP_DF_DIV
| RECIP_V4SF_DIV
368 { "divf", (RECIP_SF_DIV
| RECIP_V4SF_DIV
) },
369 { "divd", (RECIP_DF_DIV
| RECIP_V2DF_DIV
) },
370 { "rsqrt", (RECIP_SF_RSQRT
| RECIP_DF_RSQRT
| RECIP_V4SF_RSQRT
371 | RECIP_V2DF_RSQRT
) },
372 { "rsqrtf", (RECIP_SF_RSQRT
| RECIP_V4SF_RSQRT
) },
373 { "rsqrtd", (RECIP_DF_RSQRT
| RECIP_V2DF_RSQRT
) },
376 /* 2 argument gen function typedef. */
377 typedef rtx (*gen_2arg_fn_t
) (rtx
, rtx
, rtx
);
380 /* Target cpu costs. */
382 struct processor_costs
{
383 const int mulsi
; /* cost of SImode multiplication. */
384 const int mulsi_const
; /* cost of SImode multiplication by constant. */
385 const int mulsi_const9
; /* cost of SImode mult by short constant. */
386 const int muldi
; /* cost of DImode multiplication. */
387 const int divsi
; /* cost of SImode division. */
388 const int divdi
; /* cost of DImode division. */
389 const int fp
; /* cost of simple SFmode and DFmode insns. */
390 const int dmul
; /* cost of DFmode multiplication (and fmadd). */
391 const int sdiv
; /* cost of SFmode division (fdivs). */
392 const int ddiv
; /* cost of DFmode division (fdiv). */
393 const int cache_line_size
; /* cache line size in bytes. */
394 const int l1_cache_size
; /* size of l1 cache, in kilobytes. */
395 const int l2_cache_size
; /* size of l2 cache, in kilobytes. */
396 const int simultaneous_prefetches
; /* number of parallel prefetch
400 const struct processor_costs
*rs6000_cost
;
402 /* Processor costs (relative to an add) */
404 /* Instruction size costs on 32bit processors. */
406 struct processor_costs size32_cost
= {
407 COSTS_N_INSNS (1), /* mulsi */
408 COSTS_N_INSNS (1), /* mulsi_const */
409 COSTS_N_INSNS (1), /* mulsi_const9 */
410 COSTS_N_INSNS (1), /* muldi */
411 COSTS_N_INSNS (1), /* divsi */
412 COSTS_N_INSNS (1), /* divdi */
413 COSTS_N_INSNS (1), /* fp */
414 COSTS_N_INSNS (1), /* dmul */
415 COSTS_N_INSNS (1), /* sdiv */
416 COSTS_N_INSNS (1), /* ddiv */
423 /* Instruction size costs on 64bit processors. */
425 struct processor_costs size64_cost
= {
426 COSTS_N_INSNS (1), /* mulsi */
427 COSTS_N_INSNS (1), /* mulsi_const */
428 COSTS_N_INSNS (1), /* mulsi_const9 */
429 COSTS_N_INSNS (1), /* muldi */
430 COSTS_N_INSNS (1), /* divsi */
431 COSTS_N_INSNS (1), /* divdi */
432 COSTS_N_INSNS (1), /* fp */
433 COSTS_N_INSNS (1), /* dmul */
434 COSTS_N_INSNS (1), /* sdiv */
435 COSTS_N_INSNS (1), /* ddiv */
442 /* Instruction costs on RIOS1 processors. */
444 struct processor_costs rios1_cost
= {
445 COSTS_N_INSNS (5), /* mulsi */
446 COSTS_N_INSNS (4), /* mulsi_const */
447 COSTS_N_INSNS (3), /* mulsi_const9 */
448 COSTS_N_INSNS (5), /* muldi */
449 COSTS_N_INSNS (19), /* divsi */
450 COSTS_N_INSNS (19), /* divdi */
451 COSTS_N_INSNS (2), /* fp */
452 COSTS_N_INSNS (2), /* dmul */
453 COSTS_N_INSNS (19), /* sdiv */
454 COSTS_N_INSNS (19), /* ddiv */
455 128, /* cache line size */
461 /* Instruction costs on RIOS2 processors. */
463 struct processor_costs rios2_cost
= {
464 COSTS_N_INSNS (2), /* mulsi */
465 COSTS_N_INSNS (2), /* mulsi_const */
466 COSTS_N_INSNS (2), /* mulsi_const9 */
467 COSTS_N_INSNS (2), /* muldi */
468 COSTS_N_INSNS (13), /* divsi */
469 COSTS_N_INSNS (13), /* divdi */
470 COSTS_N_INSNS (2), /* fp */
471 COSTS_N_INSNS (2), /* dmul */
472 COSTS_N_INSNS (17), /* sdiv */
473 COSTS_N_INSNS (17), /* ddiv */
474 256, /* cache line size */
480 /* Instruction costs on RS64A processors. */
482 struct processor_costs rs64a_cost
= {
483 COSTS_N_INSNS (20), /* mulsi */
484 COSTS_N_INSNS (12), /* mulsi_const */
485 COSTS_N_INSNS (8), /* mulsi_const9 */
486 COSTS_N_INSNS (34), /* muldi */
487 COSTS_N_INSNS (65), /* divsi */
488 COSTS_N_INSNS (67), /* divdi */
489 COSTS_N_INSNS (4), /* fp */
490 COSTS_N_INSNS (4), /* dmul */
491 COSTS_N_INSNS (31), /* sdiv */
492 COSTS_N_INSNS (31), /* ddiv */
493 128, /* cache line size */
499 /* Instruction costs on MPCCORE processors. */
501 struct processor_costs mpccore_cost
= {
502 COSTS_N_INSNS (2), /* mulsi */
503 COSTS_N_INSNS (2), /* mulsi_const */
504 COSTS_N_INSNS (2), /* mulsi_const9 */
505 COSTS_N_INSNS (2), /* muldi */
506 COSTS_N_INSNS (6), /* divsi */
507 COSTS_N_INSNS (6), /* divdi */
508 COSTS_N_INSNS (4), /* fp */
509 COSTS_N_INSNS (5), /* dmul */
510 COSTS_N_INSNS (10), /* sdiv */
511 COSTS_N_INSNS (17), /* ddiv */
512 32, /* cache line size */
518 /* Instruction costs on PPC403 processors. */
520 struct processor_costs ppc403_cost
= {
521 COSTS_N_INSNS (4), /* mulsi */
522 COSTS_N_INSNS (4), /* mulsi_const */
523 COSTS_N_INSNS (4), /* mulsi_const9 */
524 COSTS_N_INSNS (4), /* muldi */
525 COSTS_N_INSNS (33), /* divsi */
526 COSTS_N_INSNS (33), /* divdi */
527 COSTS_N_INSNS (11), /* fp */
528 COSTS_N_INSNS (11), /* dmul */
529 COSTS_N_INSNS (11), /* sdiv */
530 COSTS_N_INSNS (11), /* ddiv */
531 32, /* cache line size */
537 /* Instruction costs on PPC405 processors. */
539 struct processor_costs ppc405_cost
= {
540 COSTS_N_INSNS (5), /* mulsi */
541 COSTS_N_INSNS (4), /* mulsi_const */
542 COSTS_N_INSNS (3), /* mulsi_const9 */
543 COSTS_N_INSNS (5), /* muldi */
544 COSTS_N_INSNS (35), /* divsi */
545 COSTS_N_INSNS (35), /* divdi */
546 COSTS_N_INSNS (11), /* fp */
547 COSTS_N_INSNS (11), /* dmul */
548 COSTS_N_INSNS (11), /* sdiv */
549 COSTS_N_INSNS (11), /* ddiv */
550 32, /* cache line size */
556 /* Instruction costs on PPC440 processors. */
558 struct processor_costs ppc440_cost
= {
559 COSTS_N_INSNS (3), /* mulsi */
560 COSTS_N_INSNS (2), /* mulsi_const */
561 COSTS_N_INSNS (2), /* mulsi_const9 */
562 COSTS_N_INSNS (3), /* muldi */
563 COSTS_N_INSNS (34), /* divsi */
564 COSTS_N_INSNS (34), /* divdi */
565 COSTS_N_INSNS (5), /* fp */
566 COSTS_N_INSNS (5), /* dmul */
567 COSTS_N_INSNS (19), /* sdiv */
568 COSTS_N_INSNS (33), /* ddiv */
569 32, /* cache line size */
575 /* Instruction costs on PPC476 processors. */
577 struct processor_costs ppc476_cost
= {
578 COSTS_N_INSNS (4), /* mulsi */
579 COSTS_N_INSNS (4), /* mulsi_const */
580 COSTS_N_INSNS (4), /* mulsi_const9 */
581 COSTS_N_INSNS (4), /* muldi */
582 COSTS_N_INSNS (11), /* divsi */
583 COSTS_N_INSNS (11), /* divdi */
584 COSTS_N_INSNS (6), /* fp */
585 COSTS_N_INSNS (6), /* dmul */
586 COSTS_N_INSNS (19), /* sdiv */
587 COSTS_N_INSNS (33), /* ddiv */
588 32, /* l1 cache line size */
594 /* Instruction costs on PPC601 processors. */
596 struct processor_costs ppc601_cost
= {
597 COSTS_N_INSNS (5), /* mulsi */
598 COSTS_N_INSNS (5), /* mulsi_const */
599 COSTS_N_INSNS (5), /* mulsi_const9 */
600 COSTS_N_INSNS (5), /* muldi */
601 COSTS_N_INSNS (36), /* divsi */
602 COSTS_N_INSNS (36), /* divdi */
603 COSTS_N_INSNS (4), /* fp */
604 COSTS_N_INSNS (5), /* dmul */
605 COSTS_N_INSNS (17), /* sdiv */
606 COSTS_N_INSNS (31), /* ddiv */
607 32, /* cache line size */
613 /* Instruction costs on PPC603 processors. */
615 struct processor_costs ppc603_cost
= {
616 COSTS_N_INSNS (5), /* mulsi */
617 COSTS_N_INSNS (3), /* mulsi_const */
618 COSTS_N_INSNS (2), /* mulsi_const9 */
619 COSTS_N_INSNS (5), /* muldi */
620 COSTS_N_INSNS (37), /* divsi */
621 COSTS_N_INSNS (37), /* divdi */
622 COSTS_N_INSNS (3), /* fp */
623 COSTS_N_INSNS (4), /* dmul */
624 COSTS_N_INSNS (18), /* sdiv */
625 COSTS_N_INSNS (33), /* ddiv */
626 32, /* cache line size */
632 /* Instruction costs on PPC604 processors. */
634 struct processor_costs ppc604_cost
= {
635 COSTS_N_INSNS (4), /* mulsi */
636 COSTS_N_INSNS (4), /* mulsi_const */
637 COSTS_N_INSNS (4), /* mulsi_const9 */
638 COSTS_N_INSNS (4), /* muldi */
639 COSTS_N_INSNS (20), /* divsi */
640 COSTS_N_INSNS (20), /* divdi */
641 COSTS_N_INSNS (3), /* fp */
642 COSTS_N_INSNS (3), /* dmul */
643 COSTS_N_INSNS (18), /* sdiv */
644 COSTS_N_INSNS (32), /* ddiv */
645 32, /* cache line size */
651 /* Instruction costs on PPC604e processors. */
653 struct processor_costs ppc604e_cost
= {
654 COSTS_N_INSNS (2), /* mulsi */
655 COSTS_N_INSNS (2), /* mulsi_const */
656 COSTS_N_INSNS (2), /* mulsi_const9 */
657 COSTS_N_INSNS (2), /* muldi */
658 COSTS_N_INSNS (20), /* divsi */
659 COSTS_N_INSNS (20), /* divdi */
660 COSTS_N_INSNS (3), /* fp */
661 COSTS_N_INSNS (3), /* dmul */
662 COSTS_N_INSNS (18), /* sdiv */
663 COSTS_N_INSNS (32), /* ddiv */
664 32, /* cache line size */
670 /* Instruction costs on PPC620 processors. */
672 struct processor_costs ppc620_cost
= {
673 COSTS_N_INSNS (5), /* mulsi */
674 COSTS_N_INSNS (4), /* mulsi_const */
675 COSTS_N_INSNS (3), /* mulsi_const9 */
676 COSTS_N_INSNS (7), /* muldi */
677 COSTS_N_INSNS (21), /* divsi */
678 COSTS_N_INSNS (37), /* divdi */
679 COSTS_N_INSNS (3), /* fp */
680 COSTS_N_INSNS (3), /* dmul */
681 COSTS_N_INSNS (18), /* sdiv */
682 COSTS_N_INSNS (32), /* ddiv */
683 128, /* cache line size */
689 /* Instruction costs on PPC630 processors. */
691 struct processor_costs ppc630_cost
= {
692 COSTS_N_INSNS (5), /* mulsi */
693 COSTS_N_INSNS (4), /* mulsi_const */
694 COSTS_N_INSNS (3), /* mulsi_const9 */
695 COSTS_N_INSNS (7), /* muldi */
696 COSTS_N_INSNS (21), /* divsi */
697 COSTS_N_INSNS (37), /* divdi */
698 COSTS_N_INSNS (3), /* fp */
699 COSTS_N_INSNS (3), /* dmul */
700 COSTS_N_INSNS (17), /* sdiv */
701 COSTS_N_INSNS (21), /* ddiv */
702 128, /* cache line size */
708 /* Instruction costs on Cell processor. */
709 /* COSTS_N_INSNS (1) ~ one add. */
711 struct processor_costs ppccell_cost
= {
712 COSTS_N_INSNS (9/2)+2, /* mulsi */
713 COSTS_N_INSNS (6/2), /* mulsi_const */
714 COSTS_N_INSNS (6/2), /* mulsi_const9 */
715 COSTS_N_INSNS (15/2)+2, /* muldi */
716 COSTS_N_INSNS (38/2), /* divsi */
717 COSTS_N_INSNS (70/2), /* divdi */
718 COSTS_N_INSNS (10/2), /* fp */
719 COSTS_N_INSNS (10/2), /* dmul */
720 COSTS_N_INSNS (74/2), /* sdiv */
721 COSTS_N_INSNS (74/2), /* ddiv */
722 128, /* cache line size */
728 /* Instruction costs on PPC750 and PPC7400 processors. */
730 struct processor_costs ppc750_cost
= {
731 COSTS_N_INSNS (5), /* mulsi */
732 COSTS_N_INSNS (3), /* mulsi_const */
733 COSTS_N_INSNS (2), /* mulsi_const9 */
734 COSTS_N_INSNS (5), /* muldi */
735 COSTS_N_INSNS (17), /* divsi */
736 COSTS_N_INSNS (17), /* divdi */
737 COSTS_N_INSNS (3), /* fp */
738 COSTS_N_INSNS (3), /* dmul */
739 COSTS_N_INSNS (17), /* sdiv */
740 COSTS_N_INSNS (31), /* ddiv */
741 32, /* cache line size */
747 /* Instruction costs on PPC7450 processors. */
749 struct processor_costs ppc7450_cost
= {
750 COSTS_N_INSNS (4), /* mulsi */
751 COSTS_N_INSNS (3), /* mulsi_const */
752 COSTS_N_INSNS (3), /* mulsi_const9 */
753 COSTS_N_INSNS (4), /* muldi */
754 COSTS_N_INSNS (23), /* divsi */
755 COSTS_N_INSNS (23), /* divdi */
756 COSTS_N_INSNS (5), /* fp */
757 COSTS_N_INSNS (5), /* dmul */
758 COSTS_N_INSNS (21), /* sdiv */
759 COSTS_N_INSNS (35), /* ddiv */
760 32, /* cache line size */
766 /* Instruction costs on PPC8540 processors. */
768 struct processor_costs ppc8540_cost
= {
769 COSTS_N_INSNS (4), /* mulsi */
770 COSTS_N_INSNS (4), /* mulsi_const */
771 COSTS_N_INSNS (4), /* mulsi_const9 */
772 COSTS_N_INSNS (4), /* muldi */
773 COSTS_N_INSNS (19), /* divsi */
774 COSTS_N_INSNS (19), /* divdi */
775 COSTS_N_INSNS (4), /* fp */
776 COSTS_N_INSNS (4), /* dmul */
777 COSTS_N_INSNS (29), /* sdiv */
778 COSTS_N_INSNS (29), /* ddiv */
779 32, /* cache line size */
782 1, /* prefetch streams /*/
785 /* Instruction costs on E300C2 and E300C3 cores. */
787 struct processor_costs ppce300c2c3_cost
= {
788 COSTS_N_INSNS (4), /* mulsi */
789 COSTS_N_INSNS (4), /* mulsi_const */
790 COSTS_N_INSNS (4), /* mulsi_const9 */
791 COSTS_N_INSNS (4), /* muldi */
792 COSTS_N_INSNS (19), /* divsi */
793 COSTS_N_INSNS (19), /* divdi */
794 COSTS_N_INSNS (3), /* fp */
795 COSTS_N_INSNS (4), /* dmul */
796 COSTS_N_INSNS (18), /* sdiv */
797 COSTS_N_INSNS (33), /* ddiv */
801 1, /* prefetch streams /*/
804 /* Instruction costs on PPCE500MC processors. */
806 struct processor_costs ppce500mc_cost
= {
807 COSTS_N_INSNS (4), /* mulsi */
808 COSTS_N_INSNS (4), /* mulsi_const */
809 COSTS_N_INSNS (4), /* mulsi_const9 */
810 COSTS_N_INSNS (4), /* muldi */
811 COSTS_N_INSNS (14), /* divsi */
812 COSTS_N_INSNS (14), /* divdi */
813 COSTS_N_INSNS (8), /* fp */
814 COSTS_N_INSNS (10), /* dmul */
815 COSTS_N_INSNS (36), /* sdiv */
816 COSTS_N_INSNS (66), /* ddiv */
817 64, /* cache line size */
820 1, /* prefetch streams /*/
823 /* Instruction costs on PPCE500MC64 processors. */
825 struct processor_costs ppce500mc64_cost
= {
826 COSTS_N_INSNS (4), /* mulsi */
827 COSTS_N_INSNS (4), /* mulsi_const */
828 COSTS_N_INSNS (4), /* mulsi_const9 */
829 COSTS_N_INSNS (4), /* muldi */
830 COSTS_N_INSNS (14), /* divsi */
831 COSTS_N_INSNS (14), /* divdi */
832 COSTS_N_INSNS (4), /* fp */
833 COSTS_N_INSNS (10), /* dmul */
834 COSTS_N_INSNS (36), /* sdiv */
835 COSTS_N_INSNS (66), /* ddiv */
836 64, /* cache line size */
839 1, /* prefetch streams /*/
842 /* Instruction costs on AppliedMicro Titan processors. */
844 struct processor_costs titan_cost
= {
845 COSTS_N_INSNS (5), /* mulsi */
846 COSTS_N_INSNS (5), /* mulsi_const */
847 COSTS_N_INSNS (5), /* mulsi_const9 */
848 COSTS_N_INSNS (5), /* muldi */
849 COSTS_N_INSNS (18), /* divsi */
850 COSTS_N_INSNS (18), /* divdi */
851 COSTS_N_INSNS (10), /* fp */
852 COSTS_N_INSNS (10), /* dmul */
853 COSTS_N_INSNS (46), /* sdiv */
854 COSTS_N_INSNS (72), /* ddiv */
855 32, /* cache line size */
858 1, /* prefetch streams /*/
861 /* Instruction costs on POWER4 and POWER5 processors. */
863 struct processor_costs power4_cost
= {
864 COSTS_N_INSNS (3), /* mulsi */
865 COSTS_N_INSNS (2), /* mulsi_const */
866 COSTS_N_INSNS (2), /* mulsi_const9 */
867 COSTS_N_INSNS (4), /* muldi */
868 COSTS_N_INSNS (18), /* divsi */
869 COSTS_N_INSNS (34), /* divdi */
870 COSTS_N_INSNS (3), /* fp */
871 COSTS_N_INSNS (3), /* dmul */
872 COSTS_N_INSNS (17), /* sdiv */
873 COSTS_N_INSNS (17), /* ddiv */
874 128, /* cache line size */
877 8, /* prefetch streams /*/
880 /* Instruction costs on POWER6 processors. */
882 struct processor_costs power6_cost
= {
883 COSTS_N_INSNS (8), /* mulsi */
884 COSTS_N_INSNS (8), /* mulsi_const */
885 COSTS_N_INSNS (8), /* mulsi_const9 */
886 COSTS_N_INSNS (8), /* muldi */
887 COSTS_N_INSNS (22), /* divsi */
888 COSTS_N_INSNS (28), /* divdi */
889 COSTS_N_INSNS (3), /* fp */
890 COSTS_N_INSNS (3), /* dmul */
891 COSTS_N_INSNS (13), /* sdiv */
892 COSTS_N_INSNS (16), /* ddiv */
893 128, /* cache line size */
896 16, /* prefetch streams */
899 /* Instruction costs on POWER7 processors. */
901 struct processor_costs power7_cost
= {
902 COSTS_N_INSNS (2), /* mulsi */
903 COSTS_N_INSNS (2), /* mulsi_const */
904 COSTS_N_INSNS (2), /* mulsi_const9 */
905 COSTS_N_INSNS (2), /* muldi */
906 COSTS_N_INSNS (18), /* divsi */
907 COSTS_N_INSNS (34), /* divdi */
908 COSTS_N_INSNS (3), /* fp */
909 COSTS_N_INSNS (3), /* dmul */
910 COSTS_N_INSNS (13), /* sdiv */
911 COSTS_N_INSNS (16), /* ddiv */
912 128, /* cache line size */
915 12, /* prefetch streams */
918 /* Instruction costs on POWER A2 processors. */
920 struct processor_costs ppca2_cost
= {
921 COSTS_N_INSNS (16), /* mulsi */
922 COSTS_N_INSNS (16), /* mulsi_const */
923 COSTS_N_INSNS (16), /* mulsi_const9 */
924 COSTS_N_INSNS (16), /* muldi */
925 COSTS_N_INSNS (22), /* divsi */
926 COSTS_N_INSNS (28), /* divdi */
927 COSTS_N_INSNS (3), /* fp */
928 COSTS_N_INSNS (3), /* dmul */
929 COSTS_N_INSNS (59), /* sdiv */
930 COSTS_N_INSNS (72), /* ddiv */
934 16, /* prefetch streams */
938 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
939 #undef RS6000_BUILTIN
940 #undef RS6000_BUILTIN_EQUATE
941 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
942 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
944 static const enum rs6000_btc builtin_classify
[(int)RS6000_BUILTIN_COUNT
] =
946 #include "rs6000-builtin.def"
949 #undef RS6000_BUILTIN
950 #undef RS6000_BUILTIN_EQUATE
952 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
953 static tree (*rs6000_veclib_handler
) (tree
, tree
, tree
);
956 static bool rs6000_function_ok_for_sibcall (tree
, tree
);
957 static const char *rs6000_invalid_within_doloop (const_rtx
);
958 static bool rs6000_legitimate_address_p (enum machine_mode
, rtx
, bool);
959 static bool rs6000_debug_legitimate_address_p (enum machine_mode
, rtx
, bool);
960 static rtx
rs6000_generate_compare (rtx
, enum machine_mode
);
961 static void rs6000_emit_stack_tie (void);
962 static void rs6000_frame_related (rtx
, rtx
, HOST_WIDE_INT
, rtx
, rtx
);
963 static bool spe_func_has_64bit_regs_p (void);
964 static void emit_frame_save (rtx
, rtx
, enum machine_mode
, unsigned int,
966 static rtx
gen_frame_mem_offset (enum machine_mode
, rtx
, int);
967 static unsigned rs6000_hash_constant (rtx
);
968 static unsigned toc_hash_function (const void *);
969 static int toc_hash_eq (const void *, const void *);
970 static bool reg_offset_addressing_ok_p (enum machine_mode
);
971 static bool virtual_stack_registers_memory_p (rtx
);
972 static bool constant_pool_expr_p (rtx
);
973 static bool legitimate_small_data_p (enum machine_mode
, rtx
);
974 static bool legitimate_lo_sum_address_p (enum machine_mode
, rtx
, int);
975 static struct machine_function
* rs6000_init_machine_status (void);
976 static bool rs6000_assemble_integer (rtx
, unsigned int, int);
977 static bool no_global_regs_above (int, bool);
978 #ifdef HAVE_GAS_HIDDEN
979 static void rs6000_assemble_visibility (tree
, int);
981 static int rs6000_ra_ever_killed (void);
982 static bool rs6000_attribute_takes_identifier_p (const_tree
);
983 static tree
rs6000_handle_longcall_attribute (tree
*, tree
, tree
, int, bool *);
984 static tree
rs6000_handle_altivec_attribute (tree
*, tree
, tree
, int, bool *);
985 static bool rs6000_ms_bitfield_layout_p (const_tree
);
986 static tree
rs6000_handle_struct_attribute (tree
*, tree
, tree
, int, bool *);
987 static void rs6000_eliminate_indexed_memrefs (rtx operands
[2]);
988 static const char *rs6000_mangle_type (const_tree
);
989 static void rs6000_set_default_type_attributes (tree
);
990 static rtx
rs6000_savres_routine_sym (rs6000_stack_t
*, bool, bool, bool);
991 static rtx
rs6000_emit_stack_reset (rs6000_stack_t
*, rtx
, rtx
, int, bool);
992 static rtx
rs6000_make_savres_rtx (rs6000_stack_t
*, rtx
, int,
993 enum machine_mode
, bool, bool, bool);
994 static bool rs6000_reg_live_or_pic_offset_p (int);
995 static tree
rs6000_builtin_vectorized_libmass (tree
, tree
, tree
);
996 static tree
rs6000_builtin_vectorized_function (tree
, tree
, tree
);
997 static int rs6000_savres_strategy (rs6000_stack_t
*, bool, int, int);
998 static void rs6000_restore_saved_cr (rtx
, int);
999 static bool rs6000_output_addr_const_extra (FILE *, rtx
);
1000 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT
);
1001 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT
);
1002 static void rs6000_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
1004 static rtx
rs6000_emit_set_long_const (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
1005 static bool rs6000_return_in_memory (const_tree
, const_tree
);
1006 static rtx
rs6000_function_value (const_tree
, const_tree
, bool);
1007 static void rs6000_file_start (void);
1009 static int rs6000_elf_reloc_rw_mask (void);
1010 static void rs6000_elf_asm_out_constructor (rtx
, int);
1011 static void rs6000_elf_asm_out_destructor (rtx
, int);
1012 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED
;
1013 static void rs6000_elf_asm_init_sections (void);
1014 static section
*rs6000_elf_select_rtx_section (enum machine_mode
, rtx
,
1015 unsigned HOST_WIDE_INT
);
1016 static void rs6000_elf_encode_section_info (tree
, rtx
, int)
1019 static bool rs6000_use_blocks_for_constant_p (enum machine_mode
, const_rtx
);
1020 static void rs6000_alloc_sdmode_stack_slot (void);
1021 static void rs6000_instantiate_decls (void);
1023 static void rs6000_xcoff_asm_output_anchor (rtx
);
1024 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
1025 static void rs6000_xcoff_asm_init_sections (void);
1026 static int rs6000_xcoff_reloc_rw_mask (void);
1027 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree
);
1028 static section
*rs6000_xcoff_select_section (tree
, int,
1029 unsigned HOST_WIDE_INT
);
1030 static void rs6000_xcoff_unique_section (tree
, int);
1031 static section
*rs6000_xcoff_select_rtx_section
1032 (enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
);
1033 static const char * rs6000_xcoff_strip_name_encoding (const char *);
1034 static unsigned int rs6000_xcoff_section_type_flags (tree
, const char *, int);
1035 static void rs6000_xcoff_file_start (void);
1036 static void rs6000_xcoff_file_end (void);
1038 static int rs6000_variable_issue (FILE *, int, rtx
, int);
1039 static int rs6000_register_move_cost (enum machine_mode
,
1040 reg_class_t
, reg_class_t
);
1041 static int rs6000_memory_move_cost (enum machine_mode
, reg_class_t
, bool);
1042 static bool rs6000_rtx_costs (rtx
, int, int, int *, bool);
1043 static bool rs6000_debug_rtx_costs (rtx
, int, int, int *, bool);
1044 static int rs6000_debug_address_cost (rtx
, bool);
1045 static int rs6000_adjust_cost (rtx
, rtx
, rtx
, int);
1046 static int rs6000_debug_adjust_cost (rtx
, rtx
, rtx
, int);
1047 static void rs6000_sched_init (FILE *, int, int);
1048 static bool is_microcoded_insn (rtx
);
1049 static bool is_nonpipeline_insn (rtx
);
1050 static bool is_cracked_insn (rtx
);
1051 static bool is_branch_slot_insn (rtx
);
1052 static bool is_load_insn (rtx
);
1053 static rtx
get_store_dest (rtx pat
);
1054 static bool is_store_insn (rtx
);
1055 static bool set_to_load_agen (rtx
,rtx
);
1056 static bool adjacent_mem_locations (rtx
,rtx
);
1057 static int rs6000_adjust_priority (rtx
, int);
1058 static int rs6000_issue_rate (void);
1059 static bool rs6000_is_costly_dependence (dep_t
, int, int);
1060 static rtx
get_next_active_insn (rtx
, rtx
);
1061 static bool insn_terminates_group_p (rtx
, enum group_termination
);
1062 static bool insn_must_be_first_in_group (rtx
);
1063 static bool insn_must_be_last_in_group (rtx
);
1064 static bool is_costly_group (rtx
*, rtx
);
1065 static int force_new_group (int, FILE *, rtx
*, rtx
, bool *, int, int *);
1066 static int redefine_groups (FILE *, int, rtx
, rtx
);
1067 static int pad_groups (FILE *, int, rtx
, rtx
);
1068 static void rs6000_sched_finish (FILE *, int);
1069 static int rs6000_sched_reorder (FILE *, int, rtx
*, int *, int);
1070 static int rs6000_sched_reorder2 (FILE *, int, rtx
*, int *, int);
1071 static int rs6000_use_sched_lookahead (void);
1072 static int rs6000_use_sched_lookahead_guard (rtx
);
1073 static void * rs6000_alloc_sched_context (void);
1074 static void rs6000_init_sched_context (void *, bool);
1075 static void rs6000_set_sched_context (void *);
1076 static void rs6000_free_sched_context (void *);
1077 static tree
rs6000_builtin_reciprocal (unsigned int, bool, bool);
1078 static tree
rs6000_builtin_mask_for_load (void);
1079 static tree
rs6000_builtin_mul_widen_even (tree
);
1080 static tree
rs6000_builtin_mul_widen_odd (tree
);
1081 static tree
rs6000_builtin_conversion (unsigned int, tree
, tree
);
1082 static tree
rs6000_builtin_vec_perm (tree
, tree
*);
1083 static bool rs6000_builtin_support_vector_misalignment (enum
1087 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt
,
1089 static enum machine_mode
rs6000_preferred_simd_mode (enum machine_mode
);
1091 static void def_builtin (int, const char *, tree
, int);
1092 static bool rs6000_vector_alignment_reachable (const_tree
, bool);
1093 static void rs6000_init_builtins (void);
1094 static tree
rs6000_builtin_decl (unsigned, bool);
1096 static rtx
rs6000_expand_unop_builtin (enum insn_code
, tree
, rtx
);
1097 static rtx
rs6000_expand_binop_builtin (enum insn_code
, tree
, rtx
);
1098 static rtx
rs6000_expand_ternop_builtin (enum insn_code
, tree
, rtx
);
1099 static rtx
rs6000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
1100 static void altivec_init_builtins (void);
1101 static unsigned builtin_hash_function (const void *);
1102 static int builtin_hash_eq (const void *, const void *);
1103 static tree
builtin_function_type (enum machine_mode
, enum machine_mode
,
1104 enum machine_mode
, enum machine_mode
,
1105 enum rs6000_builtins
, const char *name
);
1106 static void rs6000_common_init_builtins (void);
1107 static void rs6000_init_libfuncs (void);
1109 static void paired_init_builtins (void);
1110 static rtx
paired_expand_builtin (tree
, rtx
, bool *);
1111 static rtx
paired_expand_lv_builtin (enum insn_code
, tree
, rtx
);
1112 static rtx
paired_expand_stv_builtin (enum insn_code
, tree
);
1113 static rtx
paired_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
1115 static void enable_mask_for_builtins (struct builtin_description
*, int,
1116 enum rs6000_builtins
,
1117 enum rs6000_builtins
);
1118 static void spe_init_builtins (void);
1119 static rtx
spe_expand_builtin (tree
, rtx
, bool *);
1120 static rtx
spe_expand_stv_builtin (enum insn_code
, tree
);
1121 static rtx
spe_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
1122 static rtx
spe_expand_evsel_builtin (enum insn_code
, tree
, rtx
);
1123 static int rs6000_emit_int_cmove (rtx
, rtx
, rtx
, rtx
);
1124 static rs6000_stack_t
*rs6000_stack_info (void);
1125 static void debug_stack_info (rs6000_stack_t
*);
1127 static rtx
altivec_expand_builtin (tree
, rtx
, bool *);
1128 static rtx
altivec_expand_ld_builtin (tree
, rtx
, bool *);
1129 static rtx
altivec_expand_st_builtin (tree
, rtx
, bool *);
1130 static rtx
altivec_expand_dst_builtin (tree
, rtx
, bool *);
1131 static rtx
altivec_expand_abs_builtin (enum insn_code
, tree
, rtx
);
1132 static rtx
altivec_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
1133 static rtx
altivec_expand_stv_builtin (enum insn_code
, tree
);
1134 static rtx
altivec_expand_vec_init_builtin (tree
, tree
, rtx
);
1135 static rtx
altivec_expand_vec_set_builtin (tree
);
1136 static rtx
altivec_expand_vec_ext_builtin (tree
, rtx
);
1137 static int get_element_number (tree
, tree
);
1138 static void rs6000_option_override (void);
1139 static void rs6000_option_optimization (int, int);
1140 static void rs6000_option_default_params (void);
1141 static bool rs6000_handle_option (size_t, const char *, int);
1142 static void rs6000_parse_tls_size_option (void);
1143 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1144 static int first_altivec_reg_to_save (void);
1145 static unsigned int compute_vrsave_mask (void);
1146 static void compute_save_world_info (rs6000_stack_t
*info_ptr
);
1147 static void is_altivec_return_reg (rtx
, void *);
1148 static rtx
generate_set_vrsave (rtx
, rs6000_stack_t
*, int);
1149 int easy_vector_constant (rtx
, enum machine_mode
);
1150 static rtx
rs6000_dwarf_register_span (rtx
);
1151 static void rs6000_init_dwarf_reg_sizes_extra (tree
);
1152 static rtx
rs6000_legitimize_address (rtx
, rtx
, enum machine_mode
);
1153 static rtx
rs6000_debug_legitimize_address (rtx
, rtx
, enum machine_mode
);
1154 static rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
1155 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
1156 static rtx
rs6000_delegitimize_address (rtx
);
1157 static rtx
rs6000_tls_get_addr (void);
1158 static rtx
rs6000_got_sym (void);
1159 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
1160 static const char *rs6000_get_some_local_dynamic_name (void);
1161 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
1162 static rtx
rs6000_complex_function_value (enum machine_mode
);
1163 static rtx
rs6000_spe_function_arg (const CUMULATIVE_ARGS
*,
1164 enum machine_mode
, const_tree
);
1165 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
1166 HOST_WIDE_INT
, int);
1167 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
1170 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
1173 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
1174 const_tree
, HOST_WIDE_INT
,
1176 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, const_tree
, bool, bool);
1177 static rtx
rs6000_mixed_function_arg (enum machine_mode
, const_tree
, int);
1178 static void rs6000_function_arg_advance (CUMULATIVE_ARGS
*, enum machine_mode
,
1180 static rtx
rs6000_function_arg (CUMULATIVE_ARGS
*, enum machine_mode
,
1182 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
1183 static void setup_incoming_varargs (CUMULATIVE_ARGS
*,
1184 enum machine_mode
, tree
,
1186 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
1188 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
1190 static const char *invalid_arg_for_unprototyped_fn (const_tree
, const_tree
, const_tree
);
1192 static void macho_branch_islands (void);
1193 static int no_previous_def (tree function_name
);
1194 static tree
get_prev_label (tree function_name
);
1195 static void rs6000_darwin_file_start (void);
1198 static tree
rs6000_build_builtin_va_list (void);
1199 static void rs6000_va_start (tree
, rtx
);
1200 static tree
rs6000_gimplify_va_arg (tree
, tree
, gimple_seq
*, gimple_seq
*);
1201 static bool rs6000_must_pass_in_stack (enum machine_mode
, const_tree
);
1202 static bool rs6000_scalar_mode_supported_p (enum machine_mode
);
1203 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
1204 static rtx
rs6000_emit_vector_compare_inner (enum rtx_code
, rtx
, rtx
);
1205 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
1207 static tree
rs6000_stack_protect_fail (void);
1209 static rtx
rs6000_legitimize_reload_address (rtx
, enum machine_mode
, int, int,
1212 static rtx
rs6000_debug_legitimize_reload_address (rtx
, enum machine_mode
, int,
1215 rtx (*rs6000_legitimize_reload_address_ptr
) (rtx
, enum machine_mode
, int, int,
1217 = rs6000_legitimize_reload_address
;
1219 static bool rs6000_mode_dependent_address_p (const_rtx
);
1220 static bool rs6000_mode_dependent_address (const_rtx
);
1221 static bool rs6000_debug_mode_dependent_address (const_rtx
);
1222 static bool (*rs6000_mode_dependent_address_ptr
) (const_rtx
)
1223 = rs6000_mode_dependent_address
;
1225 static enum reg_class
rs6000_secondary_reload_class (enum reg_class
,
1226 enum machine_mode
, rtx
);
1227 static enum reg_class
rs6000_debug_secondary_reload_class (enum reg_class
,
1230 enum reg_class (*rs6000_secondary_reload_class_ptr
) (enum reg_class
,
1231 enum machine_mode
, rtx
)
1232 = rs6000_secondary_reload_class
;
1234 static enum reg_class
rs6000_preferred_reload_class (rtx
, enum reg_class
);
1235 static enum reg_class
rs6000_debug_preferred_reload_class (rtx
,
1237 enum reg_class (*rs6000_preferred_reload_class_ptr
) (rtx
, enum reg_class
)
1238 = rs6000_preferred_reload_class
;
1240 static bool rs6000_secondary_memory_needed (enum reg_class
, enum reg_class
,
1243 static bool rs6000_debug_secondary_memory_needed (enum reg_class
,
1247 bool (*rs6000_secondary_memory_needed_ptr
) (enum reg_class
, enum reg_class
,
1249 = rs6000_secondary_memory_needed
;
1251 static bool rs6000_cannot_change_mode_class (enum machine_mode
,
1254 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode
,
1258 bool (*rs6000_cannot_change_mode_class_ptr
) (enum machine_mode
,
1261 = rs6000_cannot_change_mode_class
;
1263 static reg_class_t
rs6000_secondary_reload (bool, rtx
, reg_class_t
,
1265 struct secondary_reload_info
*);
1267 static const reg_class_t
*rs6000_ira_cover_classes (void);
1269 const int INSN_NOT_AVAILABLE
= -1;
1270 static enum machine_mode
rs6000_eh_return_filter_mode (void);
1271 static bool rs6000_can_eliminate (const int, const int);
1272 static void rs6000_trampoline_init (rtx
, tree
, rtx
);
1274 /* Hash table stuff for keeping track of TOC entries. */
1276 struct GTY(()) toc_hash_struct
1278 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1279 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1281 enum machine_mode key_mode
;
1285 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
1287 /* Hash table to keep track of the argument types for builtin functions. */
1289 struct GTY(()) builtin_hash_struct
1292 enum machine_mode mode
[4]; /* return value + 3 arguments. */
1293 unsigned char uns_p
[4]; /* and whether the types are unsigned. */
1296 static GTY ((param_is (struct builtin_hash_struct
))) htab_t builtin_hash_table
;
1298 /* Default register names. */
1299 char rs6000_reg_names
[][8] =
1301 "0", "1", "2", "3", "4", "5", "6", "7",
1302 "8", "9", "10", "11", "12", "13", "14", "15",
1303 "16", "17", "18", "19", "20", "21", "22", "23",
1304 "24", "25", "26", "27", "28", "29", "30", "31",
1305 "0", "1", "2", "3", "4", "5", "6", "7",
1306 "8", "9", "10", "11", "12", "13", "14", "15",
1307 "16", "17", "18", "19", "20", "21", "22", "23",
1308 "24", "25", "26", "27", "28", "29", "30", "31",
1309 "mq", "lr", "ctr","ap",
1310 "0", "1", "2", "3", "4", "5", "6", "7",
1312 /* AltiVec registers. */
1313 "0", "1", "2", "3", "4", "5", "6", "7",
1314 "8", "9", "10", "11", "12", "13", "14", "15",
1315 "16", "17", "18", "19", "20", "21", "22", "23",
1316 "24", "25", "26", "27", "28", "29", "30", "31",
1318 /* SPE registers. */
1319 "spe_acc", "spefscr",
1320 /* Soft frame pointer. */
1324 #ifdef TARGET_REGNAMES
1325 static const char alt_reg_names
[][8] =
1327 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1328 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1329 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1330 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1331 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1332 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1333 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1334 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1335 "mq", "lr", "ctr", "ap",
1336 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1338 /* AltiVec registers. */
1339 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1340 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1341 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1342 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1344 /* SPE registers. */
1345 "spe_acc", "spefscr",
1346 /* Soft frame pointer. */
1351 /* Table of valid machine attributes. */
1353 static const struct attribute_spec rs6000_attribute_table
[] =
1355 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1356 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
},
1357 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
1358 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
1359 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
1360 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
1361 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1362 SUBTARGET_ATTRIBUTE_TABLE
,
1364 { NULL
, 0, 0, false, false, false, NULL
}
1367 #ifndef MASK_STRICT_ALIGN
1368 #define MASK_STRICT_ALIGN 0
1370 #ifndef TARGET_PROFILE_KERNEL
1371 #define TARGET_PROFILE_KERNEL 0
1374 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1375 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1377 /* Initialize the GCC target structure. */
1378 #undef TARGET_ATTRIBUTE_TABLE
1379 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1380 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1381 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1382 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1383 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1385 #undef TARGET_ASM_ALIGNED_DI_OP
1386 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1388 /* Default unaligned ops are only provided for ELF. Find the ops needed
1389 for non-ELF systems. */
1390 #ifndef OBJECT_FORMAT_ELF
1392 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1394 #undef TARGET_ASM_UNALIGNED_HI_OP
1395 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1396 #undef TARGET_ASM_UNALIGNED_SI_OP
1397 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1398 #undef TARGET_ASM_UNALIGNED_DI_OP
1399 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1402 #undef TARGET_ASM_UNALIGNED_HI_OP
1403 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1404 #undef TARGET_ASM_UNALIGNED_SI_OP
1405 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1406 #undef TARGET_ASM_UNALIGNED_DI_OP
1407 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1408 #undef TARGET_ASM_ALIGNED_DI_OP
1409 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1413 /* This hook deals with fixups for relocatable code and DI-mode objects
1415 #undef TARGET_ASM_INTEGER
1416 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1418 #ifdef HAVE_GAS_HIDDEN
1419 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1420 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1423 #undef TARGET_HAVE_TLS
1424 #define TARGET_HAVE_TLS HAVE_AS_TLS
1426 #undef TARGET_CANNOT_FORCE_CONST_MEM
1427 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1429 #undef TARGET_DELEGITIMIZE_ADDRESS
1430 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1432 #undef TARGET_ASM_FUNCTION_PROLOGUE
1433 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1434 #undef TARGET_ASM_FUNCTION_EPILOGUE
1435 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1437 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1438 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1440 #undef TARGET_LEGITIMIZE_ADDRESS
1441 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1443 #undef TARGET_SCHED_VARIABLE_ISSUE
1444 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1446 #undef TARGET_SCHED_ISSUE_RATE
1447 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1448 #undef TARGET_SCHED_ADJUST_COST
1449 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1450 #undef TARGET_SCHED_ADJUST_PRIORITY
1451 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1452 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1453 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1454 #undef TARGET_SCHED_INIT
1455 #define TARGET_SCHED_INIT rs6000_sched_init
1456 #undef TARGET_SCHED_FINISH
1457 #define TARGET_SCHED_FINISH rs6000_sched_finish
1458 #undef TARGET_SCHED_REORDER
1459 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1460 #undef TARGET_SCHED_REORDER2
1461 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1463 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1464 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1466 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1467 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1469 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1470 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1471 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1472 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1473 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1474 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1475 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1476 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1478 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1479 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1480 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1481 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1482 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1483 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1484 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1485 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1486 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1487 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1488 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1489 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1490 rs6000_builtin_support_vector_misalignment
1491 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1492 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1493 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1494 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1495 rs6000_builtin_vectorization_cost
1496 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1497 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1498 rs6000_preferred_simd_mode
1500 #undef TARGET_INIT_BUILTINS
1501 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1502 #undef TARGET_BUILTIN_DECL
1503 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1505 #undef TARGET_EXPAND_BUILTIN
1506 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1508 #undef TARGET_MANGLE_TYPE
1509 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1511 #undef TARGET_INIT_LIBFUNCS
1512 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1515 #undef TARGET_BINDS_LOCAL_P
1516 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1519 #undef TARGET_MS_BITFIELD_LAYOUT_P
1520 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1522 #undef TARGET_ASM_OUTPUT_MI_THUNK
1523 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1525 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1526 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1528 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1529 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1531 #undef TARGET_INVALID_WITHIN_DOLOOP
1532 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1534 #undef TARGET_REGISTER_MOVE_COST
1535 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1536 #undef TARGET_MEMORY_MOVE_COST
1537 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1538 #undef TARGET_RTX_COSTS
1539 #define TARGET_RTX_COSTS rs6000_rtx_costs
1540 #undef TARGET_ADDRESS_COST
1541 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1543 #undef TARGET_DWARF_REGISTER_SPAN
1544 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1546 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1547 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1549 /* On rs6000, function arguments are promoted, as are function return
1551 #undef TARGET_PROMOTE_FUNCTION_MODE
1552 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1554 #undef TARGET_RETURN_IN_MEMORY
1555 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1557 #undef TARGET_SETUP_INCOMING_VARARGS
1558 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1560 /* Always strict argument naming on rs6000. */
1561 #undef TARGET_STRICT_ARGUMENT_NAMING
1562 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1563 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1564 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1565 #undef TARGET_SPLIT_COMPLEX_ARG
1566 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1567 #undef TARGET_MUST_PASS_IN_STACK
1568 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1569 #undef TARGET_PASS_BY_REFERENCE
1570 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1571 #undef TARGET_ARG_PARTIAL_BYTES
1572 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1573 #undef TARGET_FUNCTION_ARG_ADVANCE
1574 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1575 #undef TARGET_FUNCTION_ARG
1576 #define TARGET_FUNCTION_ARG rs6000_function_arg
1578 #undef TARGET_BUILD_BUILTIN_VA_LIST
1579 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1581 #undef TARGET_EXPAND_BUILTIN_VA_START
1582 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1584 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1585 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1587 #undef TARGET_EH_RETURN_FILTER_MODE
1588 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1590 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1591 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1593 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1594 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1596 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1597 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1599 #undef TARGET_HANDLE_OPTION
1600 #define TARGET_HANDLE_OPTION rs6000_handle_option
1602 #undef TARGET_OPTION_OVERRIDE
1603 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1605 #undef TARGET_OPTION_OPTIMIZATION
1606 #define TARGET_OPTION_OPTIMIZATION rs6000_option_optimization
1608 #undef TARGET_OPTION_DEFAULT_PARAMS
1609 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1611 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1612 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1613 rs6000_builtin_vectorized_function
1615 #undef TARGET_DEFAULT_TARGET_FLAGS
1616 #define TARGET_DEFAULT_TARGET_FLAGS \
1619 #undef TARGET_STACK_PROTECT_FAIL
1620 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1622 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1623 The PowerPC architecture requires only weak consistency among
1624 processors--that is, memory accesses between processors need not be
1625 sequentially consistent and memory accesses among processors can occur
1626 in any order. The ability to order memory accesses weakly provides
1627 opportunities for more efficient use of the system bus. Unless a
1628 dependency exists, the 604e allows read operations to precede store
1630 #undef TARGET_RELAXED_ORDERING
1631 #define TARGET_RELAXED_ORDERING true
1634 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1635 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1638 /* Use a 32-bit anchor range. This leads to sequences like:
1640 addis tmp,anchor,high
1643 where tmp itself acts as an anchor, and can be shared between
1644 accesses to the same 64k page. */
1645 #undef TARGET_MIN_ANCHOR_OFFSET
1646 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1647 #undef TARGET_MAX_ANCHOR_OFFSET
1648 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1649 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1650 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1652 #undef TARGET_BUILTIN_RECIPROCAL
1653 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1655 #undef TARGET_EXPAND_TO_RTL_HOOK
1656 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1658 #undef TARGET_INSTANTIATE_DECLS
1659 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1661 #undef TARGET_SECONDARY_RELOAD
1662 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1664 #undef TARGET_IRA_COVER_CLASSES
1665 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1667 #undef TARGET_LEGITIMATE_ADDRESS_P
1668 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1670 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1671 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1673 #undef TARGET_CAN_ELIMINATE
1674 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1676 #undef TARGET_TRAMPOLINE_INIT
1677 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1679 #undef TARGET_FUNCTION_VALUE
1680 #define TARGET_FUNCTION_VALUE rs6000_function_value
1682 struct gcc_target targetm
= TARGET_INITIALIZER
;
1684 /* Return number of consecutive hard regs needed starting at reg REGNO
1685 to hold something of mode MODE.
1686 This is ordinarily the length in words of a value of mode MODE
1687 but can be less for certain modes in special long registers.
1689 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1690 scalar instructions. The upper 32 bits are only available to the
1693 POWER and PowerPC GPRs hold 32 bits worth;
1694 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1697 rs6000_hard_regno_nregs_internal (int regno
, enum machine_mode mode
)
1699 unsigned HOST_WIDE_INT reg_size
;
1701 if (FP_REGNO_P (regno
))
1702 reg_size
= (VECTOR_MEM_VSX_P (mode
)
1703 ? UNITS_PER_VSX_WORD
1704 : UNITS_PER_FP_WORD
);
1706 else if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1707 reg_size
= UNITS_PER_SPE_WORD
;
1709 else if (ALTIVEC_REGNO_P (regno
))
1710 reg_size
= UNITS_PER_ALTIVEC_WORD
;
1712 /* The value returned for SCmode in the E500 double case is 2 for
1713 ABI compatibility; storing an SCmode value in a single register
1714 would require function_arg and rs6000_spe_function_arg to handle
1715 SCmode so as to pass the value correctly in a pair of
1717 else if (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
) && mode
!= SCmode
1718 && !DECIMAL_FLOAT_MODE_P (mode
))
1719 reg_size
= UNITS_PER_FP_WORD
;
1722 reg_size
= UNITS_PER_WORD
;
1724 return (GET_MODE_SIZE (mode
) + reg_size
- 1) / reg_size
;
1727 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1730 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
1732 int last_regno
= regno
+ rs6000_hard_regno_nregs
[mode
][regno
] - 1;
1734 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1735 implementations. Don't allow an item to be split between a FP register
1736 and an Altivec register. */
1737 if (VECTOR_MEM_VSX_P (mode
))
1739 if (FP_REGNO_P (regno
))
1740 return FP_REGNO_P (last_regno
);
1742 if (ALTIVEC_REGNO_P (regno
))
1743 return ALTIVEC_REGNO_P (last_regno
);
1746 /* The GPRs can hold any mode, but values bigger than one register
1747 cannot go past R31. */
1748 if (INT_REGNO_P (regno
))
1749 return INT_REGNO_P (last_regno
);
1751 /* The float registers (except for VSX vector modes) can only hold floating
1752 modes and DImode. This excludes the 32-bit decimal float mode for
1754 if (FP_REGNO_P (regno
))
1756 if (SCALAR_FLOAT_MODE_P (mode
)
1757 && (mode
!= TDmode
|| (regno
% 2) == 0)
1758 && FP_REGNO_P (last_regno
))
1761 if (GET_MODE_CLASS (mode
) == MODE_INT
1762 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
)
1765 if (PAIRED_SIMD_REGNO_P (regno
) && TARGET_PAIRED_FLOAT
1766 && PAIRED_VECTOR_MODE (mode
))
1772 /* The CR register can only hold CC modes. */
1773 if (CR_REGNO_P (regno
))
1774 return GET_MODE_CLASS (mode
) == MODE_CC
;
1776 if (CA_REGNO_P (regno
))
1777 return mode
== BImode
;
1779 /* AltiVec only in AldyVec registers. */
1780 if (ALTIVEC_REGNO_P (regno
))
1781 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
);
1783 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1784 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1787 /* We cannot put TImode anywhere except general register and it must be able
1788 to fit within the register set. In the future, allow TImode in the
1789 Altivec or VSX registers. */
1791 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1794 /* Print interesting facts about registers. */
1796 rs6000_debug_reg_print (int first_regno
, int last_regno
, const char *reg_name
)
1800 for (r
= first_regno
; r
<= last_regno
; ++r
)
1802 const char *comma
= "";
1805 if (first_regno
== last_regno
)
1806 fprintf (stderr
, "%s:\t", reg_name
);
1808 fprintf (stderr
, "%s%d:\t", reg_name
, r
- first_regno
);
1811 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1812 if (rs6000_hard_regno_mode_ok_p
[m
][r
] && rs6000_hard_regno_nregs
[m
][r
])
1816 fprintf (stderr
, ",\n\t");
1821 if (rs6000_hard_regno_nregs
[m
][r
] > 1)
1822 len
+= fprintf (stderr
, "%s%s/%d", comma
, GET_MODE_NAME (m
),
1823 rs6000_hard_regno_nregs
[m
][r
]);
1825 len
+= fprintf (stderr
, "%s%s", comma
, GET_MODE_NAME (m
));
1830 if (call_used_regs
[r
])
1834 fprintf (stderr
, ",\n\t");
1839 len
+= fprintf (stderr
, "%s%s", comma
, "call-used");
1847 fprintf (stderr
, ",\n\t");
1852 len
+= fprintf (stderr
, "%s%s", comma
, "fixed");
1858 fprintf (stderr
, ",\n\t");
1862 fprintf (stderr
, "%sregno = %d\n", comma
, r
);
1866 /* Print various interesting information with -mdebug=reg. */
1868 rs6000_debug_reg_global (void)
1870 const char *nl
= (const char *)0;
1872 char costly_num
[20];
1874 const char *costly_str
;
1875 const char *nop_str
;
1877 /* Map enum rs6000_vector to string. */
1878 static const char *rs6000_debug_vector_unit
[] = {
1887 fprintf (stderr
, "Register information: (last virtual reg = %d)\n",
1888 LAST_VIRTUAL_REGISTER
);
1889 rs6000_debug_reg_print (0, 31, "gr");
1890 rs6000_debug_reg_print (32, 63, "fp");
1891 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO
,
1894 rs6000_debug_reg_print (LR_REGNO
, LR_REGNO
, "lr");
1895 rs6000_debug_reg_print (CTR_REGNO
, CTR_REGNO
, "ctr");
1896 rs6000_debug_reg_print (CR0_REGNO
, CR7_REGNO
, "cr");
1897 rs6000_debug_reg_print (MQ_REGNO
, MQ_REGNO
, "mq");
1898 rs6000_debug_reg_print (CA_REGNO
, CA_REGNO
, "ca");
1899 rs6000_debug_reg_print (VRSAVE_REGNO
, VRSAVE_REGNO
, "vrsave");
1900 rs6000_debug_reg_print (VSCR_REGNO
, VSCR_REGNO
, "vscr");
1901 rs6000_debug_reg_print (SPE_ACC_REGNO
, SPE_ACC_REGNO
, "spe_a");
1902 rs6000_debug_reg_print (SPEFSCR_REGNO
, SPEFSCR_REGNO
, "spe_f");
1906 "d reg_class = %s\n"
1907 "f reg_class = %s\n"
1908 "v reg_class = %s\n"
1909 "wa reg_class = %s\n"
1910 "wd reg_class = %s\n"
1911 "wf reg_class = %s\n"
1912 "ws reg_class = %s\n\n",
1913 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_d
]],
1914 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_f
]],
1915 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_v
]],
1916 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wa
]],
1917 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wd
]],
1918 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wf
]],
1919 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_ws
]]);
1921 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1922 if (rs6000_vector_unit
[m
] || rs6000_vector_mem
[m
])
1925 fprintf (stderr
, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1927 rs6000_debug_vector_unit
[ rs6000_vector_unit
[m
] ],
1928 rs6000_debug_vector_unit
[ rs6000_vector_mem
[m
] ]);
1934 if (rs6000_recip_control
)
1936 fprintf (stderr
, "\nReciprocal mask = 0x%x\n", rs6000_recip_control
);
1938 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1939 if (rs6000_recip_bits
[m
])
1942 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1944 (RS6000_RECIP_AUTO_RE_P (m
)
1946 : (RS6000_RECIP_HAVE_RE_P (m
) ? "have" : "none")),
1947 (RS6000_RECIP_AUTO_RSQRTE_P (m
)
1949 : (RS6000_RECIP_HAVE_RSQRTE_P (m
) ? "have" : "none")));
1952 fputs ("\n", stderr
);
1955 switch (rs6000_sched_costly_dep
)
1957 case max_dep_latency
:
1958 costly_str
= "max_dep_latency";
1962 costly_str
= "no_dep_costly";
1965 case all_deps_costly
:
1966 costly_str
= "all_deps_costly";
1969 case true_store_to_load_dep_costly
:
1970 costly_str
= "true_store_to_load_dep_costly";
1973 case store_to_load_dep_costly
:
1974 costly_str
= "store_to_load_dep_costly";
1978 costly_str
= costly_num
;
1979 sprintf (costly_num
, "%d", (int)rs6000_sched_costly_dep
);
1983 switch (rs6000_sched_insert_nops
)
1985 case sched_finish_regroup_exact
:
1986 nop_str
= "sched_finish_regroup_exact";
1989 case sched_finish_pad_groups
:
1990 nop_str
= "sched_finish_pad_groups";
1993 case sched_finish_none
:
1994 nop_str
= "sched_finish_none";
1999 sprintf (nop_num
, "%d", (int)rs6000_sched_insert_nops
);
2004 "always_hint = %s\n"
2005 "align_branch_targets = %s\n"
2006 "sched_restricted_insns_priority = %d\n"
2007 "sched_costly_dep = %s\n"
2008 "sched_insert_nops = %s\n\n",
2009 rs6000_always_hint
? "true" : "false",
2010 rs6000_align_branch_targets
? "true" : "false",
2011 (int)rs6000_sched_restricted_insns_priority
,
2012 costly_str
, nop_str
);
2015 /* Initialize the various global tables that are based on register size. */
2017 rs6000_init_hard_regno_mode_ok (void)
2023 /* Precalculate REGNO_REG_CLASS. */
2024 rs6000_regno_regclass
[0] = GENERAL_REGS
;
2025 for (r
= 1; r
< 32; ++r
)
2026 rs6000_regno_regclass
[r
] = BASE_REGS
;
2028 for (r
= 32; r
< 64; ++r
)
2029 rs6000_regno_regclass
[r
] = FLOAT_REGS
;
2031 for (r
= 64; r
< FIRST_PSEUDO_REGISTER
; ++r
)
2032 rs6000_regno_regclass
[r
] = NO_REGS
;
2034 for (r
= FIRST_ALTIVEC_REGNO
; r
<= LAST_ALTIVEC_REGNO
; ++r
)
2035 rs6000_regno_regclass
[r
] = ALTIVEC_REGS
;
2037 rs6000_regno_regclass
[CR0_REGNO
] = CR0_REGS
;
2038 for (r
= CR1_REGNO
; r
<= CR7_REGNO
; ++r
)
2039 rs6000_regno_regclass
[r
] = CR_REGS
;
2041 rs6000_regno_regclass
[MQ_REGNO
] = MQ_REGS
;
2042 rs6000_regno_regclass
[LR_REGNO
] = LINK_REGS
;
2043 rs6000_regno_regclass
[CTR_REGNO
] = CTR_REGS
;
2044 rs6000_regno_regclass
[CA_REGNO
] = CA_REGS
;
2045 rs6000_regno_regclass
[VRSAVE_REGNO
] = VRSAVE_REGS
;
2046 rs6000_regno_regclass
[VSCR_REGNO
] = VRSAVE_REGS
;
2047 rs6000_regno_regclass
[SPE_ACC_REGNO
] = SPE_ACC_REGS
;
2048 rs6000_regno_regclass
[SPEFSCR_REGNO
] = SPEFSCR_REGS
;
2049 rs6000_regno_regclass
[ARG_POINTER_REGNUM
] = BASE_REGS
;
2050 rs6000_regno_regclass
[FRAME_POINTER_REGNUM
] = BASE_REGS
;
2052 /* Precalculate vector information, this must be set up before the
2053 rs6000_hard_regno_nregs_internal below. */
2054 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2056 rs6000_vector_unit
[m
] = rs6000_vector_mem
[m
] = VECTOR_NONE
;
2057 rs6000_vector_reload
[m
][0] = CODE_FOR_nothing
;
2058 rs6000_vector_reload
[m
][1] = CODE_FOR_nothing
;
2061 for (c
= 0; c
< (int)(int)RS6000_CONSTRAINT_MAX
; c
++)
2062 rs6000_constraints
[c
] = NO_REGS
;
2064 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2065 believes it can use native alignment or still uses 128-bit alignment. */
2066 if (TARGET_VSX
&& !TARGET_VSX_ALIGN_128
)
2077 /* V2DF mode, VSX only. */
2080 rs6000_vector_unit
[V2DFmode
] = VECTOR_VSX
;
2081 rs6000_vector_mem
[V2DFmode
] = VECTOR_VSX
;
2082 rs6000_vector_align
[V2DFmode
] = align64
;
2085 /* V4SF mode, either VSX or Altivec. */
2088 rs6000_vector_unit
[V4SFmode
] = VECTOR_VSX
;
2089 rs6000_vector_mem
[V4SFmode
] = VECTOR_VSX
;
2090 rs6000_vector_align
[V4SFmode
] = align32
;
2092 else if (TARGET_ALTIVEC
)
2094 rs6000_vector_unit
[V4SFmode
] = VECTOR_ALTIVEC
;
2095 rs6000_vector_mem
[V4SFmode
] = VECTOR_ALTIVEC
;
2096 rs6000_vector_align
[V4SFmode
] = align32
;
2099 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2103 rs6000_vector_unit
[V4SImode
] = VECTOR_ALTIVEC
;
2104 rs6000_vector_unit
[V8HImode
] = VECTOR_ALTIVEC
;
2105 rs6000_vector_unit
[V16QImode
] = VECTOR_ALTIVEC
;
2106 rs6000_vector_align
[V4SImode
] = align32
;
2107 rs6000_vector_align
[V8HImode
] = align32
;
2108 rs6000_vector_align
[V16QImode
] = align32
;
2112 rs6000_vector_mem
[V4SImode
] = VECTOR_VSX
;
2113 rs6000_vector_mem
[V8HImode
] = VECTOR_VSX
;
2114 rs6000_vector_mem
[V16QImode
] = VECTOR_VSX
;
2118 rs6000_vector_mem
[V4SImode
] = VECTOR_ALTIVEC
;
2119 rs6000_vector_mem
[V8HImode
] = VECTOR_ALTIVEC
;
2120 rs6000_vector_mem
[V16QImode
] = VECTOR_ALTIVEC
;
2124 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2125 Altivec doesn't have 64-bit support. */
2128 rs6000_vector_mem
[V2DImode
] = VECTOR_VSX
;
2129 rs6000_vector_unit
[V2DImode
] = VECTOR_NONE
;
2130 rs6000_vector_align
[V2DImode
] = align64
;
2133 /* DFmode, see if we want to use the VSX unit. */
2134 if (TARGET_VSX
&& TARGET_VSX_SCALAR_DOUBLE
)
2136 rs6000_vector_unit
[DFmode
] = VECTOR_VSX
;
2137 rs6000_vector_mem
[DFmode
]
2138 = (TARGET_VSX_SCALAR_MEMORY
? VECTOR_VSX
: VECTOR_NONE
);
2139 rs6000_vector_align
[DFmode
] = align64
;
2142 /* TODO add SPE and paired floating point vector support. */
2144 /* Register class constaints for the constraints that depend on compile
2146 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
2147 rs6000_constraints
[RS6000_CONSTRAINT_f
] = FLOAT_REGS
;
2149 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
2150 rs6000_constraints
[RS6000_CONSTRAINT_d
] = FLOAT_REGS
;
2154 /* At present, we just use VSX_REGS, but we have different constraints
2155 based on the use, in case we want to fine tune the default register
2156 class used. wa = any VSX register, wf = register class to use for
2157 V4SF, wd = register class to use for V2DF, and ws = register classs to
2158 use for DF scalars. */
2159 rs6000_constraints
[RS6000_CONSTRAINT_wa
] = VSX_REGS
;
2160 rs6000_constraints
[RS6000_CONSTRAINT_wf
] = VSX_REGS
;
2161 rs6000_constraints
[RS6000_CONSTRAINT_wd
] = VSX_REGS
;
2162 rs6000_constraints
[RS6000_CONSTRAINT_ws
] = (TARGET_VSX_SCALAR_MEMORY
2168 rs6000_constraints
[RS6000_CONSTRAINT_v
] = ALTIVEC_REGS
;
2170 /* Set up the reload helper functions. */
2171 if (TARGET_VSX
|| TARGET_ALTIVEC
)
2175 rs6000_vector_reload
[V16QImode
][0] = CODE_FOR_reload_v16qi_di_store
;
2176 rs6000_vector_reload
[V16QImode
][1] = CODE_FOR_reload_v16qi_di_load
;
2177 rs6000_vector_reload
[V8HImode
][0] = CODE_FOR_reload_v8hi_di_store
;
2178 rs6000_vector_reload
[V8HImode
][1] = CODE_FOR_reload_v8hi_di_load
;
2179 rs6000_vector_reload
[V4SImode
][0] = CODE_FOR_reload_v4si_di_store
;
2180 rs6000_vector_reload
[V4SImode
][1] = CODE_FOR_reload_v4si_di_load
;
2181 rs6000_vector_reload
[V2DImode
][0] = CODE_FOR_reload_v2di_di_store
;
2182 rs6000_vector_reload
[V2DImode
][1] = CODE_FOR_reload_v2di_di_load
;
2183 rs6000_vector_reload
[V4SFmode
][0] = CODE_FOR_reload_v4sf_di_store
;
2184 rs6000_vector_reload
[V4SFmode
][1] = CODE_FOR_reload_v4sf_di_load
;
2185 rs6000_vector_reload
[V2DFmode
][0] = CODE_FOR_reload_v2df_di_store
;
2186 rs6000_vector_reload
[V2DFmode
][1] = CODE_FOR_reload_v2df_di_load
;
2190 rs6000_vector_reload
[V16QImode
][0] = CODE_FOR_reload_v16qi_si_store
;
2191 rs6000_vector_reload
[V16QImode
][1] = CODE_FOR_reload_v16qi_si_load
;
2192 rs6000_vector_reload
[V8HImode
][0] = CODE_FOR_reload_v8hi_si_store
;
2193 rs6000_vector_reload
[V8HImode
][1] = CODE_FOR_reload_v8hi_si_load
;
2194 rs6000_vector_reload
[V4SImode
][0] = CODE_FOR_reload_v4si_si_store
;
2195 rs6000_vector_reload
[V4SImode
][1] = CODE_FOR_reload_v4si_si_load
;
2196 rs6000_vector_reload
[V2DImode
][0] = CODE_FOR_reload_v2di_si_store
;
2197 rs6000_vector_reload
[V2DImode
][1] = CODE_FOR_reload_v2di_si_load
;
2198 rs6000_vector_reload
[V4SFmode
][0] = CODE_FOR_reload_v4sf_si_store
;
2199 rs6000_vector_reload
[V4SFmode
][1] = CODE_FOR_reload_v4sf_si_load
;
2200 rs6000_vector_reload
[V2DFmode
][0] = CODE_FOR_reload_v2df_si_store
;
2201 rs6000_vector_reload
[V2DFmode
][1] = CODE_FOR_reload_v2df_si_load
;
2205 /* Precalculate HARD_REGNO_NREGS. */
2206 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
2207 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2208 rs6000_hard_regno_nregs
[m
][r
]
2209 = rs6000_hard_regno_nregs_internal (r
, (enum machine_mode
)m
);
2211 /* Precalculate HARD_REGNO_MODE_OK. */
2212 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
2213 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2214 if (rs6000_hard_regno_mode_ok (r
, (enum machine_mode
)m
))
2215 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
2217 /* Precalculate CLASS_MAX_NREGS sizes. */
2218 for (c
= 0; c
< LIM_REG_CLASSES
; ++c
)
2222 if (TARGET_VSX
&& VSX_REG_CLASS_P (c
))
2223 reg_size
= UNITS_PER_VSX_WORD
;
2225 else if (c
== ALTIVEC_REGS
)
2226 reg_size
= UNITS_PER_ALTIVEC_WORD
;
2228 else if (c
== FLOAT_REGS
)
2229 reg_size
= UNITS_PER_FP_WORD
;
2232 reg_size
= UNITS_PER_WORD
;
2234 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2235 rs6000_class_max_nregs
[m
][c
]
2236 = (GET_MODE_SIZE (m
) + reg_size
- 1) / reg_size
;
2239 if (TARGET_E500_DOUBLE
)
2240 rs6000_class_max_nregs
[DFmode
][GENERAL_REGS
] = 1;
2242 /* Calculate which modes to automatically generate code to use a the
2243 reciprocal divide and square root instructions. In the future, possibly
2244 automatically generate the instructions even if the user did not specify
2245 -mrecip. The older machines double precision reciprocal sqrt estimate is
2246 not accurate enough. */
2247 memset (rs6000_recip_bits
, 0, sizeof (rs6000_recip_bits
));
2249 rs6000_recip_bits
[SFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2251 rs6000_recip_bits
[DFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2252 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
))
2253 rs6000_recip_bits
[V4SFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2254 if (VECTOR_UNIT_VSX_P (V2DFmode
))
2255 rs6000_recip_bits
[V2DFmode
] = RS6000_RECIP_MASK_HAVE_RE
;
2257 if (TARGET_FRSQRTES
)
2258 rs6000_recip_bits
[SFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2260 rs6000_recip_bits
[DFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2261 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
))
2262 rs6000_recip_bits
[V4SFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2263 if (VECTOR_UNIT_VSX_P (V2DFmode
))
2264 rs6000_recip_bits
[V2DFmode
] |= RS6000_RECIP_MASK_HAVE_RSQRTE
;
2266 if (rs6000_recip_control
)
2268 if (!TARGET_FUSED_MADD
)
2269 warning (0, "-mrecip requires -mfused-madd");
2270 if (!flag_finite_math_only
)
2271 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2272 if (flag_trapping_math
)
2273 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2274 if (!flag_reciprocal_math
)
2275 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2276 if (TARGET_FUSED_MADD
&& flag_finite_math_only
&& !flag_trapping_math
2277 && flag_reciprocal_math
)
2279 if (RS6000_RECIP_HAVE_RE_P (SFmode
)
2280 && (rs6000_recip_control
& RECIP_SF_DIV
) != 0)
2281 rs6000_recip_bits
[SFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2283 if (RS6000_RECIP_HAVE_RE_P (DFmode
)
2284 && (rs6000_recip_control
& RECIP_DF_DIV
) != 0)
2285 rs6000_recip_bits
[DFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2287 if (RS6000_RECIP_HAVE_RE_P (V4SFmode
)
2288 && (rs6000_recip_control
& RECIP_V4SF_DIV
) != 0)
2289 rs6000_recip_bits
[V4SFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2291 if (RS6000_RECIP_HAVE_RE_P (V2DFmode
)
2292 && (rs6000_recip_control
& RECIP_V2DF_DIV
) != 0)
2293 rs6000_recip_bits
[V2DFmode
] |= RS6000_RECIP_MASK_AUTO_RE
;
2295 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode
)
2296 && (rs6000_recip_control
& RECIP_SF_RSQRT
) != 0)
2297 rs6000_recip_bits
[SFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2299 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode
)
2300 && (rs6000_recip_control
& RECIP_DF_RSQRT
) != 0)
2301 rs6000_recip_bits
[DFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2303 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode
)
2304 && (rs6000_recip_control
& RECIP_V4SF_RSQRT
) != 0)
2305 rs6000_recip_bits
[V4SFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2307 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode
)
2308 && (rs6000_recip_control
& RECIP_V2DF_RSQRT
) != 0)
2309 rs6000_recip_bits
[V2DFmode
] |= RS6000_RECIP_MASK_AUTO_RSQRTE
;
2313 if (TARGET_DEBUG_REG
)
2314 rs6000_debug_reg_global ();
2316 if (TARGET_DEBUG_COST
|| TARGET_DEBUG_REG
)
2318 "SImode variable mult cost = %d\n"
2319 "SImode constant mult cost = %d\n"
2320 "SImode short constant mult cost = %d\n"
2321 "DImode multipliciation cost = %d\n"
2322 "SImode division cost = %d\n"
2323 "DImode division cost = %d\n"
2324 "Simple fp operation cost = %d\n"
2325 "DFmode multiplication cost = %d\n"
2326 "SFmode division cost = %d\n"
2327 "DFmode division cost = %d\n"
2328 "cache line size = %d\n"
2329 "l1 cache size = %d\n"
2330 "l2 cache size = %d\n"
2331 "simultaneous prefetches = %d\n"
2334 rs6000_cost
->mulsi_const
,
2335 rs6000_cost
->mulsi_const9
,
2343 rs6000_cost
->cache_line_size
,
2344 rs6000_cost
->l1_cache_size
,
2345 rs6000_cost
->l2_cache_size
,
2346 rs6000_cost
->simultaneous_prefetches
);
2350 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2353 darwin_rs6000_override_options (void)
2355 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2357 rs6000_altivec_abi
= 1;
2358 TARGET_ALTIVEC_VRSAVE
= 1;
2359 if (DEFAULT_ABI
== ABI_DARWIN
)
2361 if (MACHO_DYNAMIC_NO_PIC_P
)
2364 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2367 else if (flag_pic
== 1)
2372 darwin_one_byte_bool
= 1;
2374 if (TARGET_64BIT
&& ! TARGET_POWERPC64
)
2376 target_flags
|= MASK_POWERPC64
;
2377 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2381 rs6000_default_long_calls
= 1;
2382 target_flags
|= MASK_SOFT_FLOAT
;
2385 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2387 if (!flag_mkernel
&& !flag_apple_kext
2389 && ! (target_flags_explicit
& MASK_ALTIVEC
))
2390 target_flags
|= MASK_ALTIVEC
;
2392 /* Unless the user (not the configurer) has explicitly overridden
2393 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2394 G4 unless targetting the kernel. */
2397 && strverscmp (darwin_macosx_version_min
, "10.5") >= 0
2398 && ! (target_flags_explicit
& MASK_ALTIVEC
)
2399 && ! rs6000_select
[1].string
)
2401 target_flags
|= MASK_ALTIVEC
;
2406 /* If not otherwise specified by a target, make 'long double' equivalent to
2409 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2410 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2413 /* Override command line options. Mostly we process the processor
2414 type and sometimes adjust other TARGET_ options. */
2417 rs6000_option_override_internal (const char *default_cpu
)
2420 struct rs6000_cpu_select
*ptr
;
2423 /* Simplifications for entries below. */
2426 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
2427 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
2430 /* This table occasionally claims that a processor does not support
2431 a particular feature even though it does, but the feature is slower
2432 than the alternative. Thus, it shouldn't be relied on as a
2433 complete description of the processor's support.
2435 Please keep this list in order, and don't forget to update the
2436 documentation in invoke.texi when adding a new processor or
2440 const char *const name
; /* Canonical processor name. */
2441 const enum processor_type processor
; /* Processor type enum value. */
2442 const int target_enable
; /* Target flags to enable. */
2443 } const processor_target_table
[]
2444 = {{"401", PROCESSOR_PPC403
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2445 {"403", PROCESSOR_PPC403
,
2446 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_STRICT_ALIGN
},
2447 {"405", PROCESSOR_PPC405
,
2448 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
2449 {"405fp", PROCESSOR_PPC405
,
2450 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
2451 {"440", PROCESSOR_PPC440
,
2452 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
2453 {"440fp", PROCESSOR_PPC440
,
2454 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
2455 {"464", PROCESSOR_PPC440
,
2456 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
2457 {"464fp", PROCESSOR_PPC440
,
2458 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
2459 {"476", PROCESSOR_PPC476
,
2460 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_PPC_GFXOPT
| MASK_MFCRF
2461 | MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_MULHW
| MASK_DLMZB
},
2462 {"476fp", PROCESSOR_PPC476
,
2463 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_MFCRF
| MASK_POPCNTB
2464 | MASK_FPRND
| MASK_CMPB
| MASK_MULHW
| MASK_DLMZB
},
2465 {"505", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
},
2466 {"601", PROCESSOR_PPC601
,
2467 MASK_POWER
| POWERPC_BASE_MASK
| MASK_MULTIPLE
| MASK_STRING
},
2468 {"602", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2469 {"603", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2470 {"603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2471 {"604", PROCESSOR_PPC604
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2472 {"604e", PROCESSOR_PPC604e
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2473 {"620", PROCESSOR_PPC620
,
2474 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
2475 {"630", PROCESSOR_PPC630
,
2476 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
2477 {"740", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2478 {"7400", PROCESSOR_PPC7400
, POWERPC_7400_MASK
},
2479 {"7450", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
2480 {"750", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2481 {"801", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2482 {"821", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2483 {"823", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2484 {"8540", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
2486 /* 8548 has a dummy entry for now. */
2487 {"8548", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
2489 {"a2", PROCESSOR_PPCA2
,
2490 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_POPCNTB
2491 | MASK_CMPB
| MASK_NO_UPDATE
},
2492 {"e300c2", PROCESSOR_PPCE300C2
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2493 {"e300c3", PROCESSOR_PPCE300C3
, POWERPC_BASE_MASK
},
2494 {"e500mc", PROCESSOR_PPCE500MC
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
2496 {"e500mc64", PROCESSOR_PPCE500MC64
, POWERPC_BASE_MASK
| MASK_POWERPC64
2497 | MASK_PPC_GFXOPT
| MASK_ISEL
},
2498 {"860", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2499 {"970", PROCESSOR_POWER4
,
2500 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
2501 {"cell", PROCESSOR_CELL
,
2502 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
2503 {"common", PROCESSOR_COMMON
, MASK_NEW_MNEMONICS
},
2504 {"ec603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2505 {"G3", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2506 {"G4", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
2507 {"G5", PROCESSOR_POWER4
,
2508 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
2509 {"titan", PROCESSOR_TITAN
,
2510 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
2511 {"power", PROCESSOR_POWER
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
2512 {"power2", PROCESSOR_POWER
,
2513 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
2514 {"power3", PROCESSOR_PPC630
,
2515 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
2516 {"power4", PROCESSOR_POWER4
,
2517 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
2519 {"power5", PROCESSOR_POWER5
,
2520 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
2521 | MASK_MFCRF
| MASK_POPCNTB
},
2522 {"power5+", PROCESSOR_POWER5
,
2523 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
2524 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
},
2525 {"power6", PROCESSOR_POWER6
,
2526 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
2527 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
2528 | MASK_RECIP_PRECISION
},
2529 {"power6x", PROCESSOR_POWER6
,
2530 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
2531 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
2532 | MASK_MFPGPR
| MASK_RECIP_PRECISION
},
2533 {"power7", PROCESSOR_POWER7
, /* Don't add MASK_ISEL by default */
2534 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_MFCRF
2535 | MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
| MASK_POPCNTD
2536 | MASK_VSX
| MASK_RECIP_PRECISION
},
2537 {"powerpc", PROCESSOR_POWERPC
, POWERPC_BASE_MASK
},
2538 {"powerpc64", PROCESSOR_POWERPC64
,
2539 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
2540 {"rios", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
2541 {"rios1", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
2542 {"rios2", PROCESSOR_RIOS2
,
2543 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
2544 {"rsc", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
2545 {"rsc1", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
2546 {"rs64", PROCESSOR_RS64A
,
2547 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
}
2550 const size_t ptt_size
= ARRAY_SIZE (processor_target_table
);
2552 /* Some OSs don't support saving the high part of 64-bit registers on
2553 context switch. Other OSs don't support saving Altivec registers.
2554 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2555 settings; if the user wants either, the user must explicitly specify
2556 them and we won't interfere with the user's specification. */
2559 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
2560 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
| MASK_STRICT_ALIGN
2561 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
2562 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_MULHW
2563 | MASK_DLMZB
| MASK_CMPB
| MASK_MFPGPR
| MASK_DFP
2564 | MASK_POPCNTD
| MASK_VSX
| MASK_ISEL
| MASK_NO_UPDATE
2565 | MASK_RECIP_PRECISION
)
2568 /* Masks for instructions set at various powerpc ISAs. */
2570 ISA_2_1_MASKS
= MASK_MFCRF
,
2571 ISA_2_2_MASKS
= (ISA_2_1_MASKS
| MASK_POPCNTB
| MASK_FPRND
),
2573 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't
2574 add ALTIVEC, since in general it isn't a win on power6. In ISA 2.04,
2575 fsel, fre, fsqrt, etc. were no longer documented as optional. Group
2576 masks by server and embedded. */
2577 ISA_2_5_MASKS_EMBEDDED
= (ISA_2_2_MASKS
| MASK_CMPB
| MASK_RECIP_PRECISION
2578 | MASK_PPC_GFXOPT
| MASK_PPC_GPOPT
),
2579 ISA_2_5_MASKS_SERVER
= (ISA_2_5_MASKS_EMBEDDED
| MASK_DFP
),
2581 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
2582 altivec is a win so enable it. */
2583 ISA_2_6_MASKS_EMBEDDED
= (ISA_2_5_MASKS_EMBEDDED
| MASK_POPCNTD
),
2584 ISA_2_6_MASKS_SERVER
= (ISA_2_5_MASKS_SERVER
| MASK_POPCNTD
| MASK_ALTIVEC
2588 /* Numerous experiment shows that IRA based loop pressure
2589 calculation works better for RTL loop invariant motion on targets
2590 with enough (>= 32) registers. It is an expensive optimization.
2591 So it is on only for peak performance. */
2593 flag_ira_loop_pressure
= 1;
2595 /* Set the pointer size. */
2598 rs6000_pmode
= (int)DImode
;
2599 rs6000_pointer_size
= 64;
2603 rs6000_pmode
= (int)SImode
;
2604 rs6000_pointer_size
= 32;
2607 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
2608 #ifdef OS_MISSING_POWERPC64
2609 if (OS_MISSING_POWERPC64
)
2610 set_masks
&= ~MASK_POWERPC64
;
2612 #ifdef OS_MISSING_ALTIVEC
2613 if (OS_MISSING_ALTIVEC
)
2614 set_masks
&= ~MASK_ALTIVEC
;
2617 /* Don't override by the processor default if given explicitly. */
2618 set_masks
&= ~target_flags_explicit
;
2620 /* Identify the processor type. */
2621 rs6000_select
[0].string
= default_cpu
;
2622 rs6000_cpu
= TARGET_POWERPC64
? PROCESSOR_DEFAULT64
: PROCESSOR_DEFAULT
;
2624 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
2626 ptr
= &rs6000_select
[i
];
2627 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
2629 for (j
= 0; j
< ptt_size
; j
++)
2630 if (! strcmp (ptr
->string
, processor_target_table
[j
].name
))
2632 if (ptr
->set_tune_p
)
2633 rs6000_cpu
= processor_target_table
[j
].processor
;
2635 if (ptr
->set_arch_p
)
2637 target_flags
&= ~set_masks
;
2638 target_flags
|= (processor_target_table
[j
].target_enable
2645 error ("bad value (%s) for %s switch", ptr
->string
, ptr
->name
);
2649 if (rs6000_cpu
== PROCESSOR_PPCE300C2
|| rs6000_cpu
== PROCESSOR_PPCE300C3
2650 || rs6000_cpu
== PROCESSOR_PPCE500MC
|| rs6000_cpu
== PROCESSOR_PPCE500MC64
)
2653 error ("AltiVec not supported in this target");
2655 error ("Spe not supported in this target");
2658 /* Disable Cell microcode if we are optimizing for the Cell
2659 and not optimizing for size. */
2660 if (rs6000_gen_cell_microcode
== -1)
2661 rs6000_gen_cell_microcode
= !(rs6000_cpu
== PROCESSOR_CELL
2664 /* If we are optimizing big endian systems for space and it's OK to
2665 use instructions that would be microcoded on the Cell, use the
2666 load/store multiple and string instructions. */
2667 if (BYTES_BIG_ENDIAN
&& optimize_size
&& rs6000_gen_cell_microcode
)
2668 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
2670 /* Don't allow -mmultiple or -mstring on little endian systems
2671 unless the cpu is a 750, because the hardware doesn't support the
2672 instructions used in little endian mode, and causes an alignment
2673 trap. The 750 does not cause an alignment trap (except when the
2674 target is unaligned). */
2676 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
2678 if (TARGET_MULTIPLE
)
2680 target_flags
&= ~MASK_MULTIPLE
;
2681 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
2682 warning (0, "-mmultiple is not supported on little endian systems");
2687 target_flags
&= ~MASK_STRING
;
2688 if ((target_flags_explicit
& MASK_STRING
) != 0)
2689 warning (0, "-mstring is not supported on little endian systems");
2693 /* Add some warnings for VSX. */
2696 const char *msg
= NULL
;
2697 if (!TARGET_HARD_FLOAT
|| !TARGET_FPRS
2698 || !TARGET_SINGLE_FLOAT
|| !TARGET_DOUBLE_FLOAT
)
2700 if (target_flags_explicit
& MASK_VSX
)
2701 msg
= N_("-mvsx requires hardware floating point");
2703 target_flags
&= ~ MASK_VSX
;
2705 else if (TARGET_PAIRED_FLOAT
)
2706 msg
= N_("-mvsx and -mpaired are incompatible");
2707 /* The hardware will allow VSX and little endian, but until we make sure
2708 things like vector select, etc. work don't allow VSX on little endian
2709 systems at this point. */
2710 else if (!BYTES_BIG_ENDIAN
)
2711 msg
= N_("-mvsx used with little endian code");
2712 else if (TARGET_AVOID_XFORM
> 0)
2713 msg
= N_("-mvsx needs indexed addressing");
2714 else if (!TARGET_ALTIVEC
&& (target_flags_explicit
& MASK_ALTIVEC
))
2716 if (target_flags_explicit
& MASK_VSX
)
2717 msg
= N_("-mvsx and -mno-altivec are incompatible");
2719 msg
= N_("-mno-altivec disables vsx");
2725 target_flags
&= ~ MASK_VSX
;
2726 target_flags_explicit
|= MASK_VSX
;
2730 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2731 unless the user explicitly used the -mno-<option> to disable the code. */
2733 target_flags
|= (ISA_2_6_MASKS_SERVER
& ~target_flags_explicit
);
2734 else if (TARGET_POPCNTD
)
2735 target_flags
|= (ISA_2_6_MASKS_EMBEDDED
& ~target_flags_explicit
);
2736 else if (TARGET_DFP
)
2737 target_flags
|= (ISA_2_5_MASKS_SERVER
& ~target_flags_explicit
);
2738 else if (TARGET_CMPB
)
2739 target_flags
|= (ISA_2_5_MASKS_EMBEDDED
& ~target_flags_explicit
);
2740 else if (TARGET_POPCNTB
|| TARGET_FPRND
)
2741 target_flags
|= (ISA_2_2_MASKS
& ~target_flags_explicit
);
2742 else if (TARGET_ALTIVEC
)
2743 target_flags
|= (MASK_PPC_GFXOPT
& ~target_flags_explicit
);
2745 /* E500mc does "better" if we inline more aggressively. Respect the
2746 user's opinion, though. */
2747 if (rs6000_block_move_inline_limit
== 0
2748 && (rs6000_cpu
== PROCESSOR_PPCE500MC
2749 || rs6000_cpu
== PROCESSOR_PPCE500MC64
))
2750 rs6000_block_move_inline_limit
= 128;
2752 /* store_one_arg depends on expand_block_move to handle at least the
2753 size of reg_parm_stack_space. */
2754 if (rs6000_block_move_inline_limit
< (TARGET_POWERPC64
? 64 : 32))
2755 rs6000_block_move_inline_limit
= (TARGET_POWERPC64
? 64 : 32);
2757 /* Set debug flags */
2758 if (rs6000_debug_name
)
2760 if (! strcmp (rs6000_debug_name
, "all"))
2761 rs6000_debug_stack
= rs6000_debug_arg
= rs6000_debug_reg
2762 = rs6000_debug_addr
= rs6000_debug_cost
= 1;
2763 else if (! strcmp (rs6000_debug_name
, "stack"))
2764 rs6000_debug_stack
= 1;
2765 else if (! strcmp (rs6000_debug_name
, "arg"))
2766 rs6000_debug_arg
= 1;
2767 else if (! strcmp (rs6000_debug_name
, "reg"))
2768 rs6000_debug_reg
= 1;
2769 else if (! strcmp (rs6000_debug_name
, "addr"))
2770 rs6000_debug_addr
= 1;
2771 else if (! strcmp (rs6000_debug_name
, "cost"))
2772 rs6000_debug_cost
= 1;
2774 error ("unknown -mdebug-%s switch", rs6000_debug_name
);
2776 /* If the appropriate debug option is enabled, replace the target hooks
2777 with debug versions that call the real version and then prints
2778 debugging information. */
2779 if (TARGET_DEBUG_COST
)
2781 targetm
.rtx_costs
= rs6000_debug_rtx_costs
;
2782 targetm
.address_cost
= rs6000_debug_address_cost
;
2783 targetm
.sched
.adjust_cost
= rs6000_debug_adjust_cost
;
2786 if (TARGET_DEBUG_ADDR
)
2788 targetm
.legitimate_address_p
= rs6000_debug_legitimate_address_p
;
2789 targetm
.legitimize_address
= rs6000_debug_legitimize_address
;
2790 rs6000_secondary_reload_class_ptr
2791 = rs6000_debug_secondary_reload_class
;
2792 rs6000_secondary_memory_needed_ptr
2793 = rs6000_debug_secondary_memory_needed
;
2794 rs6000_cannot_change_mode_class_ptr
2795 = rs6000_debug_cannot_change_mode_class
;
2796 rs6000_preferred_reload_class_ptr
2797 = rs6000_debug_preferred_reload_class
;
2798 rs6000_legitimize_reload_address_ptr
2799 = rs6000_debug_legitimize_reload_address
;
2800 rs6000_mode_dependent_address_ptr
2801 = rs6000_debug_mode_dependent_address
;
2805 if (rs6000_traceback_name
)
2807 if (! strncmp (rs6000_traceback_name
, "full", 4))
2808 rs6000_traceback
= traceback_full
;
2809 else if (! strncmp (rs6000_traceback_name
, "part", 4))
2810 rs6000_traceback
= traceback_part
;
2811 else if (! strncmp (rs6000_traceback_name
, "no", 2))
2812 rs6000_traceback
= traceback_none
;
2814 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2815 rs6000_traceback_name
);
2818 if (rs6000_veclibabi_name
)
2820 if (strcmp (rs6000_veclibabi_name
, "mass") == 0)
2821 rs6000_veclib_handler
= rs6000_builtin_vectorized_libmass
;
2823 error ("unknown vectorization library ABI type (%s) for "
2824 "-mveclibabi= switch", rs6000_veclibabi_name
);
2827 if (!rs6000_explicit_options
.long_double
)
2828 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2830 #ifndef POWERPC_LINUX
2831 if (!rs6000_explicit_options
.ieee
)
2832 rs6000_ieeequad
= 1;
2835 /* Enable Altivec ABI for AIX -maltivec. */
2836 if (TARGET_XCOFF
&& (TARGET_ALTIVEC
|| TARGET_VSX
))
2837 rs6000_altivec_abi
= 1;
2839 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2840 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2841 be explicitly overridden in either case. */
2844 if (!rs6000_explicit_options
.altivec_abi
2845 && (TARGET_64BIT
|| TARGET_ALTIVEC
|| TARGET_VSX
))
2846 rs6000_altivec_abi
= 1;
2848 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2849 if (!rs6000_explicit_options
.vrsave
)
2850 TARGET_ALTIVEC_VRSAVE
= rs6000_altivec_abi
;
2853 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2854 So far, the only darwin64 targets are also MACH-O. */
2856 && DEFAULT_ABI
== ABI_DARWIN
2859 rs6000_darwin64_abi
= 1;
2860 /* Default to natural alignment, for better performance. */
2861 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
2864 /* Place FP constants in the constant pool instead of TOC
2865 if section anchors enabled. */
2866 if (flag_section_anchors
)
2867 TARGET_NO_FP_IN_TOC
= 1;
2869 /* Handle -mtls-size option. */
2870 rs6000_parse_tls_size_option ();
2872 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2873 SUBTARGET_OVERRIDE_OPTIONS
;
2875 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2876 SUBSUBTARGET_OVERRIDE_OPTIONS
;
2878 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2879 SUB3TARGET_OVERRIDE_OPTIONS
;
2882 if (TARGET_E500
|| rs6000_cpu
== PROCESSOR_PPCE500MC
2883 || rs6000_cpu
== PROCESSOR_PPCE500MC64
)
2885 /* The e500 and e500mc do not have string instructions, and we set
2886 MASK_STRING above when optimizing for size. */
2887 if ((target_flags
& MASK_STRING
) != 0)
2888 target_flags
= target_flags
& ~MASK_STRING
;
2890 else if (rs6000_select
[1].string
!= NULL
)
2892 /* For the powerpc-eabispe configuration, we set all these by
2893 default, so let's unset them if we manually set another
2894 CPU that is not the E500. */
2895 if (!rs6000_explicit_options
.spe_abi
)
2897 if (!rs6000_explicit_options
.spe
)
2899 if (!rs6000_explicit_options
.float_gprs
)
2900 rs6000_float_gprs
= 0;
2901 if (!(target_flags_explicit
& MASK_ISEL
))
2902 target_flags
&= ~MASK_ISEL
;
2905 /* Detect invalid option combinations with E500. */
2908 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
2909 && rs6000_cpu
!= PROCESSOR_POWER5
2910 && rs6000_cpu
!= PROCESSOR_POWER6
2911 && rs6000_cpu
!= PROCESSOR_POWER7
2912 && rs6000_cpu
!= PROCESSOR_PPCA2
2913 && rs6000_cpu
!= PROCESSOR_CELL
);
2914 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
2915 || rs6000_cpu
== PROCESSOR_POWER5
2916 || rs6000_cpu
== PROCESSOR_POWER7
);
2917 rs6000_align_branch_targets
= (rs6000_cpu
== PROCESSOR_POWER4
2918 || rs6000_cpu
== PROCESSOR_POWER5
2919 || rs6000_cpu
== PROCESSOR_POWER6
2920 || rs6000_cpu
== PROCESSOR_POWER7
2921 || rs6000_cpu
== PROCESSOR_PPCE500MC
2922 || rs6000_cpu
== PROCESSOR_PPCE500MC64
);
2924 /* Allow debug switches to override the above settings. */
2925 if (TARGET_ALWAYS_HINT
> 0)
2926 rs6000_always_hint
= TARGET_ALWAYS_HINT
;
2928 if (TARGET_SCHED_GROUPS
> 0)
2929 rs6000_sched_groups
= TARGET_SCHED_GROUPS
;
2931 if (TARGET_ALIGN_BRANCH_TARGETS
> 0)
2932 rs6000_align_branch_targets
= TARGET_ALIGN_BRANCH_TARGETS
;
2934 rs6000_sched_restricted_insns_priority
2935 = (rs6000_sched_groups
? 1 : 0);
2937 /* Handle -msched-costly-dep option. */
2938 rs6000_sched_costly_dep
2939 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
2941 if (rs6000_sched_costly_dep_str
)
2943 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
2944 rs6000_sched_costly_dep
= no_dep_costly
;
2945 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
2946 rs6000_sched_costly_dep
= all_deps_costly
;
2947 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
2948 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
2949 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
2950 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
2952 rs6000_sched_costly_dep
= ((enum rs6000_dependence_cost
)
2953 atoi (rs6000_sched_costly_dep_str
));
2956 /* Handle -minsert-sched-nops option. */
2957 rs6000_sched_insert_nops
2958 = (rs6000_sched_groups
? sched_finish_regroup_exact
: sched_finish_none
);
2960 if (rs6000_sched_insert_nops_str
)
2962 if (! strcmp (rs6000_sched_insert_nops_str
, "no"))
2963 rs6000_sched_insert_nops
= sched_finish_none
;
2964 else if (! strcmp (rs6000_sched_insert_nops_str
, "pad"))
2965 rs6000_sched_insert_nops
= sched_finish_pad_groups
;
2966 else if (! strcmp (rs6000_sched_insert_nops_str
, "regroup_exact"))
2967 rs6000_sched_insert_nops
= sched_finish_regroup_exact
;
2969 rs6000_sched_insert_nops
= ((enum rs6000_nop_insertion
)
2970 atoi (rs6000_sched_insert_nops_str
));
2973 #ifdef TARGET_REGNAMES
2974 /* If the user desires alternate register names, copy in the
2975 alternate names now. */
2976 if (TARGET_REGNAMES
)
2977 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
2980 /* Set aix_struct_return last, after the ABI is determined.
2981 If -maix-struct-return or -msvr4-struct-return was explicitly
2982 used, don't override with the ABI default. */
2983 if (!rs6000_explicit_options
.aix_struct_ret
)
2984 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
2987 /* IBM XL compiler defaults to unsigned bitfields. */
2988 if (TARGET_XL_COMPAT
)
2989 flag_signed_bitfields
= 0;
2992 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
2993 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
2996 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
2998 /* We can only guarantee the availability of DI pseudo-ops when
2999 assembling for 64-bit targets. */
3002 targetm
.asm_out
.aligned_op
.di
= NULL
;
3003 targetm
.asm_out
.unaligned_op
.di
= NULL
;
3006 /* Set branch target alignment, if not optimizing for size. */
3009 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3010 aligned 8byte to avoid misprediction by the branch predictor. */
3011 if (rs6000_cpu
== PROCESSOR_TITAN
3012 || rs6000_cpu
== PROCESSOR_CELL
)
3014 if (align_functions
<= 0)
3015 align_functions
= 8;
3016 if (align_jumps
<= 0)
3018 if (align_loops
<= 0)
3021 if (rs6000_align_branch_targets
)
3023 if (align_functions
<= 0)
3024 align_functions
= 16;
3025 if (align_jumps
<= 0)
3027 if (align_loops
<= 0)
3030 if (align_jumps_max_skip
<= 0)
3031 align_jumps_max_skip
= 15;
3032 if (align_loops_max_skip
<= 0)
3033 align_loops_max_skip
= 15;
3036 /* Arrange to save and restore machine status around nested functions. */
3037 init_machine_status
= rs6000_init_machine_status
;
3039 /* We should always be splitting complex arguments, but we can't break
3040 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3041 if (DEFAULT_ABI
!= ABI_AIX
)
3042 targetm
.calls
.split_complex_arg
= NULL
;
3044 /* Initialize rs6000_cost with the appropriate target costs. */
3046 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
3050 case PROCESSOR_RIOS1
:
3051 rs6000_cost
= &rios1_cost
;
3054 case PROCESSOR_RIOS2
:
3055 rs6000_cost
= &rios2_cost
;
3058 case PROCESSOR_RS64A
:
3059 rs6000_cost
= &rs64a_cost
;
3062 case PROCESSOR_MPCCORE
:
3063 rs6000_cost
= &mpccore_cost
;
3066 case PROCESSOR_PPC403
:
3067 rs6000_cost
= &ppc403_cost
;
3070 case PROCESSOR_PPC405
:
3071 rs6000_cost
= &ppc405_cost
;
3074 case PROCESSOR_PPC440
:
3075 rs6000_cost
= &ppc440_cost
;
3078 case PROCESSOR_PPC476
:
3079 rs6000_cost
= &ppc476_cost
;
3082 case PROCESSOR_PPC601
:
3083 rs6000_cost
= &ppc601_cost
;
3086 case PROCESSOR_PPC603
:
3087 rs6000_cost
= &ppc603_cost
;
3090 case PROCESSOR_PPC604
:
3091 rs6000_cost
= &ppc604_cost
;
3094 case PROCESSOR_PPC604e
:
3095 rs6000_cost
= &ppc604e_cost
;
3098 case PROCESSOR_PPC620
:
3099 rs6000_cost
= &ppc620_cost
;
3102 case PROCESSOR_PPC630
:
3103 rs6000_cost
= &ppc630_cost
;
3106 case PROCESSOR_CELL
:
3107 rs6000_cost
= &ppccell_cost
;
3110 case PROCESSOR_PPC750
:
3111 case PROCESSOR_PPC7400
:
3112 rs6000_cost
= &ppc750_cost
;
3115 case PROCESSOR_PPC7450
:
3116 rs6000_cost
= &ppc7450_cost
;
3119 case PROCESSOR_PPC8540
:
3120 rs6000_cost
= &ppc8540_cost
;
3123 case PROCESSOR_PPCE300C2
:
3124 case PROCESSOR_PPCE300C3
:
3125 rs6000_cost
= &ppce300c2c3_cost
;
3128 case PROCESSOR_PPCE500MC
:
3129 rs6000_cost
= &ppce500mc_cost
;
3132 case PROCESSOR_PPCE500MC64
:
3133 rs6000_cost
= &ppce500mc64_cost
;
3136 case PROCESSOR_TITAN
:
3137 rs6000_cost
= &titan_cost
;
3140 case PROCESSOR_POWER4
:
3141 case PROCESSOR_POWER5
:
3142 rs6000_cost
= &power4_cost
;
3145 case PROCESSOR_POWER6
:
3146 rs6000_cost
= &power6_cost
;
3149 case PROCESSOR_POWER7
:
3150 rs6000_cost
= &power7_cost
;
3153 case PROCESSOR_PPCA2
:
3154 rs6000_cost
= &ppca2_cost
;
3161 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES
,
3162 rs6000_cost
->simultaneous_prefetches
,
3163 global_options
.x_param_values
,
3164 global_options_set
.x_param_values
);
3165 maybe_set_param_value (PARAM_L1_CACHE_SIZE
, rs6000_cost
->l1_cache_size
,
3166 global_options
.x_param_values
,
3167 global_options_set
.x_param_values
);
3168 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE
,
3169 rs6000_cost
->cache_line_size
,
3170 global_options
.x_param_values
,
3171 global_options_set
.x_param_values
);
3172 maybe_set_param_value (PARAM_L2_CACHE_SIZE
, rs6000_cost
->l2_cache_size
,
3173 global_options
.x_param_values
,
3174 global_options_set
.x_param_values
);
3176 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
3177 can be optimized to ap = __builtin_next_arg (0). */
3178 if (DEFAULT_ABI
!= ABI_V4
)
3179 targetm
.expand_builtin_va_start
= NULL
;
3181 /* Set up single/double float flags.
3182 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3183 then set both flags. */
3184 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
3185 && rs6000_single_float
== 0 && rs6000_double_float
== 0)
3186 rs6000_single_float
= rs6000_double_float
= 1;
3188 /* Reset single and double FP flags if target is E500. */
3191 rs6000_single_float
= rs6000_double_float
= 0;
3192 if (TARGET_E500_SINGLE
)
3193 rs6000_single_float
= 1;
3194 if (TARGET_E500_DOUBLE
)
3195 rs6000_single_float
= rs6000_double_float
= 1;
3198 /* If not explicitly specified via option, decide whether to generate indexed
3199 load/store instructions. */
3200 if (TARGET_AVOID_XFORM
== -1)
3201 /* Avoid indexed addressing when targeting Power6 in order to avoid
3202 the DERAT mispredict penalty. */
3203 TARGET_AVOID_XFORM
= (rs6000_cpu
== PROCESSOR_POWER6
&& TARGET_CMPB
);
3205 /* Set the -mrecip options. */
3206 if (rs6000_recip_name
)
3208 char *p
= ASTRDUP (rs6000_recip_name
);
3210 unsigned int mask
, i
;
3213 while ((q
= strtok (p
, ",")) != NULL
)
3224 if (!strcmp (q
, "default"))
3225 mask
= ((TARGET_RECIP_PRECISION
)
3226 ? RECIP_HIGH_PRECISION
: RECIP_LOW_PRECISION
);
3229 for (i
= 0; i
< ARRAY_SIZE (recip_options
); i
++)
3230 if (!strcmp (q
, recip_options
[i
].string
))
3232 mask
= recip_options
[i
].mask
;
3236 if (i
== ARRAY_SIZE (recip_options
))
3238 error ("Unknown option for -mrecip=%s", q
);
3245 rs6000_recip_control
&= ~mask
;
3247 rs6000_recip_control
|= mask
;
3251 rs6000_init_hard_regno_mode_ok ();
3254 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3255 define the target cpu type. */
3258 rs6000_option_override (void)
3260 rs6000_option_override_internal (OPTION_TARGET_CPU_DEFAULT
);
3263 /* Implement targetm.vectorize.builtin_mask_for_load. */
3265 rs6000_builtin_mask_for_load (void)
3267 if (TARGET_ALTIVEC
|| TARGET_VSX
)
3268 return altivec_builtin_mask_for_load
;
3273 /* Implement targetm.vectorize.builtin_conversion.
3274 Returns a decl of a function that implements conversion of an integer vector
3275 into a floating-point vector, or vice-versa. DEST_TYPE is the
3276 destination type and SRC_TYPE the source type of the conversion.
3277 Return NULL_TREE if it is not available. */
3279 rs6000_builtin_conversion (unsigned int tcode
, tree dest_type
, tree src_type
)
3281 enum tree_code code
= (enum tree_code
) tcode
;
3285 case FIX_TRUNC_EXPR
:
3286 switch (TYPE_MODE (dest_type
))
3289 if (!VECTOR_UNIT_VSX_P (V2DFmode
))
3292 return TYPE_UNSIGNED (dest_type
)
3293 ? rs6000_builtin_decls
[VSX_BUILTIN_XVCVDPUXDS_UNS
]
3294 : rs6000_builtin_decls
[VSX_BUILTIN_XVCVDPSXDS
];
3297 if (VECTOR_UNIT_NONE_P (V4SImode
) || VECTOR_UNIT_NONE_P (V4SFmode
))
3300 return TYPE_UNSIGNED (dest_type
)
3301 ? rs6000_builtin_decls
[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
]
3302 : rs6000_builtin_decls
[VECTOR_BUILTIN_FIX_V4SF_V4SI
];
3309 switch (TYPE_MODE (src_type
))
3312 if (!VECTOR_UNIT_VSX_P (V2DFmode
))
3315 return TYPE_UNSIGNED (src_type
)
3316 ? rs6000_builtin_decls
[VSX_BUILTIN_XVCVUXDDP
]
3317 : rs6000_builtin_decls
[VSX_BUILTIN_XVCVSXDDP
];
3320 if (VECTOR_UNIT_NONE_P (V4SImode
) || VECTOR_UNIT_NONE_P (V4SFmode
))
3323 return TYPE_UNSIGNED (src_type
)
3324 ? rs6000_builtin_decls
[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
]
3325 : rs6000_builtin_decls
[VECTOR_BUILTIN_FLOAT_V4SI_V4SF
];
3336 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3338 rs6000_builtin_mul_widen_even (tree type
)
3340 if (!TARGET_ALTIVEC
)
3343 switch (TYPE_MODE (type
))
3346 return TYPE_UNSIGNED (type
)
3347 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUH_UNS
]
3348 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESH
];
3351 return TYPE_UNSIGNED (type
)
3352 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUB_UNS
]
3353 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESB
];
3359 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3361 rs6000_builtin_mul_widen_odd (tree type
)
3363 if (!TARGET_ALTIVEC
)
3366 switch (TYPE_MODE (type
))
3369 return TYPE_UNSIGNED (type
)
3370 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUH_UNS
]
3371 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSH
];
3374 return TYPE_UNSIGNED (type
)
3375 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUB_UNS
]
3376 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSB
];
3383 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3384 after applying N number of iterations. This routine does not determine
3385 how may iterations are required to reach desired alignment. */
3388 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED
, bool is_packed
)
3395 if (rs6000_alignment_flags
== MASK_ALIGN_NATURAL
)
3398 if (rs6000_alignment_flags
== MASK_ALIGN_POWER
)
3408 /* Assuming that all other types are naturally aligned. CHECKME! */
3413 /* Return true if the vector misalignment factor is supported by the
3416 rs6000_builtin_support_vector_misalignment (enum machine_mode mode
,
3423 /* Return if movmisalign pattern is not supported for this mode. */
3424 if (optab_handler (movmisalign_optab
, mode
) == CODE_FOR_nothing
)
3427 if (misalignment
== -1)
3429 /* Misalignment factor is unknown at compile time but we know
3430 it's word aligned. */
3431 if (rs6000_vector_alignment_reachable (type
, is_packed
))
3433 int element_size
= TREE_INT_CST_LOW (TYPE_SIZE (type
));
3435 if (element_size
== 64 || element_size
== 32)
3442 /* VSX supports word-aligned vector. */
3443 if (misalignment
% 4 == 0)
3449 /* Implement targetm.vectorize.builtin_vec_perm. */
3451 rs6000_builtin_vec_perm (tree type
, tree
*mask_element_type
)
3453 tree inner_type
= TREE_TYPE (type
);
3454 bool uns_p
= TYPE_UNSIGNED (inner_type
);
3457 *mask_element_type
= unsigned_char_type_node
;
3459 switch (TYPE_MODE (type
))
3463 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_16QI_UNS
]
3464 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_16QI
]);
3469 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_8HI_UNS
]
3470 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_8HI
]);
3475 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SI_UNS
]
3476 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SI
]);
3480 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SF
];
3484 if (!TARGET_ALLOW_DF_PERMUTE
)
3487 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_2DF
];
3491 if (!TARGET_ALLOW_DF_PERMUTE
)
3495 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_2DI_UNS
]
3496 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_2DI
]);
3508 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3510 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost
,
3511 tree vectype
, int misalign
)
3515 switch (type_of_cost
)
3525 case cond_branch_not_taken
:
3529 case cond_branch_taken
:
3532 case unaligned_load
:
3533 if (TARGET_VSX
&& TARGET_ALLOW_MOVMISALIGN
)
3535 elements
= TYPE_VECTOR_SUBPARTS (vectype
);
3537 /* Double word aligned. */
3545 /* Double word aligned. */
3549 /* Unknown misalignment. */
3562 /* Misaligned loads are not supported. */
3567 case unaligned_store
:
3568 if (TARGET_VSX
&& TARGET_ALLOW_MOVMISALIGN
)
3570 elements
= TYPE_VECTOR_SUBPARTS (vectype
);
3572 /* Double word aligned. */
3580 /* Double word aligned. */
3584 /* Unknown misalignment. */
3597 /* Misaligned stores are not supported. */
3607 /* Implement targetm.vectorize.preferred_simd_mode. */
3609 static enum machine_mode
3610 rs6000_preferred_simd_mode (enum machine_mode mode
)
3619 if (TARGET_ALTIVEC
|| TARGET_VSX
)
3643 if (TARGET_PAIRED_FLOAT
3649 /* Handle generic options of the form -mfoo=yes/no.
3650 NAME is the option name.
3651 VALUE is the option value.
3652 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3653 whether the option value is 'yes' or 'no' respectively. */
3655 rs6000_parse_yes_no_option (const char *name
, const char *value
, int *flag
)
3659 else if (!strcmp (value
, "yes"))
3661 else if (!strcmp (value
, "no"))
3664 error ("unknown -m%s= option specified: '%s'", name
, value
);
3667 /* Validate and record the size specified with the -mtls-size option. */
3670 rs6000_parse_tls_size_option (void)
3672 if (rs6000_tls_size_string
== 0)
3674 else if (strcmp (rs6000_tls_size_string
, "16") == 0)
3675 rs6000_tls_size
= 16;
3676 else if (strcmp (rs6000_tls_size_string
, "32") == 0)
3677 rs6000_tls_size
= 32;
3678 else if (strcmp (rs6000_tls_size_string
, "64") == 0)
3679 rs6000_tls_size
= 64;
3681 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string
);
3685 rs6000_option_optimization (int level ATTRIBUTE_UNUSED
,
3686 int size ATTRIBUTE_UNUSED
)
3688 if (DEFAULT_ABI
== ABI_DARWIN
)
3689 /* The Darwin libraries never set errno, so we might as well
3690 avoid calling them when that's the only reason we would. */
3691 flag_errno_math
= 0;
3693 /* Enable section anchors by default. */
3695 flag_section_anchors
= 2;
3698 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3701 rs6000_option_default_params (void)
3703 /* Double growth factor to counter reduced min jump length. */
3704 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS
, 16);
3707 static enum fpu_type_t
3708 rs6000_parse_fpu_option (const char *option
)
3710 if (!strcmp("none", option
)) return FPU_NONE
;
3711 if (!strcmp("sp_lite", option
)) return FPU_SF_LITE
;
3712 if (!strcmp("dp_lite", option
)) return FPU_DF_LITE
;
3713 if (!strcmp("sp_full", option
)) return FPU_SF_FULL
;
3714 if (!strcmp("dp_full", option
)) return FPU_DF_FULL
;
3715 error("unknown value %s for -mfpu", option
);
3720 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3721 library with vectorized intrinsics. */
3724 rs6000_builtin_vectorized_libmass (tree fndecl
, tree type_out
, tree type_in
)
3727 const char *suffix
= NULL
;
3728 tree fntype
, new_fndecl
, bdecl
= NULL_TREE
;
3731 enum machine_mode el_mode
, in_mode
;
3734 /* Libmass is suitable for unsafe math only as it does not correctly support
3735 parts of IEEE with the required precision such as denormals. Only support
3736 it if we have VSX to use the simd d2 or f4 functions.
3737 XXX: Add variable length support. */
3738 if (!flag_unsafe_math_optimizations
|| !TARGET_VSX
)
3741 el_mode
= TYPE_MODE (TREE_TYPE (type_out
));
3742 n
= TYPE_VECTOR_SUBPARTS (type_out
);
3743 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
3744 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
3745 if (el_mode
!= in_mode
3749 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
)
3751 enum built_in_function fn
= DECL_FUNCTION_CODE (fndecl
);
3754 case BUILT_IN_ATAN2
:
3755 case BUILT_IN_HYPOT
:
3761 case BUILT_IN_ACOSH
:
3763 case BUILT_IN_ASINH
:
3765 case BUILT_IN_ATANH
:
3773 case BUILT_IN_EXPM1
:
3774 case BUILT_IN_LGAMMA
:
3775 case BUILT_IN_LOG10
:
3776 case BUILT_IN_LOG1P
:
3784 bdecl
= implicit_built_in_decls
[fn
];
3785 suffix
= "d2"; /* pow -> powd2 */
3786 if (el_mode
!= DFmode
3791 case BUILT_IN_ATAN2F
:
3792 case BUILT_IN_HYPOTF
:
3797 case BUILT_IN_ACOSF
:
3798 case BUILT_IN_ACOSHF
:
3799 case BUILT_IN_ASINF
:
3800 case BUILT_IN_ASINHF
:
3801 case BUILT_IN_ATANF
:
3802 case BUILT_IN_ATANHF
:
3803 case BUILT_IN_CBRTF
:
3805 case BUILT_IN_COSHF
:
3807 case BUILT_IN_ERFCF
:
3808 case BUILT_IN_EXP2F
:
3810 case BUILT_IN_EXPM1F
:
3811 case BUILT_IN_LGAMMAF
:
3812 case BUILT_IN_LOG10F
:
3813 case BUILT_IN_LOG1PF
:
3814 case BUILT_IN_LOG2F
:
3817 case BUILT_IN_SINHF
:
3818 case BUILT_IN_SQRTF
:
3820 case BUILT_IN_TANHF
:
3821 bdecl
= implicit_built_in_decls
[fn
];
3822 suffix
= "4"; /* powf -> powf4 */
3823 if (el_mode
!= SFmode
3835 gcc_assert (suffix
!= NULL
);
3836 bname
= IDENTIFIER_POINTER (DECL_NAME (bdecl
));
3837 strcpy (name
, bname
+ sizeof ("__builtin_") - 1);
3838 strcat (name
, suffix
);
3841 fntype
= build_function_type_list (type_out
, type_in
, NULL
);
3842 else if (n_args
== 2)
3843 fntype
= build_function_type_list (type_out
, type_in
, type_in
, NULL
);
3847 /* Build a function declaration for the vectorized function. */
3848 new_fndecl
= build_decl (BUILTINS_LOCATION
,
3849 FUNCTION_DECL
, get_identifier (name
), fntype
);
3850 TREE_PUBLIC (new_fndecl
) = 1;
3851 DECL_EXTERNAL (new_fndecl
) = 1;
3852 DECL_IS_NOVOPS (new_fndecl
) = 1;
3853 TREE_READONLY (new_fndecl
) = 1;
3858 /* Returns a function decl for a vectorized version of the builtin function
3859 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3860 if it is not available. */
3863 rs6000_builtin_vectorized_function (tree fndecl
, tree type_out
,
3866 enum machine_mode in_mode
, out_mode
;
3869 if (TREE_CODE (type_out
) != VECTOR_TYPE
3870 || TREE_CODE (type_in
) != VECTOR_TYPE
3871 || !TARGET_VECTORIZE_BUILTINS
)
3874 out_mode
= TYPE_MODE (TREE_TYPE (type_out
));
3875 out_n
= TYPE_VECTOR_SUBPARTS (type_out
);
3876 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
3877 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
3879 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
)
3881 enum built_in_function fn
= DECL_FUNCTION_CODE (fndecl
);
3884 case BUILT_IN_COPYSIGN
:
3885 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3886 && out_mode
== DFmode
&& out_n
== 2
3887 && in_mode
== DFmode
&& in_n
== 2)
3888 return rs6000_builtin_decls
[VSX_BUILTIN_CPSGNDP
];
3890 case BUILT_IN_COPYSIGNF
:
3891 if (out_mode
!= SFmode
|| out_n
!= 4
3892 || in_mode
!= SFmode
|| in_n
!= 4)
3894 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3895 return rs6000_builtin_decls
[VSX_BUILTIN_CPSGNSP
];
3896 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3897 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_COPYSIGN_V4SF
];
3900 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3901 && out_mode
== DFmode
&& out_n
== 2
3902 && in_mode
== DFmode
&& in_n
== 2)
3903 return rs6000_builtin_decls
[VSX_BUILTIN_XVSQRTDP
];
3905 case BUILT_IN_SQRTF
:
3906 if (VECTOR_UNIT_VSX_P (V4SFmode
)
3907 && out_mode
== SFmode
&& out_n
== 4
3908 && in_mode
== SFmode
&& in_n
== 4)
3909 return rs6000_builtin_decls
[VSX_BUILTIN_XVSQRTSP
];
3912 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3913 && out_mode
== DFmode
&& out_n
== 2
3914 && in_mode
== DFmode
&& in_n
== 2)
3915 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIP
];
3917 case BUILT_IN_CEILF
:
3918 if (out_mode
!= SFmode
|| out_n
!= 4
3919 || in_mode
!= SFmode
|| in_n
!= 4)
3921 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3922 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIP
];
3923 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3924 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIP
];
3926 case BUILT_IN_FLOOR
:
3927 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3928 && out_mode
== DFmode
&& out_n
== 2
3929 && in_mode
== DFmode
&& in_n
== 2)
3930 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIM
];
3932 case BUILT_IN_FLOORF
:
3933 if (out_mode
!= SFmode
|| out_n
!= 4
3934 || in_mode
!= SFmode
|| in_n
!= 4)
3936 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3937 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIM
];
3938 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3939 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIM
];
3942 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3943 && out_mode
== DFmode
&& out_n
== 2
3944 && in_mode
== DFmode
&& in_n
== 2)
3945 return rs6000_builtin_decls
[VSX_BUILTIN_XVMADDDP
];
3948 if (VECTOR_UNIT_VSX_P (V4SFmode
)
3949 && out_mode
== SFmode
&& out_n
== 4
3950 && in_mode
== SFmode
&& in_n
== 4)
3951 return rs6000_builtin_decls
[VSX_BUILTIN_XVMADDSP
];
3952 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
)
3953 && out_mode
== SFmode
&& out_n
== 4
3954 && in_mode
== SFmode
&& in_n
== 4)
3955 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMADDFP
];
3957 case BUILT_IN_TRUNC
:
3958 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3959 && out_mode
== DFmode
&& out_n
== 2
3960 && in_mode
== DFmode
&& in_n
== 2)
3961 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIZ
];
3963 case BUILT_IN_TRUNCF
:
3964 if (out_mode
!= SFmode
|| out_n
!= 4
3965 || in_mode
!= SFmode
|| in_n
!= 4)
3967 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3968 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIZ
];
3969 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3970 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIZ
];
3972 case BUILT_IN_NEARBYINT
:
3973 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3974 && flag_unsafe_math_optimizations
3975 && out_mode
== DFmode
&& out_n
== 2
3976 && in_mode
== DFmode
&& in_n
== 2)
3977 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPI
];
3979 case BUILT_IN_NEARBYINTF
:
3980 if (VECTOR_UNIT_VSX_P (V4SFmode
)
3981 && flag_unsafe_math_optimizations
3982 && out_mode
== SFmode
&& out_n
== 4
3983 && in_mode
== SFmode
&& in_n
== 4)
3984 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPI
];
3987 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3988 && !flag_trapping_math
3989 && out_mode
== DFmode
&& out_n
== 2
3990 && in_mode
== DFmode
&& in_n
== 2)
3991 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIC
];
3993 case BUILT_IN_RINTF
:
3994 if (VECTOR_UNIT_VSX_P (V4SFmode
)
3995 && !flag_trapping_math
3996 && out_mode
== SFmode
&& out_n
== 4
3997 && in_mode
== SFmode
&& in_n
== 4)
3998 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIC
];
4005 else if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
4007 enum rs6000_builtins fn
4008 = (enum rs6000_builtins
)DECL_FUNCTION_CODE (fndecl
);
4011 case RS6000_BUILTIN_RSQRTF
:
4012 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
)
4013 && out_mode
== SFmode
&& out_n
== 4
4014 && in_mode
== SFmode
&& in_n
== 4)
4015 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRSQRTFP
];
4017 case RS6000_BUILTIN_RSQRT
:
4018 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4019 && out_mode
== DFmode
&& out_n
== 2
4020 && in_mode
== DFmode
&& in_n
== 2)
4021 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V2DF
];
4023 case RS6000_BUILTIN_RECIPF
:
4024 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode
)
4025 && out_mode
== SFmode
&& out_n
== 4
4026 && in_mode
== SFmode
&& in_n
== 4)
4027 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRECIPFP
];
4029 case RS6000_BUILTIN_RECIP
:
4030 if (VECTOR_UNIT_VSX_P (V2DFmode
)
4031 && out_mode
== DFmode
&& out_n
== 2
4032 && in_mode
== DFmode
&& in_n
== 2)
4033 return rs6000_builtin_decls
[VSX_BUILTIN_RECIP_V2DF
];
4040 /* Generate calls to libmass if appropriate. */
4041 if (rs6000_veclib_handler
)
4042 return rs6000_veclib_handler (fndecl
, type_out
, type_in
);
4048 /* Implement TARGET_HANDLE_OPTION. */
4051 rs6000_handle_option (size_t code
, const char *arg
, int value
)
4053 enum fpu_type_t fpu_type
= FPU_NONE
;
4059 target_flags
&= ~(MASK_POWER
| MASK_POWER2
4060 | MASK_MULTIPLE
| MASK_STRING
);
4061 target_flags_explicit
|= (MASK_POWER
| MASK_POWER2
4062 | MASK_MULTIPLE
| MASK_STRING
);
4064 case OPT_mno_powerpc
:
4065 target_flags
&= ~(MASK_POWERPC
| MASK_PPC_GPOPT
4066 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
4067 target_flags_explicit
|= (MASK_POWERPC
| MASK_PPC_GPOPT
4068 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
4071 target_flags
&= ~MASK_MINIMAL_TOC
;
4072 TARGET_NO_FP_IN_TOC
= 0;
4073 TARGET_NO_SUM_IN_TOC
= 0;
4074 target_flags_explicit
|= MASK_MINIMAL_TOC
;
4075 #ifdef TARGET_USES_SYSV4_OPT
4076 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4077 just the same as -mminimal-toc. */
4078 target_flags
|= MASK_MINIMAL_TOC
;
4079 target_flags_explicit
|= MASK_MINIMAL_TOC
;
4083 #ifdef TARGET_USES_SYSV4_OPT
4085 /* Make -mtoc behave like -mminimal-toc. */
4086 target_flags
|= MASK_MINIMAL_TOC
;
4087 target_flags_explicit
|= MASK_MINIMAL_TOC
;
4091 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4093 if (strcmp (arg
, "small") == 0)
4094 cmodel
= CMODEL_SMALL
;
4095 else if (strcmp (arg
, "medium") == 0)
4096 cmodel
= CMODEL_MEDIUM
;
4097 else if (strcmp (arg
, "large") == 0)
4098 cmodel
= CMODEL_LARGE
;
4101 error ("invalid option for -mcmodel: '%s'", arg
);
4104 rs6000_explicit_options
.cmodel
= true;
4107 #ifdef TARGET_USES_AIX64_OPT
4112 target_flags
|= MASK_POWERPC64
| MASK_POWERPC
;
4113 target_flags
|= ~target_flags_explicit
& MASK_PPC_GFXOPT
;
4114 target_flags_explicit
|= MASK_POWERPC64
| MASK_POWERPC
;
4117 #ifdef TARGET_USES_AIX64_OPT
4122 target_flags
&= ~MASK_POWERPC64
;
4123 target_flags_explicit
|= MASK_POWERPC64
;
4126 case OPT_minsert_sched_nops_
:
4127 rs6000_sched_insert_nops_str
= arg
;
4130 case OPT_mminimal_toc
:
4133 TARGET_NO_FP_IN_TOC
= 0;
4134 TARGET_NO_SUM_IN_TOC
= 0;
4141 target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
4142 target_flags_explicit
|= (MASK_MULTIPLE
| MASK_STRING
);
4149 target_flags
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
4150 target_flags_explicit
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
4154 case OPT_mpowerpc_gpopt
:
4155 case OPT_mpowerpc_gfxopt
:
4158 target_flags
|= MASK_POWERPC
;
4159 target_flags_explicit
|= MASK_POWERPC
;
4163 case OPT_maix_struct_return
:
4164 case OPT_msvr4_struct_return
:
4165 rs6000_explicit_options
.aix_struct_ret
= true;
4169 rs6000_explicit_options
.vrsave
= true;
4170 TARGET_ALTIVEC_VRSAVE
= value
;
4174 rs6000_explicit_options
.vrsave
= true;
4175 rs6000_parse_yes_no_option ("vrsave", arg
, &(TARGET_ALTIVEC_VRSAVE
));
4179 target_flags_explicit
|= MASK_ISEL
;
4181 rs6000_parse_yes_no_option ("isel", arg
, &isel
);
4183 target_flags
|= MASK_ISEL
;
4185 target_flags
&= ~MASK_ISEL
;
4189 rs6000_explicit_options
.spe
= true;
4194 rs6000_explicit_options
.spe
= true;
4195 rs6000_parse_yes_no_option ("spe", arg
, &(rs6000_spe
));
4199 rs6000_debug_name
= arg
;
4202 #ifdef TARGET_USES_SYSV4_OPT
4204 rs6000_abi_name
= arg
;
4208 rs6000_sdata_name
= arg
;
4211 case OPT_mtls_size_
:
4212 rs6000_tls_size_string
= arg
;
4215 case OPT_mrelocatable
:
4218 target_flags
|= MASK_MINIMAL_TOC
;
4219 target_flags_explicit
|= MASK_MINIMAL_TOC
;
4220 TARGET_NO_FP_IN_TOC
= 1;
4224 case OPT_mrelocatable_lib
:
4227 target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
4228 target_flags_explicit
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
4229 TARGET_NO_FP_IN_TOC
= 1;
4233 target_flags
&= ~MASK_RELOCATABLE
;
4234 target_flags_explicit
|= MASK_RELOCATABLE
;
4240 if (!strcmp (arg
, "altivec"))
4242 rs6000_explicit_options
.altivec_abi
= true;
4243 rs6000_altivec_abi
= 1;
4245 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4248 else if (! strcmp (arg
, "no-altivec"))
4250 rs6000_explicit_options
.altivec_abi
= true;
4251 rs6000_altivec_abi
= 0;
4253 else if (! strcmp (arg
, "spe"))
4255 rs6000_explicit_options
.spe_abi
= true;
4257 rs6000_altivec_abi
= 0;
4258 if (!TARGET_SPE_ABI
)
4259 error ("not configured for ABI: '%s'", arg
);
4261 else if (! strcmp (arg
, "no-spe"))
4263 rs6000_explicit_options
.spe_abi
= true;
4267 /* These are here for testing during development only, do not
4268 document in the manual please. */
4269 else if (! strcmp (arg
, "d64"))
4271 rs6000_darwin64_abi
= 1;
4272 warning (0, "Using darwin64 ABI");
4274 else if (! strcmp (arg
, "d32"))
4276 rs6000_darwin64_abi
= 0;
4277 warning (0, "Using old darwin ABI");
4280 else if (! strcmp (arg
, "ibmlongdouble"))
4282 rs6000_explicit_options
.ieee
= true;
4283 rs6000_ieeequad
= 0;
4284 warning (0, "Using IBM extended precision long double");
4286 else if (! strcmp (arg
, "ieeelongdouble"))
4288 rs6000_explicit_options
.ieee
= true;
4289 rs6000_ieeequad
= 1;
4290 warning (0, "Using IEEE extended precision long double");
4295 error ("unknown ABI specified: '%s'", arg
);
4301 rs6000_select
[1].string
= arg
;
4305 rs6000_select
[2].string
= arg
;
4308 case OPT_mtraceback_
:
4309 rs6000_traceback_name
= arg
;
4312 case OPT_mfloat_gprs_
:
4313 rs6000_explicit_options
.float_gprs
= true;
4314 if (! strcmp (arg
, "yes") || ! strcmp (arg
, "single"))
4315 rs6000_float_gprs
= 1;
4316 else if (! strcmp (arg
, "double"))
4317 rs6000_float_gprs
= 2;
4318 else if (! strcmp (arg
, "no"))
4319 rs6000_float_gprs
= 0;
4322 error ("invalid option for -mfloat-gprs: '%s'", arg
);
4327 case OPT_mlong_double_
:
4328 rs6000_explicit_options
.long_double
= true;
4329 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
4330 if (value
!= 64 && value
!= 128)
4332 error ("Unknown switch -mlong-double-%s", arg
);
4333 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
4337 rs6000_long_double_type_size
= value
;
4340 case OPT_msched_costly_dep_
:
4341 rs6000_sched_costly_dep_str
= arg
;
4345 rs6000_explicit_options
.alignment
= true;
4346 if (! strcmp (arg
, "power"))
4348 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4349 some C library functions, so warn about it. The flag may be
4350 useful for performance studies from time to time though, so
4351 don't disable it entirely. */
4352 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
4353 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4354 " it is incompatible with the installed C and C++ libraries");
4355 rs6000_alignment_flags
= MASK_ALIGN_POWER
;
4357 else if (! strcmp (arg
, "natural"))
4358 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
4361 error ("unknown -malign-XXXXX option specified: '%s'", arg
);
4366 case OPT_msingle_float
:
4367 if (!TARGET_SINGLE_FPU
)
4368 warning (0, "-msingle-float option equivalent to -mhard-float");
4369 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4370 rs6000_double_float
= 0;
4371 target_flags
&= ~MASK_SOFT_FLOAT
;
4372 target_flags_explicit
|= MASK_SOFT_FLOAT
;
4375 case OPT_mdouble_float
:
4376 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4377 rs6000_single_float
= 1;
4378 target_flags
&= ~MASK_SOFT_FLOAT
;
4379 target_flags_explicit
|= MASK_SOFT_FLOAT
;
4382 case OPT_msimple_fpu
:
4383 if (!TARGET_SINGLE_FPU
)
4384 warning (0, "-msimple-fpu option ignored");
4387 case OPT_mhard_float
:
4388 /* -mhard_float implies -msingle-float and -mdouble-float. */
4389 rs6000_single_float
= rs6000_double_float
= 1;
4392 case OPT_msoft_float
:
4393 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4394 rs6000_single_float
= rs6000_double_float
= 0;
4398 fpu_type
= rs6000_parse_fpu_option(arg
);
4399 if (fpu_type
!= FPU_NONE
)
4400 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4402 target_flags
&= ~MASK_SOFT_FLOAT
;
4403 target_flags_explicit
|= MASK_SOFT_FLOAT
;
4404 rs6000_xilinx_fpu
= 1;
4405 if (fpu_type
== FPU_SF_LITE
|| fpu_type
== FPU_SF_FULL
)
4406 rs6000_single_float
= 1;
4407 if (fpu_type
== FPU_DF_LITE
|| fpu_type
== FPU_DF_FULL
)
4408 rs6000_single_float
= rs6000_double_float
= 1;
4409 if (fpu_type
== FPU_SF_LITE
|| fpu_type
== FPU_DF_LITE
)
4410 rs6000_simple_fpu
= 1;
4414 /* -mfpu=none is equivalent to -msoft-float */
4415 target_flags
|= MASK_SOFT_FLOAT
;
4416 target_flags_explicit
|= MASK_SOFT_FLOAT
;
4417 rs6000_single_float
= rs6000_double_float
= 0;
4421 rs6000_recip_name
= (value
) ? "default" : "none";
4425 rs6000_recip_name
= arg
;
4431 /* Do anything needed at the start of the asm file. */
4434 rs6000_file_start (void)
4438 const char *start
= buffer
;
4439 struct rs6000_cpu_select
*ptr
;
4440 const char *default_cpu
= TARGET_CPU_DEFAULT
;
4441 FILE *file
= asm_out_file
;
4443 default_file_start ();
4445 #ifdef TARGET_BI_ARCH
4446 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
4450 if (flag_verbose_asm
)
4452 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
4453 rs6000_select
[0].string
= default_cpu
;
4455 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
4457 ptr
= &rs6000_select
[i
];
4458 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
4460 fprintf (file
, "%s %s%s", start
, ptr
->name
, ptr
->string
);
4465 if (PPC405_ERRATUM77
)
4467 fprintf (file
, "%s PPC405CR_ERRATUM77", start
);
4471 #ifdef USING_ELFOS_H
4472 switch (rs6000_sdata
)
4474 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
4475 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
4476 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
4477 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
4480 if (rs6000_sdata
&& g_switch_value
)
4482 fprintf (file
, "%s -G %d", start
,
4492 #ifdef HAVE_AS_GNU_ATTRIBUTE
4493 if (TARGET_32BIT
&& DEFAULT_ABI
== ABI_V4
)
4495 fprintf (file
, "\t.gnu_attribute 4, %d\n",
4496 ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
) ? 1
4497 : (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_SINGLE_FLOAT
) ? 3
4499 fprintf (file
, "\t.gnu_attribute 8, %d\n",
4500 (TARGET_ALTIVEC_ABI
? 2
4501 : TARGET_SPE_ABI
? 3
4503 fprintf (file
, "\t.gnu_attribute 12, %d\n",
4504 aix_struct_return
? 2 : 1);
4509 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
4511 switch_to_section (toc_section
);
4512 switch_to_section (text_section
);
4517 /* Return nonzero if this function is known to have a null epilogue. */
4520 direct_return (void)
4522 if (reload_completed
)
4524 rs6000_stack_t
*info
= rs6000_stack_info ();
4526 if (info
->first_gp_reg_save
== 32
4527 && info
->first_fp_reg_save
== 64
4528 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
4529 && ! info
->lr_save_p
4530 && ! info
->cr_save_p
4531 && info
->vrsave_mask
== 0
4539 /* Return the number of instructions it takes to form a constant in an
4540 integer register. */
4543 num_insns_constant_wide (HOST_WIDE_INT value
)
4545 /* signed constant loadable with {cal|addi} */
4546 if ((unsigned HOST_WIDE_INT
) (value
+ 0x8000) < 0x10000)
4549 /* constant loadable with {cau|addis} */
4550 else if ((value
& 0xffff) == 0
4551 && (value
>> 31 == -1 || value
>> 31 == 0))
4554 #if HOST_BITS_PER_WIDE_INT == 64
4555 else if (TARGET_POWERPC64
)
4557 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
4558 HOST_WIDE_INT high
= value
>> 31;
4560 if (high
== 0 || high
== -1)
4566 return num_insns_constant_wide (high
) + 1;
4568 return num_insns_constant_wide (low
) + 1;
4570 return (num_insns_constant_wide (high
)
4571 + num_insns_constant_wide (low
) + 1);
4580 num_insns_constant (rtx op
, enum machine_mode mode
)
4582 HOST_WIDE_INT low
, high
;
4584 switch (GET_CODE (op
))
4587 #if HOST_BITS_PER_WIDE_INT == 64
4588 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
4589 && mask64_operand (op
, mode
))
4593 return num_insns_constant_wide (INTVAL (op
));
4596 if (mode
== SFmode
|| mode
== SDmode
)
4601 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
4602 if (DECIMAL_FLOAT_MODE_P (mode
))
4603 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
4605 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
4606 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
4609 if (mode
== VOIDmode
|| mode
== DImode
)
4611 high
= CONST_DOUBLE_HIGH (op
);
4612 low
= CONST_DOUBLE_LOW (op
);
4619 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
4620 if (DECIMAL_FLOAT_MODE_P (mode
))
4621 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, l
);
4623 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
4624 high
= l
[WORDS_BIG_ENDIAN
== 0];
4625 low
= l
[WORDS_BIG_ENDIAN
!= 0];
4629 return (num_insns_constant_wide (low
)
4630 + num_insns_constant_wide (high
));
4633 if ((high
== 0 && low
>= 0)
4634 || (high
== -1 && low
< 0))
4635 return num_insns_constant_wide (low
);
4637 else if (mask64_operand (op
, mode
))
4641 return num_insns_constant_wide (high
) + 1;
4644 return (num_insns_constant_wide (high
)
4645 + num_insns_constant_wide (low
) + 1);
4653 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4654 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4655 corresponding element of the vector, but for V4SFmode and V2SFmode,
4656 the corresponding "float" is interpreted as an SImode integer. */
4659 const_vector_elt_as_int (rtx op
, unsigned int elt
)
4661 rtx tmp
= CONST_VECTOR_ELT (op
, elt
);
4662 if (GET_MODE (op
) == V4SFmode
4663 || GET_MODE (op
) == V2SFmode
)
4664 tmp
= gen_lowpart (SImode
, tmp
);
4665 return INTVAL (tmp
);
4668 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4669 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4670 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4671 all items are set to the same value and contain COPIES replicas of the
4672 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4673 operand and the others are set to the value of the operand's msb. */
4676 vspltis_constant (rtx op
, unsigned step
, unsigned copies
)
4678 enum machine_mode mode
= GET_MODE (op
);
4679 enum machine_mode inner
= GET_MODE_INNER (mode
);
4682 unsigned nunits
= GET_MODE_NUNITS (mode
);
4683 unsigned bitsize
= GET_MODE_BITSIZE (inner
);
4684 unsigned mask
= GET_MODE_MASK (inner
);
4686 HOST_WIDE_INT val
= const_vector_elt_as_int (op
, nunits
- 1);
4687 HOST_WIDE_INT splat_val
= val
;
4688 HOST_WIDE_INT msb_val
= val
> 0 ? 0 : -1;
4690 /* Construct the value to be splatted, if possible. If not, return 0. */
4691 for (i
= 2; i
<= copies
; i
*= 2)
4693 HOST_WIDE_INT small_val
;
4695 small_val
= splat_val
>> bitsize
;
4697 if (splat_val
!= ((small_val
<< bitsize
) | (small_val
& mask
)))
4699 splat_val
= small_val
;
4702 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4703 if (EASY_VECTOR_15 (splat_val
))
4706 /* Also check if we can splat, and then add the result to itself. Do so if
4707 the value is positive, of if the splat instruction is using OP's mode;
4708 for splat_val < 0, the splat and the add should use the same mode. */
4709 else if (EASY_VECTOR_15_ADD_SELF (splat_val
)
4710 && (splat_val
>= 0 || (step
== 1 && copies
== 1)))
4713 /* Also check if are loading up the most significant bit which can be done by
4714 loading up -1 and shifting the value left by -1. */
4715 else if (EASY_VECTOR_MSB (splat_val
, inner
))
4721 /* Check if VAL is present in every STEP-th element, and the
4722 other elements are filled with its most significant bit. */
4723 for (i
= 0; i
< nunits
- 1; ++i
)
4725 HOST_WIDE_INT desired_val
;
4726 if (((i
+ 1) & (step
- 1)) == 0)
4729 desired_val
= msb_val
;
4731 if (desired_val
!= const_vector_elt_as_int (op
, i
))
4739 /* Return true if OP is of the given MODE and can be synthesized
4740 with a vspltisb, vspltish or vspltisw. */
4743 easy_altivec_constant (rtx op
, enum machine_mode mode
)
4745 unsigned step
, copies
;
4747 if (mode
== VOIDmode
)
4748 mode
= GET_MODE (op
);
4749 else if (mode
!= GET_MODE (op
))
4752 /* Start with a vspltisw. */
4753 step
= GET_MODE_NUNITS (mode
) / 4;
4756 if (vspltis_constant (op
, step
, copies
))
4759 /* Then try with a vspltish. */
4765 if (vspltis_constant (op
, step
, copies
))
4768 /* And finally a vspltisb. */
4774 if (vspltis_constant (op
, step
, copies
))
4780 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4781 result is OP. Abort if it is not possible. */
4784 gen_easy_altivec_constant (rtx op
)
4786 enum machine_mode mode
= GET_MODE (op
);
4787 int nunits
= GET_MODE_NUNITS (mode
);
4788 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
4789 unsigned step
= nunits
/ 4;
4790 unsigned copies
= 1;
4792 /* Start with a vspltisw. */
4793 if (vspltis_constant (op
, step
, copies
))
4794 return gen_rtx_VEC_DUPLICATE (V4SImode
, gen_lowpart (SImode
, last
));
4796 /* Then try with a vspltish. */
4802 if (vspltis_constant (op
, step
, copies
))
4803 return gen_rtx_VEC_DUPLICATE (V8HImode
, gen_lowpart (HImode
, last
));
4805 /* And finally a vspltisb. */
4811 if (vspltis_constant (op
, step
, copies
))
4812 return gen_rtx_VEC_DUPLICATE (V16QImode
, gen_lowpart (QImode
, last
));
4818 output_vec_const_move (rtx
*operands
)
4821 enum machine_mode mode
;
4826 mode
= GET_MODE (dest
);
4828 if (TARGET_VSX
&& zero_constant (vec
, mode
))
4829 return "xxlxor %x0,%x0,%x0";
4834 if (zero_constant (vec
, mode
))
4835 return "vxor %0,%0,%0";
4837 splat_vec
= gen_easy_altivec_constant (vec
);
4838 gcc_assert (GET_CODE (splat_vec
) == VEC_DUPLICATE
);
4839 operands
[1] = XEXP (splat_vec
, 0);
4840 if (!EASY_VECTOR_15 (INTVAL (operands
[1])))
4843 switch (GET_MODE (splat_vec
))
4846 return "vspltisw %0,%1";
4849 return "vspltish %0,%1";
4852 return "vspltisb %0,%1";
4859 gcc_assert (TARGET_SPE
);
4861 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4862 pattern of V1DI, V4HI, and V2SF.
4864 FIXME: We should probably return # and add post reload
4865 splitters for these, but this way is so easy ;-). */
4866 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
4867 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
4868 operands
[1] = CONST_VECTOR_ELT (vec
, 0);
4869 operands
[2] = CONST_VECTOR_ELT (vec
, 1);
4871 return "li %0,%1\n\tevmergelo %0,%0,%0";
4873 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4876 /* Initialize TARGET of vector PAIRED to VALS. */
4879 paired_expand_vector_init (rtx target
, rtx vals
)
4881 enum machine_mode mode
= GET_MODE (target
);
4882 int n_elts
= GET_MODE_NUNITS (mode
);
4884 rtx x
, new_rtx
, tmp
, constant_op
, op1
, op2
;
4887 for (i
= 0; i
< n_elts
; ++i
)
4889 x
= XVECEXP (vals
, 0, i
);
4890 if (!CONSTANT_P (x
))
4895 /* Load from constant pool. */
4896 emit_move_insn (target
, gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0)));
4902 /* The vector is initialized only with non-constants. */
4903 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, XVECEXP (vals
, 0, 0),
4904 XVECEXP (vals
, 0, 1));
4906 emit_move_insn (target
, new_rtx
);
4910 /* One field is non-constant and the other one is a constant. Load the
4911 constant from the constant pool and use ps_merge instruction to
4912 construct the whole vector. */
4913 op1
= XVECEXP (vals
, 0, 0);
4914 op2
= XVECEXP (vals
, 0, 1);
4916 constant_op
= (CONSTANT_P (op1
)) ? op1
: op2
;
4918 tmp
= gen_reg_rtx (GET_MODE (constant_op
));
4919 emit_move_insn (tmp
, constant_op
);
4921 if (CONSTANT_P (op1
))
4922 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, tmp
, op2
);
4924 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, op1
, tmp
);
4926 emit_move_insn (target
, new_rtx
);
4930 paired_expand_vector_move (rtx operands
[])
4932 rtx op0
= operands
[0], op1
= operands
[1];
4934 emit_move_insn (op0
, op1
);
4937 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4938 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4939 operands for the relation operation COND. This is a recursive
4943 paired_emit_vector_compare (enum rtx_code rcode
,
4944 rtx dest
, rtx op0
, rtx op1
,
4945 rtx cc_op0
, rtx cc_op1
)
4947 rtx tmp
= gen_reg_rtx (V2SFmode
);
4950 gcc_assert (TARGET_PAIRED_FLOAT
);
4951 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
4957 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4961 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
4962 emit_insn (gen_selv2sf4 (dest
, tmp
, op0
, op1
, CONST0_RTX (SFmode
)));
4966 paired_emit_vector_compare (GE
, dest
, op0
, op1
, cc_op1
, cc_op0
);
4969 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4972 tmp1
= gen_reg_rtx (V2SFmode
);
4973 max
= gen_reg_rtx (V2SFmode
);
4974 min
= gen_reg_rtx (V2SFmode
);
4975 gen_reg_rtx (V2SFmode
);
4977 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
4978 emit_insn (gen_selv2sf4
4979 (max
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
4980 emit_insn (gen_subv2sf3 (tmp
, cc_op1
, cc_op0
));
4981 emit_insn (gen_selv2sf4
4982 (min
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
4983 emit_insn (gen_subv2sf3 (tmp1
, min
, max
));
4984 emit_insn (gen_selv2sf4 (dest
, tmp1
, op0
, op1
, CONST0_RTX (SFmode
)));
4987 paired_emit_vector_compare (EQ
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4990 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4993 paired_emit_vector_compare (LT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4996 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4999 paired_emit_vector_compare (GT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
5008 /* Emit vector conditional expression.
5009 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5010 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5013 paired_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
5014 rtx cond
, rtx cc_op0
, rtx cc_op1
)
5016 enum rtx_code rcode
= GET_CODE (cond
);
5018 if (!TARGET_PAIRED_FLOAT
)
5021 paired_emit_vector_compare (rcode
, dest
, op1
, op2
, cc_op0
, cc_op1
);
5026 /* Initialize vector TARGET to VALS. */
5029 rs6000_expand_vector_init (rtx target
, rtx vals
)
5031 enum machine_mode mode
= GET_MODE (target
);
5032 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
5033 int n_elts
= GET_MODE_NUNITS (mode
);
5034 int n_var
= 0, one_var
= -1;
5035 bool all_same
= true, all_const_zero
= true;
5039 for (i
= 0; i
< n_elts
; ++i
)
5041 x
= XVECEXP (vals
, 0, i
);
5042 if (!CONSTANT_P (x
))
5043 ++n_var
, one_var
= i
;
5044 else if (x
!= CONST0_RTX (inner_mode
))
5045 all_const_zero
= false;
5047 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
5053 rtx const_vec
= gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0));
5054 bool int_vector_p
= (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
);
5055 if ((int_vector_p
|| TARGET_VSX
) && all_const_zero
)
5057 /* Zero register. */
5058 emit_insn (gen_rtx_SET (VOIDmode
, target
,
5059 gen_rtx_XOR (mode
, target
, target
)));
5062 else if (int_vector_p
&& easy_vector_constant (const_vec
, mode
))
5064 /* Splat immediate. */
5065 emit_insn (gen_rtx_SET (VOIDmode
, target
, const_vec
));
5070 /* Load from constant pool. */
5071 emit_move_insn (target
, const_vec
);
5076 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5077 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
5081 rtx element
= XVECEXP (vals
, 0, 0);
5082 if (mode
== V2DFmode
)
5083 emit_insn (gen_vsx_splat_v2df (target
, element
));
5085 emit_insn (gen_vsx_splat_v2di (target
, element
));
5089 rtx op0
= copy_to_reg (XVECEXP (vals
, 0, 0));
5090 rtx op1
= copy_to_reg (XVECEXP (vals
, 0, 1));
5091 if (mode
== V2DFmode
)
5092 emit_insn (gen_vsx_concat_v2df (target
, op0
, op1
));
5094 emit_insn (gen_vsx_concat_v2di (target
, op0
, op1
));
5099 /* With single precision floating point on VSX, know that internally single
5100 precision is actually represented as a double, and either make 2 V2DF
5101 vectors, and convert these vectors to single precision, or do one
5102 conversion, and splat the result to the other elements. */
5103 if (mode
== V4SFmode
&& VECTOR_MEM_VSX_P (mode
))
5107 rtx freg
= gen_reg_rtx (V4SFmode
);
5108 rtx sreg
= copy_to_reg (XVECEXP (vals
, 0, 0));
5110 emit_insn (gen_vsx_xscvdpsp_scalar (freg
, sreg
));
5111 emit_insn (gen_vsx_xxspltw_v4sf (target
, freg
, const0_rtx
));
5115 rtx dbl_even
= gen_reg_rtx (V2DFmode
);
5116 rtx dbl_odd
= gen_reg_rtx (V2DFmode
);
5117 rtx flt_even
= gen_reg_rtx (V4SFmode
);
5118 rtx flt_odd
= gen_reg_rtx (V4SFmode
);
5120 emit_insn (gen_vsx_concat_v2sf (dbl_even
,
5121 copy_to_reg (XVECEXP (vals
, 0, 0)),
5122 copy_to_reg (XVECEXP (vals
, 0, 1))));
5123 emit_insn (gen_vsx_concat_v2sf (dbl_odd
,
5124 copy_to_reg (XVECEXP (vals
, 0, 2)),
5125 copy_to_reg (XVECEXP (vals
, 0, 3))));
5126 emit_insn (gen_vsx_xvcvdpsp (flt_even
, dbl_even
));
5127 emit_insn (gen_vsx_xvcvdpsp (flt_odd
, dbl_odd
));
5128 emit_insn (gen_vec_extract_evenv4sf (target
, flt_even
, flt_odd
));
5133 /* Store value to stack temp. Load vector element. Splat. However, splat
5134 of 64-bit items is not supported on Altivec. */
5135 if (all_same
&& GET_MODE_SIZE (mode
) <= 4)
5137 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
5138 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0),
5139 XVECEXP (vals
, 0, 0));
5140 x
= gen_rtx_UNSPEC (VOIDmode
,
5141 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
5142 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
5144 gen_rtx_SET (VOIDmode
,
5147 x
= gen_rtx_VEC_SELECT (inner_mode
, target
,
5148 gen_rtx_PARALLEL (VOIDmode
,
5149 gen_rtvec (1, const0_rtx
)));
5150 emit_insn (gen_rtx_SET (VOIDmode
, target
,
5151 gen_rtx_VEC_DUPLICATE (mode
, x
)));
5155 /* One field is non-constant. Load constant then overwrite
5159 rtx copy
= copy_rtx (vals
);
5161 /* Load constant part of vector, substitute neighboring value for
5163 XVECEXP (copy
, 0, one_var
) = XVECEXP (vals
, 0, (one_var
+ 1) % n_elts
);
5164 rs6000_expand_vector_init (target
, copy
);
5166 /* Insert variable. */
5167 rs6000_expand_vector_set (target
, XVECEXP (vals
, 0, one_var
), one_var
);
5171 /* Construct the vector in memory one field at a time
5172 and load the whole vector. */
5173 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
5174 for (i
= 0; i
< n_elts
; i
++)
5175 emit_move_insn (adjust_address_nv (mem
, inner_mode
,
5176 i
* GET_MODE_SIZE (inner_mode
)),
5177 XVECEXP (vals
, 0, i
));
5178 emit_move_insn (target
, mem
);
5181 /* Set field ELT of TARGET to VAL. */
5184 rs6000_expand_vector_set (rtx target
, rtx val
, int elt
)
5186 enum machine_mode mode
= GET_MODE (target
);
5187 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
5188 rtx reg
= gen_reg_rtx (mode
);
5190 int width
= GET_MODE_SIZE (inner_mode
);
5193 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
5195 rtx (*set_func
) (rtx
, rtx
, rtx
, rtx
)
5196 = ((mode
== V2DFmode
) ? gen_vsx_set_v2df
: gen_vsx_set_v2di
);
5197 emit_insn (set_func (target
, target
, val
, GEN_INT (elt
)));
5201 /* Load single variable value. */
5202 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
5203 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0), val
);
5204 x
= gen_rtx_UNSPEC (VOIDmode
,
5205 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
5206 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
5208 gen_rtx_SET (VOIDmode
,
5212 /* Linear sequence. */
5213 mask
= gen_rtx_PARALLEL (V16QImode
, rtvec_alloc (16));
5214 for (i
= 0; i
< 16; ++i
)
5215 XVECEXP (mask
, 0, i
) = GEN_INT (i
);
5217 /* Set permute mask to insert element into target. */
5218 for (i
= 0; i
< width
; ++i
)
5219 XVECEXP (mask
, 0, elt
*width
+ i
)
5220 = GEN_INT (i
+ 0x10);
5221 x
= gen_rtx_CONST_VECTOR (V16QImode
, XVEC (mask
, 0));
5222 x
= gen_rtx_UNSPEC (mode
,
5223 gen_rtvec (3, target
, reg
,
5224 force_reg (V16QImode
, x
)),
5226 emit_insn (gen_rtx_SET (VOIDmode
, target
, x
));
5229 /* Extract field ELT from VEC into TARGET. */
5232 rs6000_expand_vector_extract (rtx target
, rtx vec
, int elt
)
5234 enum machine_mode mode
= GET_MODE (vec
);
5235 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
5238 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
5240 rtx (*extract_func
) (rtx
, rtx
, rtx
)
5241 = ((mode
== V2DFmode
) ? gen_vsx_extract_v2df
: gen_vsx_extract_v2di
);
5242 emit_insn (extract_func (target
, vec
, GEN_INT (elt
)));
5246 /* Allocate mode-sized buffer. */
5247 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
5249 /* Add offset to field within buffer matching vector element. */
5250 mem
= adjust_address_nv (mem
, mode
, elt
* GET_MODE_SIZE (inner_mode
));
5252 /* Store single field into mode-sized buffer. */
5253 x
= gen_rtx_UNSPEC (VOIDmode
,
5254 gen_rtvec (1, const0_rtx
), UNSPEC_STVE
);
5255 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
5257 gen_rtx_SET (VOIDmode
,
5260 emit_move_insn (target
, adjust_address_nv (mem
, inner_mode
, 0));
5263 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5264 implement ANDing by the mask IN. */
5266 build_mask64_2_operands (rtx in
, rtx
*out
)
5268 #if HOST_BITS_PER_WIDE_INT >= 64
5269 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
5272 gcc_assert (GET_CODE (in
) == CONST_INT
);
5277 /* Assume c initially something like 0x00fff000000fffff. The idea
5278 is to rotate the word so that the middle ^^^^^^ group of zeros
5279 is at the MS end and can be cleared with an rldicl mask. We then
5280 rotate back and clear off the MS ^^ group of zeros with a
5282 c
= ~c
; /* c == 0xff000ffffff00000 */
5283 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
5284 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
5285 c
= ~c
; /* c == 0x00fff000000fffff */
5286 c
&= -lsb
; /* c == 0x00fff00000000000 */
5287 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
5288 c
= ~c
; /* c == 0xff000fffffffffff */
5289 c
&= -lsb
; /* c == 0xff00000000000000 */
5291 while ((lsb
>>= 1) != 0)
5292 shift
++; /* shift == 44 on exit from loop */
5293 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
5294 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
5295 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
5299 /* Assume c initially something like 0xff000f0000000000. The idea
5300 is to rotate the word so that the ^^^ middle group of zeros
5301 is at the LS end and can be cleared with an rldicr mask. We then
5302 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5304 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
5305 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
5306 c
= ~c
; /* c == 0x00fff0ffffffffff */
5307 c
&= -lsb
; /* c == 0x00fff00000000000 */
5308 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
5309 c
= ~c
; /* c == 0xff000fffffffffff */
5310 c
&= -lsb
; /* c == 0xff00000000000000 */
5312 while ((lsb
>>= 1) != 0)
5313 shift
++; /* shift == 44 on exit from loop */
5314 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
5315 m1
>>= shift
; /* m1 == 0x0000000000000fff */
5316 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
5319 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5320 masks will be all 1's. We are guaranteed more than one transition. */
5321 out
[0] = GEN_INT (64 - shift
);
5322 out
[1] = GEN_INT (m1
);
5323 out
[2] = GEN_INT (shift
);
5324 out
[3] = GEN_INT (m2
);
5332 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5335 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
5337 if (TARGET_E500_DOUBLE
)
5339 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5340 subreg:TI and reg:TF. Decimal float modes are like integer
5341 modes (only low part of each register used) for this
5343 if (GET_CODE (op
) == SUBREG
5344 && (mode
== SImode
|| mode
== DImode
|| mode
== TImode
5345 || mode
== DDmode
|| mode
== TDmode
)
5346 && REG_P (SUBREG_REG (op
))
5347 && (GET_MODE (SUBREG_REG (op
)) == DFmode
5348 || GET_MODE (SUBREG_REG (op
)) == TFmode
))
5351 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5353 if (GET_CODE (op
) == SUBREG
5354 && (mode
== DFmode
|| mode
== TFmode
)
5355 && REG_P (SUBREG_REG (op
))
5356 && (GET_MODE (SUBREG_REG (op
)) == DImode
5357 || GET_MODE (SUBREG_REG (op
)) == TImode
5358 || GET_MODE (SUBREG_REG (op
)) == DDmode
5359 || GET_MODE (SUBREG_REG (op
)) == TDmode
))
5364 && GET_CODE (op
) == SUBREG
5366 && REG_P (SUBREG_REG (op
))
5367 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op
))))
5373 /* AIX increases natural record alignment to doubleword if the first
5374 field is an FP double while the FP fields remain word aligned. */
5377 rs6000_special_round_type_align (tree type
, unsigned int computed
,
5378 unsigned int specified
)
5380 unsigned int align
= MAX (computed
, specified
);
5381 tree field
= TYPE_FIELDS (type
);
5383 /* Skip all non field decls */
5384 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
5385 field
= DECL_CHAIN (field
);
5387 if (field
!= NULL
&& field
!= type
)
5389 type
= TREE_TYPE (field
);
5390 while (TREE_CODE (type
) == ARRAY_TYPE
)
5391 type
= TREE_TYPE (type
);
5393 if (type
!= error_mark_node
&& TYPE_MODE (type
) == DFmode
)
5394 align
= MAX (align
, 64);
5400 /* Darwin increases record alignment to the natural alignment of
5404 darwin_rs6000_special_round_type_align (tree type
, unsigned int computed
,
5405 unsigned int specified
)
5407 unsigned int align
= MAX (computed
, specified
);
5409 if (TYPE_PACKED (type
))
5412 /* Find the first field, looking down into aggregates. */
5414 tree field
= TYPE_FIELDS (type
);
5415 /* Skip all non field decls */
5416 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
5417 field
= DECL_CHAIN (field
);
5420 /* A packed field does not contribute any extra alignment. */
5421 if (DECL_PACKED (field
))
5423 type
= TREE_TYPE (field
);
5424 while (TREE_CODE (type
) == ARRAY_TYPE
)
5425 type
= TREE_TYPE (type
);
5426 } while (AGGREGATE_TYPE_P (type
));
5428 if (! AGGREGATE_TYPE_P (type
) && type
!= error_mark_node
)
5429 align
= MAX (align
, TYPE_ALIGN (type
));
5434 /* Return 1 for an operand in small memory on V.4/eabi. */
5437 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
5438 enum machine_mode mode ATTRIBUTE_UNUSED
)
5443 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
5446 if (DEFAULT_ABI
!= ABI_V4
)
5449 /* Vector and float memory instructions have a limited offset on the
5450 SPE, so using a vector or float variable directly as an operand is
5453 && (SPE_VECTOR_MODE (mode
) || FLOAT_MODE_P (mode
)))
5456 if (GET_CODE (op
) == SYMBOL_REF
)
5459 else if (GET_CODE (op
) != CONST
5460 || GET_CODE (XEXP (op
, 0)) != PLUS
5461 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
5462 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
5467 rtx sum
= XEXP (op
, 0);
5468 HOST_WIDE_INT summand
;
5470 /* We have to be careful here, because it is the referenced address
5471 that must be 32k from _SDA_BASE_, not just the symbol. */
5472 summand
= INTVAL (XEXP (sum
, 1));
5473 if (summand
< 0 || summand
> g_switch_value
)
5476 sym_ref
= XEXP (sum
, 0);
5479 return SYMBOL_REF_SMALL_P (sym_ref
);
5485 /* Return true if either operand is a general purpose register. */
5488 gpr_or_gpr_p (rtx op0
, rtx op1
)
5490 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
5491 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
5495 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5498 reg_offset_addressing_ok_p (enum machine_mode mode
)
5508 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5509 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
))
5517 /* Paired vector modes. Only reg+reg addressing is valid. */
5518 if (TARGET_PAIRED_FLOAT
)
5530 virtual_stack_registers_memory_p (rtx op
)
5534 if (GET_CODE (op
) == REG
)
5535 regnum
= REGNO (op
);
5537 else if (GET_CODE (op
) == PLUS
5538 && GET_CODE (XEXP (op
, 0)) == REG
5539 && GET_CODE (XEXP (op
, 1)) == CONST_INT
)
5540 regnum
= REGNO (XEXP (op
, 0));
5545 return (regnum
>= FIRST_VIRTUAL_REGISTER
5546 && regnum
<= LAST_VIRTUAL_POINTER_REGISTER
);
5550 constant_pool_expr_p (rtx op
)
5554 split_const (op
, &base
, &offset
);
5555 return (GET_CODE (base
) == SYMBOL_REF
5556 && CONSTANT_POOL_ADDRESS_P (base
)
5557 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base
), Pmode
));
5560 static rtx tocrel_base
, tocrel_offset
;
5563 toc_relative_expr_p (rtx op
)
5565 if (GET_CODE (op
) != CONST
)
5568 split_const (op
, &tocrel_base
, &tocrel_offset
);
5569 return (GET_CODE (tocrel_base
) == UNSPEC
5570 && XINT (tocrel_base
, 1) == UNSPEC_TOCREL
);
5574 legitimate_constant_pool_address_p (const_rtx x
, bool strict
)
5577 && (GET_CODE (x
) == PLUS
|| GET_CODE (x
) == LO_SUM
)
5578 && GET_CODE (XEXP (x
, 0)) == REG
5579 && (REGNO (XEXP (x
, 0)) == TOC_REGISTER
5580 || ((TARGET_MINIMAL_TOC
5581 || TARGET_CMODEL
!= CMODEL_SMALL
)
5582 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
)))
5583 && toc_relative_expr_p (XEXP (x
, 1)));
5587 legitimate_small_data_p (enum machine_mode mode
, rtx x
)
5589 return (DEFAULT_ABI
== ABI_V4
5590 && !flag_pic
&& !TARGET_TOC
5591 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
5592 && small_data_operand (x
, mode
));
5595 /* SPE offset addressing is limited to 5-bits worth of double words. */
5596 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5599 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
5601 unsigned HOST_WIDE_INT offset
, extra
;
5603 if (GET_CODE (x
) != PLUS
)
5605 if (GET_CODE (XEXP (x
, 0)) != REG
)
5607 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
5609 if (!reg_offset_addressing_ok_p (mode
))
5610 return virtual_stack_registers_memory_p (x
);
5611 if (legitimate_constant_pool_address_p (x
, strict
))
5613 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
5616 offset
= INTVAL (XEXP (x
, 1));
5624 /* SPE vector modes. */
5625 return SPE_CONST_OFFSET_OK (offset
);
5628 if (TARGET_E500_DOUBLE
)
5629 return SPE_CONST_OFFSET_OK (offset
);
5631 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5633 if (VECTOR_MEM_VSX_P (DFmode
))
5638 /* On e500v2, we may have:
5640 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5642 Which gets addressed with evldd instructions. */
5643 if (TARGET_E500_DOUBLE
)
5644 return SPE_CONST_OFFSET_OK (offset
);
5646 if (mode
== DFmode
|| mode
== DDmode
|| !TARGET_POWERPC64
)
5648 else if (offset
& 3)
5653 if (TARGET_E500_DOUBLE
)
5654 return (SPE_CONST_OFFSET_OK (offset
)
5655 && SPE_CONST_OFFSET_OK (offset
+ 8));
5659 if (mode
== TFmode
|| mode
== TDmode
|| !TARGET_POWERPC64
)
5661 else if (offset
& 3)
5672 return (offset
< 0x10000) && (offset
+ extra
< 0x10000);
5676 legitimate_indexed_address_p (rtx x
, int strict
)
5680 if (GET_CODE (x
) != PLUS
)
5686 /* Recognize the rtl generated by reload which we know will later be
5687 replaced with proper base and index regs. */
5689 && reload_in_progress
5690 && (REG_P (op0
) || GET_CODE (op0
) == PLUS
)
5694 return (REG_P (op0
) && REG_P (op1
)
5695 && ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
5696 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
5697 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
5698 && INT_REG_OK_FOR_INDEX_P (op0
, strict
))));
5702 avoiding_indexed_address_p (enum machine_mode mode
)
5704 /* Avoid indexed addressing for modes that have non-indexed
5705 load/store instruction forms. */
5706 return (TARGET_AVOID_XFORM
&& VECTOR_MEM_NONE_P (mode
));
5710 legitimate_indirect_address_p (rtx x
, int strict
)
5712 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
5716 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
5718 if (!TARGET_MACHO
|| !flag_pic
5719 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
5723 if (GET_CODE (x
) != LO_SUM
)
5725 if (GET_CODE (XEXP (x
, 0)) != REG
)
5727 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
5731 return CONSTANT_P (x
);
5735 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
5737 if (GET_CODE (x
) != LO_SUM
)
5739 if (GET_CODE (XEXP (x
, 0)) != REG
)
5741 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
5743 /* Restrict addressing for DI because of our SUBREG hackery. */
5744 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5745 || mode
== DDmode
|| mode
== TDmode
5750 if (TARGET_ELF
|| TARGET_MACHO
)
5752 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
5756 if (GET_MODE_NUNITS (mode
) != 1)
5758 if (GET_MODE_BITSIZE (mode
) > 64
5759 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
5760 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
5761 && (mode
== DFmode
|| mode
== DDmode
))))
5764 return CONSTANT_P (x
);
5771 /* Try machine-dependent ways of modifying an illegitimate address
5772 to be legitimate. If we find one, return the new, valid address.
5773 This is used from only one place: `memory_address' in explow.c.
5775 OLDX is the address as it was before break_out_memory_refs was
5776 called. In some cases it is useful to look at this to decide what
5779 It is always safe for this function to do nothing. It exists to
5780 recognize opportunities to optimize the output.
5782 On RS/6000, first check for the sum of a register with a constant
5783 integer that is out of range. If so, generate code to add the
5784 constant with the low-order 16 bits masked to the register and force
5785 this result into another register (this can be done with `cau').
5786 Then generate an address of REG+(CONST&0xffff), allowing for the
5787 possibility of bit 16 being a one.
5789 Then check for the sum of a register and something not constant, try to
5790 load the other things into a register and return the sum. */
5793 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
5794 enum machine_mode mode
)
5796 unsigned int extra
= 0;
5798 if (!reg_offset_addressing_ok_p (mode
))
5800 if (virtual_stack_registers_memory_p (x
))
5803 /* In theory we should not be seeing addresses of the form reg+0,
5804 but just in case it is generated, optimize it away. */
5805 if (GET_CODE (x
) == PLUS
&& XEXP (x
, 1) == const0_rtx
)
5806 return force_reg (Pmode
, XEXP (x
, 0));
5808 /* Make sure both operands are registers. */
5809 else if (GET_CODE (x
) == PLUS
)
5810 return gen_rtx_PLUS (Pmode
,
5811 force_reg (Pmode
, XEXP (x
, 0)),
5812 force_reg (Pmode
, XEXP (x
, 1)));
5814 return force_reg (Pmode
, x
);
5816 if (GET_CODE (x
) == SYMBOL_REF
)
5818 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
5820 return rs6000_legitimize_tls_address (x
, model
);
5830 if (!TARGET_POWERPC64
)
5838 extra
= TARGET_POWERPC64
? 8 : 12;
5844 if (GET_CODE (x
) == PLUS
5845 && GET_CODE (XEXP (x
, 0)) == REG
5846 && GET_CODE (XEXP (x
, 1)) == CONST_INT
5847 && ((unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000)
5849 && !((TARGET_POWERPC64
5850 && (mode
== DImode
|| mode
== TImode
)
5851 && (INTVAL (XEXP (x
, 1)) & 3) != 0)
5852 || SPE_VECTOR_MODE (mode
)
5853 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5854 || mode
== DImode
|| mode
== DDmode
5855 || mode
== TDmode
))))
5857 HOST_WIDE_INT high_int
, low_int
;
5859 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5860 if (low_int
>= 0x8000 - extra
)
5862 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
5863 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
5864 GEN_INT (high_int
)), 0);
5865 return plus_constant (sum
, low_int
);
5867 else if (GET_CODE (x
) == PLUS
5868 && GET_CODE (XEXP (x
, 0)) == REG
5869 && GET_CODE (XEXP (x
, 1)) != CONST_INT
5870 && GET_MODE_NUNITS (mode
) == 1
5871 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
5873 || ((mode
!= DImode
&& mode
!= DFmode
&& mode
!= DDmode
)
5874 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
)))
5875 && (TARGET_POWERPC64
|| mode
!= DImode
)
5876 && !avoiding_indexed_address_p (mode
)
5881 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
5882 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
5884 else if (SPE_VECTOR_MODE (mode
)
5885 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5886 || mode
== DDmode
|| mode
== TDmode
5887 || mode
== DImode
)))
5891 /* We accept [reg + reg] and [reg + OFFSET]. */
5893 if (GET_CODE (x
) == PLUS
)
5895 rtx op1
= XEXP (x
, 0);
5896 rtx op2
= XEXP (x
, 1);
5899 op1
= force_reg (Pmode
, op1
);
5901 if (GET_CODE (op2
) != REG
5902 && (GET_CODE (op2
) != CONST_INT
5903 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))
5904 || (GET_MODE_SIZE (mode
) > 8
5905 && !SPE_CONST_OFFSET_OK (INTVAL (op2
) + 8))))
5906 op2
= force_reg (Pmode
, op2
);
5908 /* We can't always do [reg + reg] for these, because [reg +
5909 reg + offset] is not a legitimate addressing mode. */
5910 y
= gen_rtx_PLUS (Pmode
, op1
, op2
);
5912 if ((GET_MODE_SIZE (mode
) > 8 || mode
== DDmode
) && REG_P (op2
))
5913 return force_reg (Pmode
, y
);
5918 return force_reg (Pmode
, x
);
5924 && GET_CODE (x
) != CONST_INT
5925 && GET_CODE (x
) != CONST_DOUBLE
5927 && GET_MODE_NUNITS (mode
) == 1
5928 && (GET_MODE_BITSIZE (mode
) <= 32
5929 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
5930 && (mode
== DFmode
|| mode
== DDmode
))))
5932 rtx reg
= gen_reg_rtx (Pmode
);
5933 emit_insn (gen_elf_high (reg
, x
));
5934 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
5936 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
5939 && ! MACHO_DYNAMIC_NO_PIC_P
5941 && GET_CODE (x
) != CONST_INT
5942 && GET_CODE (x
) != CONST_DOUBLE
5944 && GET_MODE_NUNITS (mode
) == 1
5945 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
5946 || (mode
!= DFmode
&& mode
!= DDmode
))
5950 rtx reg
= gen_reg_rtx (Pmode
);
5951 emit_insn (gen_macho_high (reg
, x
));
5952 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
5955 && GET_CODE (x
) == SYMBOL_REF
5956 && constant_pool_expr_p (x
)
5957 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
5959 rtx reg
= TARGET_CMODEL
!= CMODEL_SMALL
? gen_reg_rtx (Pmode
) : NULL_RTX
;
5960 return create_TOC_reference (x
, reg
);
5966 /* Debug version of rs6000_legitimize_address. */
5968 rs6000_debug_legitimize_address (rtx x
, rtx oldx
, enum machine_mode mode
)
5974 ret
= rs6000_legitimize_address (x
, oldx
, mode
);
5975 insns
= get_insns ();
5981 "\nrs6000_legitimize_address: mode %s, old code %s, "
5982 "new code %s, modified\n",
5983 GET_MODE_NAME (mode
), GET_RTX_NAME (GET_CODE (x
)),
5984 GET_RTX_NAME (GET_CODE (ret
)));
5986 fprintf (stderr
, "Original address:\n");
5989 fprintf (stderr
, "oldx:\n");
5992 fprintf (stderr
, "New address:\n");
5997 fprintf (stderr
, "Insns added:\n");
5998 debug_rtx_list (insns
, 20);
6004 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6005 GET_MODE_NAME (mode
), GET_RTX_NAME (GET_CODE (x
)));
6016 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6017 We need to emit DTP-relative relocations. */
6020 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
6025 fputs ("\t.long\t", file
);
6028 fputs (DOUBLE_INT_ASM_OP
, file
);
6033 output_addr_const (file
, x
);
6034 fputs ("@dtprel+0x8000", file
);
6037 /* In the name of slightly smaller debug output, and to cater to
6038 general assembler lossage, recognize various UNSPEC sequences
6039 and turn them back into a direct symbol reference. */
6042 rs6000_delegitimize_address (rtx orig_x
)
6046 orig_x
= delegitimize_mem_from_attrs (orig_x
);
6051 if ((GET_CODE (x
) == PLUS
6052 || GET_CODE (x
) == LO_SUM
)
6053 && GET_CODE (XEXP (x
, 0)) == REG
6054 && (REGNO (XEXP (x
, 0)) == TOC_REGISTER
6055 || TARGET_MINIMAL_TOC
6056 || TARGET_CMODEL
!= CMODEL_SMALL
)
6057 && GET_CODE (XEXP (x
, 1)) == CONST
)
6059 y
= XEXP (XEXP (x
, 1), 0);
6060 if (GET_CODE (y
) == UNSPEC
6061 && XINT (y
, 1) == UNSPEC_TOCREL
)
6063 y
= XVECEXP (y
, 0, 0);
6064 if (!MEM_P (orig_x
))
6067 return replace_equiv_address_nv (orig_x
, y
);
6072 && GET_CODE (orig_x
) == LO_SUM
6073 && GET_CODE (XEXP (x
, 1)) == CONST
)
6075 y
= XEXP (XEXP (x
, 1), 0);
6076 if (GET_CODE (y
) == UNSPEC
6077 && XINT (y
, 1) == UNSPEC_MACHOPIC_OFFSET
)
6078 return XVECEXP (y
, 0, 0);
6084 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6086 static GTY(()) rtx rs6000_tls_symbol
;
6088 rs6000_tls_get_addr (void)
6090 if (!rs6000_tls_symbol
)
6091 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
6093 return rs6000_tls_symbol
;
6096 /* Construct the SYMBOL_REF for TLS GOT references. */
6098 static GTY(()) rtx rs6000_got_symbol
;
6100 rs6000_got_sym (void)
6102 if (!rs6000_got_symbol
)
6104 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
6105 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
6106 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
6109 return rs6000_got_symbol
;
6112 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6113 this (thread-local) address. */
6116 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
6120 dest
= gen_reg_rtx (Pmode
);
6121 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
6127 tlsreg
= gen_rtx_REG (Pmode
, 13);
6128 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
6132 tlsreg
= gen_rtx_REG (Pmode
, 2);
6133 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
6137 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
6141 tmp
= gen_reg_rtx (Pmode
);
6144 tlsreg
= gen_rtx_REG (Pmode
, 13);
6145 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
6149 tlsreg
= gen_rtx_REG (Pmode
, 2);
6150 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
6154 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
6156 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
6161 rtx r3
, got
, tga
, tmp1
, tmp2
, call_insn
;
6163 /* We currently use relocations like @got@tlsgd for tls, which
6164 means the linker will handle allocation of tls entries, placing
6165 them in the .got section. So use a pointer to the .got section,
6166 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6167 or to secondary GOT sections used by 32-bit -fPIC. */
6169 got
= gen_rtx_REG (Pmode
, 2);
6173 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
6176 rtx gsym
= rs6000_got_sym ();
6177 got
= gen_reg_rtx (Pmode
);
6179 rs6000_emit_move (got
, gsym
, Pmode
);
6184 tmp1
= gen_reg_rtx (Pmode
);
6185 tmp2
= gen_reg_rtx (Pmode
);
6186 mem
= gen_const_mem (Pmode
, tmp1
);
6187 lab
= gen_label_rtx ();
6188 emit_insn (gen_load_toc_v4_PIC_1b (gsym
, lab
));
6189 emit_move_insn (tmp1
, gen_rtx_REG (Pmode
, LR_REGNO
));
6190 emit_move_insn (tmp2
, mem
);
6191 last
= emit_insn (gen_addsi3 (got
, tmp1
, tmp2
));
6192 set_unique_reg_note (last
, REG_EQUAL
, gsym
);
6197 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
6199 r3
= gen_rtx_REG (Pmode
, 3);
6200 tga
= rs6000_tls_get_addr ();
6201 emit_library_call_value (tga
, dest
, LCT_CONST
, Pmode
, 1, r3
, Pmode
);
6203 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
6204 insn
= gen_tls_gd_aix64 (r3
, got
, addr
, tga
, const0_rtx
);
6205 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
6206 insn
= gen_tls_gd_aix32 (r3
, got
, addr
, tga
, const0_rtx
);
6207 else if (DEFAULT_ABI
== ABI_V4
)
6208 insn
= gen_tls_gd_sysvsi (r3
, got
, addr
, tga
, const0_rtx
);
6211 call_insn
= last_call_insn ();
6212 PATTERN (call_insn
) = insn
;
6213 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
6214 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn
),
6215 pic_offset_table_rtx
);
6217 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
6219 r3
= gen_rtx_REG (Pmode
, 3);
6220 tga
= rs6000_tls_get_addr ();
6221 tmp1
= gen_reg_rtx (Pmode
);
6222 emit_library_call_value (tga
, tmp1
, LCT_CONST
, Pmode
, 1, r3
, Pmode
);
6224 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
6225 insn
= gen_tls_ld_aix64 (r3
, got
, tga
, const0_rtx
);
6226 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
6227 insn
= gen_tls_ld_aix32 (r3
, got
, tga
, const0_rtx
);
6228 else if (DEFAULT_ABI
== ABI_V4
)
6229 insn
= gen_tls_ld_sysvsi (r3
, got
, tga
, const0_rtx
);
6232 call_insn
= last_call_insn ();
6233 PATTERN (call_insn
) = insn
;
6234 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
6235 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn
),
6236 pic_offset_table_rtx
);
6238 if (rs6000_tls_size
== 16)
6241 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
6243 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
6245 else if (rs6000_tls_size
== 32)
6247 tmp2
= gen_reg_rtx (Pmode
);
6249 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
6251 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
6254 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
6256 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
6260 tmp2
= gen_reg_rtx (Pmode
);
6262 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
6264 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
6266 insn
= gen_rtx_SET (Pmode
, dest
,
6267 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
6273 /* IE, or 64-bit offset LE. */
6274 tmp2
= gen_reg_rtx (Pmode
);
6276 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
6278 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
6281 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
6283 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
6291 /* Return 1 if X contains a thread-local symbol. */
6294 rs6000_tls_referenced_p (rtx x
)
6296 if (! TARGET_HAVE_TLS
)
6299 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
6302 /* Return 1 if *X is a thread-local symbol. This is the same as
6303 rs6000_tls_symbol_ref except for the type of the unused argument. */
6306 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
6308 return RS6000_SYMBOL_REF_TLS_P (*x
);
6311 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6312 replace the input X, or the original X if no replacement is called for.
6313 The output parameter *WIN is 1 if the calling macro should goto WIN,
6316 For RS/6000, we wish to handle large displacements off a base
6317 register by splitting the addend across an addiu/addis and the mem insn.
6318 This cuts number of extra insns needed from 3 to 1.
6320 On Darwin, we use this to generate code for floating point constants.
6321 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6322 The Darwin code is inside #if TARGET_MACHO because only then are the
6323 machopic_* functions defined. */
6325 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
6326 int opnum
, int type
,
6327 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
6329 bool reg_offset_p
= reg_offset_addressing_ok_p (mode
);
6331 /* We must recognize output that we have already generated ourselves. */
6332 if (GET_CODE (x
) == PLUS
6333 && GET_CODE (XEXP (x
, 0)) == PLUS
6334 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6335 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
6336 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
6338 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6339 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
6340 opnum
, (enum reload_type
)type
);
6345 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6346 if (GET_CODE (x
) == LO_SUM
6347 && GET_CODE (XEXP (x
, 0)) == HIGH
)
6349 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6350 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6351 opnum
, (enum reload_type
)type
);
6357 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
6358 && GET_CODE (x
) == LO_SUM
6359 && GET_CODE (XEXP (x
, 0)) == PLUS
6360 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
6361 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
6362 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
6363 && machopic_operand_p (XEXP (x
, 1)))
6365 /* Result of previous invocation of this function on Darwin
6366 floating point constant. */
6367 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6368 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6369 opnum
, (enum reload_type
)type
);
6375 if (TARGET_CMODEL
!= CMODEL_SMALL
6376 && GET_CODE (x
) == LO_SUM
6377 && GET_CODE (XEXP (x
, 0)) == PLUS
6378 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6379 && REGNO (XEXP (XEXP (x
, 0), 0)) == TOC_REGISTER
6380 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
6381 && GET_CODE (XEXP (x
, 1)) == CONST
6382 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == UNSPEC
6383 && XINT (XEXP (XEXP (x
, 1), 0), 1) == UNSPEC_TOCREL
6384 && rtx_equal_p (XEXP (XEXP (XEXP (x
, 0), 1), 0), XEXP (x
, 1)))
6386 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6387 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6388 opnum
, (enum reload_type
) type
);
6393 /* Force ld/std non-word aligned offset into base register by wrapping
6395 if (GET_CODE (x
) == PLUS
6396 && GET_CODE (XEXP (x
, 0)) == REG
6397 && REGNO (XEXP (x
, 0)) < 32
6398 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 1)
6399 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6401 && (INTVAL (XEXP (x
, 1)) & 3) != 0
6402 && VECTOR_MEM_NONE_P (mode
)
6403 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
6404 && TARGET_POWERPC64
)
6406 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
6407 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6408 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
6409 opnum
, (enum reload_type
) type
);
6414 if (GET_CODE (x
) == PLUS
6415 && GET_CODE (XEXP (x
, 0)) == REG
6416 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
6417 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 1)
6418 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6420 && !SPE_VECTOR_MODE (mode
)
6421 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
6422 || mode
== DDmode
|| mode
== TDmode
6424 && VECTOR_MEM_NONE_P (mode
))
6426 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
6427 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
6429 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6431 /* Check for 32-bit overflow. */
6432 if (high
+ low
!= val
)
6438 /* Reload the high part into a base reg; leave the low part
6439 in the mem directly. */
6441 x
= gen_rtx_PLUS (GET_MODE (x
),
6442 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
6446 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6447 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
6448 opnum
, (enum reload_type
)type
);
6453 if (GET_CODE (x
) == SYMBOL_REF
6455 && VECTOR_MEM_NONE_P (mode
)
6456 && !SPE_VECTOR_MODE (mode
)
6458 && DEFAULT_ABI
== ABI_DARWIN
6459 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
6461 && DEFAULT_ABI
== ABI_V4
6464 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6465 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6469 && (mode
!= DImode
|| TARGET_POWERPC64
)
6470 && ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_POWERPC64
6471 || (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)))
6476 rtx offset
= machopic_gen_offset (x
);
6477 x
= gen_rtx_LO_SUM (GET_MODE (x
),
6478 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
6479 gen_rtx_HIGH (Pmode
, offset
)), offset
);
6483 x
= gen_rtx_LO_SUM (GET_MODE (x
),
6484 gen_rtx_HIGH (Pmode
, x
), x
);
6486 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6487 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6488 opnum
, (enum reload_type
)type
);
6493 /* Reload an offset address wrapped by an AND that represents the
6494 masking of the lower bits. Strip the outer AND and let reload
6495 convert the offset address into an indirect address. For VSX,
6496 force reload to create the address with an AND in a separate
6497 register, because we can't guarantee an altivec register will
6499 if (VECTOR_MEM_ALTIVEC_P (mode
)
6500 && GET_CODE (x
) == AND
6501 && GET_CODE (XEXP (x
, 0)) == PLUS
6502 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
6503 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
6504 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6505 && INTVAL (XEXP (x
, 1)) == -16)
6514 && GET_CODE (x
) == SYMBOL_REF
6515 && constant_pool_expr_p (x
)
6516 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
6518 x
= create_TOC_reference (x
, NULL_RTX
);
6519 if (TARGET_CMODEL
!= CMODEL_SMALL
)
6520 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
6521 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
6522 opnum
, (enum reload_type
) type
);
6530 /* Debug version of rs6000_legitimize_reload_address. */
6532 rs6000_debug_legitimize_reload_address (rtx x
, enum machine_mode mode
,
6533 int opnum
, int type
,
6534 int ind_levels
, int *win
)
6536 rtx ret
= rs6000_legitimize_reload_address (x
, mode
, opnum
, type
,
6539 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6540 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6541 GET_MODE_NAME (mode
), opnum
, type
, ind_levels
, *win
);
6545 fprintf (stderr
, "Same address returned\n");
6547 fprintf (stderr
, "NULL returned\n");
6550 fprintf (stderr
, "New address:\n");
6557 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6558 that is a valid memory address for an instruction.
6559 The MODE argument is the machine mode for the MEM expression
6560 that wants to use this address.
6562 On the RS/6000, there are four valid address: a SYMBOL_REF that
6563 refers to a constant pool entry of an address (or the sum of it
6564 plus a constant), a short (16-bit signed) constant plus a register,
6565 the sum of two registers, or a register indirect, possibly with an
6566 auto-increment. For DFmode, DDmode and DImode with a constant plus
6567 register, we must ensure that both words are addressable or PowerPC64
6568 with offset word aligned.
6570 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6571 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6572 because adjacent memory cells are accessed by adding word-sized offsets
6573 during assembly output. */
6575 rs6000_legitimate_address_p (enum machine_mode mode
, rtx x
, bool reg_ok_strict
)
6577 bool reg_offset_p
= reg_offset_addressing_ok_p (mode
);
6579 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6580 if (VECTOR_MEM_ALTIVEC_P (mode
)
6581 && GET_CODE (x
) == AND
6582 && GET_CODE (XEXP (x
, 1)) == CONST_INT
6583 && INTVAL (XEXP (x
, 1)) == -16)
6586 if (RS6000_SYMBOL_REF_TLS_P (x
))
6588 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
6590 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
6591 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
)
6592 && !SPE_VECTOR_MODE (mode
)
6595 /* Restrict addressing for DI because of our SUBREG hackery. */
6596 && !(TARGET_E500_DOUBLE
6597 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
6599 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
6601 if (virtual_stack_registers_memory_p (x
))
6603 if (reg_offset_p
&& legitimate_small_data_p (mode
, x
))
6605 if (reg_offset_p
&& legitimate_constant_pool_address_p (x
, reg_ok_strict
))
6607 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6610 && GET_CODE (x
) == PLUS
6611 && GET_CODE (XEXP (x
, 0)) == REG
6612 && (XEXP (x
, 0) == virtual_stack_vars_rtx
6613 || XEXP (x
, 0) == arg_pointer_rtx
)
6614 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
6616 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
6621 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
6623 || (mode
!= DFmode
&& mode
!= DDmode
)
6624 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
))
6625 && (TARGET_POWERPC64
|| mode
!= DImode
)
6626 && !avoiding_indexed_address_p (mode
)
6627 && legitimate_indexed_address_p (x
, reg_ok_strict
))
6629 if (GET_CODE (x
) == PRE_MODIFY
6633 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
6635 || ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_E500_DOUBLE
))
6636 && (TARGET_POWERPC64
|| mode
!= DImode
)
6637 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
)
6638 && !SPE_VECTOR_MODE (mode
)
6639 /* Restrict addressing for DI because of our SUBREG hackery. */
6640 && !(TARGET_E500_DOUBLE
6641 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
6643 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
)
6644 && (rs6000_legitimate_offset_address_p (mode
, XEXP (x
, 1), reg_ok_strict
)
6645 || (!avoiding_indexed_address_p (mode
)
6646 && legitimate_indexed_address_p (XEXP (x
, 1), reg_ok_strict
)))
6647 && rtx_equal_p (XEXP (XEXP (x
, 1), 0), XEXP (x
, 0)))
6649 if (reg_offset_p
&& legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
6654 /* Debug version of rs6000_legitimate_address_p. */
6656 rs6000_debug_legitimate_address_p (enum machine_mode mode
, rtx x
,
6659 bool ret
= rs6000_legitimate_address_p (mode
, x
, reg_ok_strict
);
6661 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6662 "strict = %d, code = %s\n",
6663 ret
? "true" : "false",
6664 GET_MODE_NAME (mode
),
6666 GET_RTX_NAME (GET_CODE (x
)));
6672 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6675 rs6000_mode_dependent_address_p (const_rtx addr
)
6677 return rs6000_mode_dependent_address_ptr (addr
);
6680 /* Go to LABEL if ADDR (a legitimate address expression)
6681 has an effect that depends on the machine mode it is used for.
6683 On the RS/6000 this is true of all integral offsets (since AltiVec
6684 and VSX modes don't allow them) or is a pre-increment or decrement.
6686 ??? Except that due to conceptual problems in offsettable_address_p
6687 we can't really report the problems of integral offsets. So leave
6688 this assuming that the adjustable offset must be valid for the
6689 sub-words of a TFmode operand, which is what we had before. */
6692 rs6000_mode_dependent_address (const_rtx addr
)
6694 switch (GET_CODE (addr
))
6697 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6698 is considered a legitimate address before reload, so there
6699 are no offset restrictions in that case. Note that this
6700 condition is safe in strict mode because any address involving
6701 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6702 been rejected as illegitimate. */
6703 if (XEXP (addr
, 0) != virtual_stack_vars_rtx
6704 && XEXP (addr
, 0) != arg_pointer_rtx
6705 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
6707 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
6708 return val
+ 12 + 0x8000 >= 0x10000;
6713 /* Anything in the constant pool is sufficiently aligned that
6714 all bytes have the same high part address. */
6715 return !legitimate_constant_pool_address_p (addr
, false);
6717 /* Auto-increment cases are now treated generically in recog.c. */
6719 return TARGET_UPDATE
;
6721 /* AND is only allowed in Altivec loads. */
6732 /* Debug version of rs6000_mode_dependent_address. */
6734 rs6000_debug_mode_dependent_address (const_rtx addr
)
6736 bool ret
= rs6000_mode_dependent_address (addr
);
6738 fprintf (stderr
, "\nrs6000_mode_dependent_address: ret = %s\n",
6739 ret
? "true" : "false");
6745 /* Implement FIND_BASE_TERM. */
6748 rs6000_find_base_term (rtx op
)
6752 split_const (op
, &base
, &offset
);
6753 if (GET_CODE (base
) == UNSPEC
)
6754 switch (XINT (base
, 1))
6757 case UNSPEC_MACHOPIC_OFFSET
:
6758 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6759 for aliasing purposes. */
6760 return XVECEXP (base
, 0, 0);
6766 /* More elaborate version of recog's offsettable_memref_p predicate
6767 that works around the ??? note of rs6000_mode_dependent_address.
6768 In particular it accepts
6770 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6772 in 32-bit mode, that the recog predicate rejects. */
6775 rs6000_offsettable_memref_p (rtx op
)
6780 /* First mimic offsettable_memref_p. */
6781 if (offsettable_address_p (1, GET_MODE (op
), XEXP (op
, 0)))
6784 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6785 the latter predicate knows nothing about the mode of the memory
6786 reference and, therefore, assumes that it is the largest supported
6787 mode (TFmode). As a consequence, legitimate offsettable memory
6788 references are rejected. rs6000_legitimate_offset_address_p contains
6789 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6790 return rs6000_legitimate_offset_address_p (GET_MODE (op
), XEXP (op
, 0), 1);
6793 /* Change register usage conditional on target flags. */
6795 rs6000_conditional_register_usage (void)
6799 /* Set MQ register fixed (already call_used) if not POWER
6800 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6805 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6807 fixed_regs
[13] = call_used_regs
[13]
6808 = call_really_used_regs
[13] = 1;
6810 /* Conditionally disable FPRs. */
6811 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
6812 for (i
= 32; i
< 64; i
++)
6813 fixed_regs
[i
] = call_used_regs
[i
]
6814 = call_really_used_regs
[i
] = 1;
6816 /* The TOC register is not killed across calls in a way that is
6817 visible to the compiler. */
6818 if (DEFAULT_ABI
== ABI_AIX
)
6819 call_really_used_regs
[2] = 0;
6821 if (DEFAULT_ABI
== ABI_V4
6822 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
6824 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
6826 if (DEFAULT_ABI
== ABI_V4
6827 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
6829 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
6830 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
6831 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
6833 if (DEFAULT_ABI
== ABI_DARWIN
6834 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
6835 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
6836 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
6837 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
6839 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
6840 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
6841 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
6845 global_regs
[SPEFSCR_REGNO
] = 1;
6846 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6847 registers in prologues and epilogues. We no longer use r14
6848 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6849 pool for link-compatibility with older versions of GCC. Once
6850 "old" code has died out, we can return r14 to the allocation
6853 = call_used_regs
[14]
6854 = call_really_used_regs
[14] = 1;
6857 if (!TARGET_ALTIVEC
&& !TARGET_VSX
)
6859 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
6860 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
6861 call_really_used_regs
[VRSAVE_REGNO
] = 1;
6864 if (TARGET_ALTIVEC
|| TARGET_VSX
)
6865 global_regs
[VSCR_REGNO
] = 1;
6867 if (TARGET_ALTIVEC_ABI
)
6869 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
6870 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
6872 /* AIX reserves VR20:31 in non-extended ABI mode. */
6874 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
< FIRST_ALTIVEC_REGNO
+ 32; ++i
)
6875 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
6879 /* Try to output insns to set TARGET equal to the constant C if it can
6880 be done in less than N insns. Do all computations in MODE.
6881 Returns the place where the output has been placed if it can be
6882 done and the insns have been emitted. If it would take more than N
6883 insns, zero is returned and no insns and emitted. */
6886 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
6887 rtx source
, int n ATTRIBUTE_UNUSED
)
6889 rtx result
, insn
, set
;
6890 HOST_WIDE_INT c0
, c1
;
6897 dest
= gen_reg_rtx (mode
);
6898 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
6902 result
= !can_create_pseudo_p () ? dest
: gen_reg_rtx (SImode
);
6904 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (result
),
6905 GEN_INT (INTVAL (source
)
6906 & (~ (HOST_WIDE_INT
) 0xffff))));
6907 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
6908 gen_rtx_IOR (SImode
, copy_rtx (result
),
6909 GEN_INT (INTVAL (source
) & 0xffff))));
6914 switch (GET_CODE (source
))
6917 c0
= INTVAL (source
);
6922 #if HOST_BITS_PER_WIDE_INT >= 64
6923 c0
= CONST_DOUBLE_LOW (source
);
6926 c0
= CONST_DOUBLE_LOW (source
);
6927 c1
= CONST_DOUBLE_HIGH (source
);
6935 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
6942 insn
= get_last_insn ();
6943 set
= single_set (insn
);
6944 if (! CONSTANT_P (SET_SRC (set
)))
6945 set_unique_reg_note (insn
, REG_EQUAL
, source
);
6950 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6951 fall back to a straight forward decomposition. We do this to avoid
6952 exponential run times encountered when looking for longer sequences
6953 with rs6000_emit_set_const. */
6955 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
6957 if (!TARGET_POWERPC64
)
6959 rtx operand1
, operand2
;
6961 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
6963 operand2
= operand_subword_force (copy_rtx (dest
), WORDS_BIG_ENDIAN
!= 0,
6965 emit_move_insn (operand1
, GEN_INT (c1
));
6966 emit_move_insn (operand2
, GEN_INT (c2
));
6970 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
6973 ud2
= (c1
& 0xffff0000) >> 16;
6974 #if HOST_BITS_PER_WIDE_INT >= 64
6978 ud4
= (c2
& 0xffff0000) >> 16;
6980 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
6981 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
6984 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
6986 emit_move_insn (dest
, GEN_INT (ud1
));
6989 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
6990 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
6993 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
6996 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
6998 emit_move_insn (copy_rtx (dest
),
6999 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7002 else if (ud3
== 0 && ud4
== 0)
7004 gcc_assert (ud2
& 0x8000);
7005 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
7008 emit_move_insn (copy_rtx (dest
),
7009 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7011 emit_move_insn (copy_rtx (dest
),
7012 gen_rtx_ZERO_EXTEND (DImode
,
7013 gen_lowpart (SImode
,
7016 else if ((ud4
== 0xffff && (ud3
& 0x8000))
7017 || (ud4
== 0 && ! (ud3
& 0x8000)))
7020 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
7023 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
7026 emit_move_insn (copy_rtx (dest
),
7027 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7029 emit_move_insn (copy_rtx (dest
),
7030 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
7033 emit_move_insn (copy_rtx (dest
),
7034 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7040 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
7043 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
7046 emit_move_insn (copy_rtx (dest
),
7047 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7050 emit_move_insn (copy_rtx (dest
),
7051 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
7054 emit_move_insn (copy_rtx (dest
),
7055 gen_rtx_IOR (DImode
, copy_rtx (dest
),
7056 GEN_INT (ud2
<< 16)));
7058 emit_move_insn (copy_rtx (dest
),
7059 gen_rtx_IOR (DImode
, copy_rtx (dest
), GEN_INT (ud1
)));
7065 /* Helper for the following. Get rid of [r+r] memory refs
7066 in cases where it won't work (TImode, TFmode, TDmode). */
7069 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
7071 if (reload_in_progress
)
7074 if (GET_CODE (operands
[0]) == MEM
7075 && GET_CODE (XEXP (operands
[0], 0)) != REG
7076 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0), false))
7078 = replace_equiv_address (operands
[0],
7079 copy_addr_to_reg (XEXP (operands
[0], 0)));
7081 if (GET_CODE (operands
[1]) == MEM
7082 && GET_CODE (XEXP (operands
[1], 0)) != REG
7083 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0), false))
7085 = replace_equiv_address (operands
[1],
7086 copy_addr_to_reg (XEXP (operands
[1], 0)));
7089 /* Return true if memory accesses to DECL are known to never straddle
7093 offsettable_ok_by_alignment (tree decl
)
7095 unsigned HOST_WIDE_INT dsize
, dalign
;
7097 /* Presume any compiler generated symbol_ref is suitably aligned. */
7101 if (TREE_CODE (decl
) != VAR_DECL
7102 && TREE_CODE (decl
) != PARM_DECL
7103 && TREE_CODE (decl
) != RESULT_DECL
7104 && TREE_CODE (decl
) != FIELD_DECL
)
7107 if (!DECL_SIZE_UNIT (decl
))
7110 if (!host_integerp (DECL_SIZE_UNIT (decl
), 1))
7113 dsize
= tree_low_cst (DECL_SIZE_UNIT (decl
), 1);
7119 dalign
= DECL_ALIGN_UNIT (decl
);
7120 return dalign
>= dsize
;
7123 /* Emit a move from SOURCE to DEST in mode MODE. */
7125 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
7129 operands
[1] = source
;
7131 if (TARGET_DEBUG_ADDR
)
7134 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7135 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7136 GET_MODE_NAME (mode
),
7139 can_create_pseudo_p ());
7141 fprintf (stderr
, "source:\n");
7145 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7146 if (GET_CODE (operands
[1]) == CONST_DOUBLE
7147 && ! FLOAT_MODE_P (mode
)
7148 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
7150 /* FIXME. This should never happen. */
7151 /* Since it seems that it does, do the safe thing and convert
7153 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
7155 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
7156 || FLOAT_MODE_P (mode
)
7157 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
7158 || CONST_DOUBLE_LOW (operands
[1]) < 0)
7159 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
7160 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
7162 /* Check if GCC is setting up a block move that will end up using FP
7163 registers as temporaries. We must make sure this is acceptable. */
7164 if (GET_CODE (operands
[0]) == MEM
7165 && GET_CODE (operands
[1]) == MEM
7167 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
7168 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
7169 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
7170 ? 32 : MEM_ALIGN (operands
[0])))
7171 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
7173 : MEM_ALIGN (operands
[1]))))
7174 && ! MEM_VOLATILE_P (operands
[0])
7175 && ! MEM_VOLATILE_P (operands
[1]))
7177 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
7178 adjust_address (operands
[1], SImode
, 0));
7179 emit_move_insn (adjust_address (copy_rtx (operands
[0]), SImode
, 4),
7180 adjust_address (copy_rtx (operands
[1]), SImode
, 4));
7184 if (can_create_pseudo_p () && GET_CODE (operands
[0]) == MEM
7185 && !gpc_reg_operand (operands
[1], mode
))
7186 operands
[1] = force_reg (mode
, operands
[1]);
7188 if (mode
== SFmode
&& ! TARGET_POWERPC
7189 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
7190 && GET_CODE (operands
[0]) == MEM
)
7194 if (reload_in_progress
|| reload_completed
)
7195 regnum
= true_regnum (operands
[1]);
7196 else if (GET_CODE (operands
[1]) == REG
)
7197 regnum
= REGNO (operands
[1]);
7201 /* If operands[1] is a register, on POWER it may have
7202 double-precision data in it, so truncate it to single
7204 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
7207 newreg
= (!can_create_pseudo_p () ? copy_rtx (operands
[1])
7208 : gen_reg_rtx (mode
));
7209 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
7210 operands
[1] = newreg
;
7214 /* Recognize the case where operand[1] is a reference to thread-local
7215 data and load its address to a register. */
7216 if (rs6000_tls_referenced_p (operands
[1]))
7218 enum tls_model model
;
7219 rtx tmp
= operands
[1];
7222 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
7224 addend
= XEXP (XEXP (tmp
, 0), 1);
7225 tmp
= XEXP (XEXP (tmp
, 0), 0);
7228 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
7229 model
= SYMBOL_REF_TLS_MODEL (tmp
);
7230 gcc_assert (model
!= 0);
7232 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
7235 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
7236 tmp
= force_operand (tmp
, operands
[0]);
7241 /* Handle the case where reload calls us with an invalid address. */
7242 if (reload_in_progress
&& mode
== Pmode
7243 && (! general_operand (operands
[1], mode
)
7244 || ! nonimmediate_operand (operands
[0], mode
)))
7247 /* 128-bit constant floating-point values on Darwin should really be
7248 loaded as two parts. */
7249 if (!TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
7250 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
7252 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7253 know how to get a DFmode SUBREG of a TFmode. */
7254 enum machine_mode imode
= (TARGET_E500_DOUBLE
? DFmode
: DImode
);
7255 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
, 0),
7256 simplify_gen_subreg (imode
, operands
[1], mode
, 0),
7258 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
,
7259 GET_MODE_SIZE (imode
)),
7260 simplify_gen_subreg (imode
, operands
[1], mode
,
7261 GET_MODE_SIZE (imode
)),
7266 if (reload_in_progress
&& cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
7267 cfun
->machine
->sdmode_stack_slot
=
7268 eliminate_regs (cfun
->machine
->sdmode_stack_slot
, VOIDmode
, NULL_RTX
);
7270 if (reload_in_progress
7272 && MEM_P (operands
[0])
7273 && rtx_equal_p (operands
[0], cfun
->machine
->sdmode_stack_slot
)
7274 && REG_P (operands
[1]))
7276 if (FP_REGNO_P (REGNO (operands
[1])))
7278 rtx mem
= adjust_address_nv (operands
[0], DDmode
, 0);
7279 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7280 emit_insn (gen_movsd_store (mem
, operands
[1]));
7282 else if (INT_REGNO_P (REGNO (operands
[1])))
7284 rtx mem
= adjust_address_nv (operands
[0], mode
, 4);
7285 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7286 emit_insn (gen_movsd_hardfloat (mem
, operands
[1]));
7292 if (reload_in_progress
7294 && REG_P (operands
[0])
7295 && MEM_P (operands
[1])
7296 && rtx_equal_p (operands
[1], cfun
->machine
->sdmode_stack_slot
))
7298 if (FP_REGNO_P (REGNO (operands
[0])))
7300 rtx mem
= adjust_address_nv (operands
[1], DDmode
, 0);
7301 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7302 emit_insn (gen_movsd_load (operands
[0], mem
));
7304 else if (INT_REGNO_P (REGNO (operands
[0])))
7306 rtx mem
= adjust_address_nv (operands
[1], mode
, 4);
7307 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
7308 emit_insn (gen_movsd_hardfloat (operands
[0], mem
));
7315 /* FIXME: In the long term, this switch statement should go away
7316 and be replaced by a sequence of tests based on things like
7322 if (CONSTANT_P (operands
[1])
7323 && GET_CODE (operands
[1]) != CONST_INT
)
7324 operands
[1] = force_const_mem (mode
, operands
[1]);
7329 rs6000_eliminate_indexed_memrefs (operands
);
7336 if (CONSTANT_P (operands
[1])
7337 && ! easy_fp_constant (operands
[1], mode
))
7338 operands
[1] = force_const_mem (mode
, operands
[1]);
7351 if (CONSTANT_P (operands
[1])
7352 && !easy_vector_constant (operands
[1], mode
))
7353 operands
[1] = force_const_mem (mode
, operands
[1]);
7358 /* Use default pattern for address of ELF small data */
7361 && DEFAULT_ABI
== ABI_V4
7362 && (GET_CODE (operands
[1]) == SYMBOL_REF
7363 || GET_CODE (operands
[1]) == CONST
)
7364 && small_data_operand (operands
[1], mode
))
7366 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
7370 if (DEFAULT_ABI
== ABI_V4
7371 && mode
== Pmode
&& mode
== SImode
7372 && flag_pic
== 1 && got_operand (operands
[1], mode
))
7374 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
7378 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
7382 && CONSTANT_P (operands
[1])
7383 && GET_CODE (operands
[1]) != HIGH
7384 && GET_CODE (operands
[1]) != CONST_INT
)
7386 rtx target
= (!can_create_pseudo_p ()
7388 : gen_reg_rtx (mode
));
7390 /* If this is a function address on -mcall-aixdesc,
7391 convert it to the address of the descriptor. */
7392 if (DEFAULT_ABI
== ABI_AIX
7393 && GET_CODE (operands
[1]) == SYMBOL_REF
7394 && XSTR (operands
[1], 0)[0] == '.')
7396 const char *name
= XSTR (operands
[1], 0);
7398 while (*name
== '.')
7400 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
7401 CONSTANT_POOL_ADDRESS_P (new_ref
)
7402 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
7403 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
7404 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
7405 SYMBOL_REF_DATA (new_ref
) = SYMBOL_REF_DATA (operands
[1]);
7406 operands
[1] = new_ref
;
7409 if (DEFAULT_ABI
== ABI_DARWIN
)
7412 if (MACHO_DYNAMIC_NO_PIC_P
)
7414 /* Take care of any required data indirection. */
7415 operands
[1] = rs6000_machopic_legitimize_pic_address (
7416 operands
[1], mode
, operands
[0]);
7417 if (operands
[0] != operands
[1])
7418 emit_insn (gen_rtx_SET (VOIDmode
,
7419 operands
[0], operands
[1]));
7423 emit_insn (gen_macho_high (target
, operands
[1]));
7424 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
7428 emit_insn (gen_elf_high (target
, operands
[1]));
7429 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
7433 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7434 and we have put it in the TOC, we just need to make a TOC-relative
7437 && GET_CODE (operands
[1]) == SYMBOL_REF
7438 && constant_pool_expr_p (operands
[1])
7439 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
7440 get_pool_mode (operands
[1])))
7441 || (TARGET_CMODEL
== CMODEL_MEDIUM
7442 && GET_CODE (operands
[1]) == SYMBOL_REF
7443 && !CONSTANT_POOL_ADDRESS_P (operands
[1])
7444 && SYMBOL_REF_LOCAL_P (operands
[1])
7445 && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands
[1]))))
7448 if (TARGET_CMODEL
!= CMODEL_SMALL
)
7450 if (can_create_pseudo_p ())
7451 reg
= gen_reg_rtx (Pmode
);
7455 operands
[1] = create_TOC_reference (operands
[1], reg
);
7457 else if (mode
== Pmode
7458 && CONSTANT_P (operands
[1])
7459 && ((GET_CODE (operands
[1]) != CONST_INT
7460 && ! easy_fp_constant (operands
[1], mode
))
7461 || (GET_CODE (operands
[1]) == CONST_INT
7462 && (num_insns_constant (operands
[1], mode
)
7463 > (TARGET_CMODEL
!= CMODEL_SMALL
? 3 : 2)))
7464 || (GET_CODE (operands
[0]) == REG
7465 && FP_REGNO_P (REGNO (operands
[0]))))
7466 && GET_CODE (operands
[1]) != HIGH
7467 && ! legitimate_constant_pool_address_p (operands
[1], false)
7468 && ! toc_relative_expr_p (operands
[1])
7469 && (TARGET_CMODEL
== CMODEL_SMALL
7470 || can_create_pseudo_p ()
7471 || (REG_P (operands
[0])
7472 && INT_REG_OK_FOR_BASE_P (operands
[0], true))))
7476 /* Darwin uses a special PIC legitimizer. */
7477 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
7480 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
7482 if (operands
[0] != operands
[1])
7483 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
7488 /* If we are to limit the number of things we put in the TOC and
7489 this is a symbol plus a constant we can add in one insn,
7490 just put the symbol in the TOC and add the constant. Don't do
7491 this if reload is in progress. */
7492 if (GET_CODE (operands
[1]) == CONST
7493 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
7494 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
7495 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
7496 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
7497 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
7498 && ! side_effects_p (operands
[0]))
7501 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
7502 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
7504 sym
= force_reg (mode
, sym
);
7505 emit_insn (gen_add3_insn (operands
[0], sym
, other
));
7509 operands
[1] = force_const_mem (mode
, operands
[1]);
7512 && GET_CODE (XEXP (operands
[1], 0)) == SYMBOL_REF
7513 && constant_pool_expr_p (XEXP (operands
[1], 0))
7514 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7515 get_pool_constant (XEXP (operands
[1], 0)),
7516 get_pool_mode (XEXP (operands
[1], 0))))
7520 if (TARGET_CMODEL
!= CMODEL_SMALL
)
7522 if (can_create_pseudo_p ())
7523 reg
= gen_reg_rtx (Pmode
);
7527 tocref
= create_TOC_reference (XEXP (operands
[1], 0), reg
);
7528 operands
[1] = gen_const_mem (mode
, tocref
);
7529 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
7535 rs6000_eliminate_indexed_memrefs (operands
);
7539 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
7541 gen_rtx_SET (VOIDmode
,
7542 operands
[0], operands
[1]),
7543 gen_rtx_CLOBBER (VOIDmode
,
7544 gen_rtx_SCRATCH (SImode
)))));
7550 fatal_insn ("bad move", gen_rtx_SET (VOIDmode
, dest
, source
));
7553 /* Above, we may have called force_const_mem which may have returned
7554 an invalid address. If we can, fix this up; otherwise, reload will
7555 have to deal with it. */
7556 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
7557 operands
[1] = validize_mem (operands
[1]);
7560 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
7563 /* Nonzero if we can use a floating-point register to pass this arg. */
7564 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7565 (SCALAR_FLOAT_MODE_P (MODE) \
7566 && (CUM)->fregno <= FP_ARG_MAX_REG \
7567 && TARGET_HARD_FLOAT && TARGET_FPRS)
7569 /* Nonzero if we can use an AltiVec register to pass this arg. */
7570 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7571 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7572 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7573 && TARGET_ALTIVEC_ABI \
7576 /* Return a nonzero value to say to return the function value in
7577 memory, just as large structures are always returned. TYPE will be
7578 the data type of the value, and FNTYPE will be the type of the
7579 function doing the returning, or @code{NULL} for libcalls.
7581 The AIX ABI for the RS/6000 specifies that all structures are
7582 returned in memory. The Darwin ABI does the same.
7584 For the Darwin 64 Bit ABI, a function result can be returned in
7585 registers or in memory, depending on the size of the return data
7586 type. If it is returned in registers, the value occupies the same
7587 registers as it would if it were the first and only function
7588 argument. Otherwise, the function places its result in memory at
7589 the location pointed to by GPR3.
7591 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7592 but a draft put them in memory, and GCC used to implement the draft
7593 instead of the final standard. Therefore, aix_struct_return
7594 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7595 compatibility can change DRAFT_V4_STRUCT_RET to override the
7596 default, and -m switches get the final word. See
7597 rs6000_option_override_internal for more details.
7599 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7600 long double support is enabled. These values are returned in memory.
7602 int_size_in_bytes returns -1 for variable size objects, which go in
7603 memory always. The cast to unsigned makes -1 > 8. */
7606 rs6000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
7608 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7610 && rs6000_darwin64_abi
7611 && TREE_CODE (type
) == RECORD_TYPE
7612 && int_size_in_bytes (type
) > 0)
7614 CUMULATIVE_ARGS valcum
;
7618 valcum
.fregno
= FP_ARG_MIN_REG
;
7619 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
7620 /* Do a trial code generation as if this were going to be passed
7621 as an argument; if any part goes in memory, we return NULL. */
7622 valret
= rs6000_darwin64_record_arg (&valcum
, type
, true, true);
7625 /* Otherwise fall through to more conventional ABI rules. */
7628 if (AGGREGATE_TYPE_P (type
)
7629 && (aix_struct_return
7630 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
7633 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7634 modes only exist for GCC vector types if -maltivec. */
7635 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
7636 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
7639 /* Return synthetic vectors in memory. */
7640 if (TREE_CODE (type
) == VECTOR_TYPE
7641 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
7643 static bool warned_for_return_big_vectors
= false;
7644 if (!warned_for_return_big_vectors
)
7646 warning (0, "GCC vector returned by reference: "
7647 "non-standard ABI extension with no compatibility guarantee");
7648 warned_for_return_big_vectors
= true;
7653 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& TYPE_MODE (type
) == TFmode
)
7659 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7660 for a call to a function whose data type is FNTYPE.
7661 For a library call, FNTYPE is 0.
7663 For incoming args we set the number of arguments in the prototype large
7664 so we never return a PARALLEL. */
7667 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
7668 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
7669 int libcall
, int n_named_args
)
7671 static CUMULATIVE_ARGS zero_cumulative
;
7673 *cum
= zero_cumulative
;
7675 cum
->fregno
= FP_ARG_MIN_REG
;
7676 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
7677 cum
->prototype
= (fntype
&& TYPE_ARG_TYPES (fntype
));
7678 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
7679 ? CALL_LIBCALL
: CALL_NORMAL
);
7680 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
7681 cum
->stdarg
= stdarg_p (fntype
);
7683 cum
->nargs_prototype
= 0;
7684 if (incoming
|| cum
->prototype
)
7685 cum
->nargs_prototype
= n_named_args
;
7687 /* Check for a longcall attribute. */
7688 if ((!fntype
&& rs6000_default_long_calls
)
7690 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
7691 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
7692 cum
->call_cookie
|= CALL_LONG
;
7694 if (TARGET_DEBUG_ARG
)
7696 fprintf (stderr
, "\ninit_cumulative_args:");
7699 tree ret_type
= TREE_TYPE (fntype
);
7700 fprintf (stderr
, " ret code = %s,",
7701 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
7704 if (cum
->call_cookie
& CALL_LONG
)
7705 fprintf (stderr
, " longcall,");
7707 fprintf (stderr
, " proto = %d, nargs = %d\n",
7708 cum
->prototype
, cum
->nargs_prototype
);
7713 && TARGET_ALTIVEC_ABI
7714 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
7716 error ("cannot return value in vector register because"
7717 " altivec instructions are disabled, use -maltivec"
7722 /* Return true if TYPE must be passed on the stack and not in registers. */
7725 rs6000_must_pass_in_stack (enum machine_mode mode
, const_tree type
)
7727 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
7728 return must_pass_in_stack_var_size (mode
, type
);
7730 return must_pass_in_stack_var_size_or_pad (mode
, type
);
7733 /* If defined, a C expression which determines whether, and in which
7734 direction, to pad out an argument with extra space. The value
7735 should be of type `enum direction': either `upward' to pad above
7736 the argument, `downward' to pad below, or `none' to inhibit
7739 For the AIX ABI structs are always stored left shifted in their
7743 function_arg_padding (enum machine_mode mode
, const_tree type
)
7745 #ifndef AGGREGATE_PADDING_FIXED
7746 #define AGGREGATE_PADDING_FIXED 0
7748 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7749 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7752 if (!AGGREGATE_PADDING_FIXED
)
7754 /* GCC used to pass structures of the same size as integer types as
7755 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7756 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7757 passed padded downward, except that -mstrict-align further
7758 muddied the water in that multi-component structures of 2 and 4
7759 bytes in size were passed padded upward.
7761 The following arranges for best compatibility with previous
7762 versions of gcc, but removes the -mstrict-align dependency. */
7763 if (BYTES_BIG_ENDIAN
)
7765 HOST_WIDE_INT size
= 0;
7767 if (mode
== BLKmode
)
7769 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
7770 size
= int_size_in_bytes (type
);
7773 size
= GET_MODE_SIZE (mode
);
7775 if (size
== 1 || size
== 2 || size
== 4)
7781 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
7783 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
7787 /* Fall back to the default. */
7788 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
7791 /* If defined, a C expression that gives the alignment boundary, in bits,
7792 of an argument with the specified mode and type. If it is not defined,
7793 PARM_BOUNDARY is used for all arguments.
7795 V.4 wants long longs and doubles to be double word aligned. Just
7796 testing the mode size is a boneheaded way to do this as it means
7797 that other types such as complex int are also double word aligned.
7798 However, we're stuck with this because changing the ABI might break
7799 existing library interfaces.
7801 Doubleword align SPE vectors.
7802 Quadword align Altivec vectors.
7803 Quadword align large synthetic vector types. */
7806 function_arg_boundary (enum machine_mode mode
, const_tree type
)
7808 if (DEFAULT_ABI
== ABI_V4
7809 && (GET_MODE_SIZE (mode
) == 8
7810 || (TARGET_HARD_FLOAT
7812 && (mode
== TFmode
|| mode
== TDmode
))))
7814 else if (SPE_VECTOR_MODE (mode
)
7815 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
7816 && int_size_in_bytes (type
) >= 8
7817 && int_size_in_bytes (type
) < 16))
7819 else if ((ALTIVEC_VECTOR_MODE (mode
) || VSX_VECTOR_MODE (mode
))
7820 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
7821 && int_size_in_bytes (type
) >= 16))
7823 else if (TARGET_MACHO
7824 && rs6000_darwin64_abi
7826 && type
&& TYPE_ALIGN (type
) > 64)
7829 return PARM_BOUNDARY
;
7832 /* For a function parm of MODE and TYPE, return the starting word in
7833 the parameter area. NWORDS of the parameter area are already used. */
7836 rs6000_parm_start (enum machine_mode mode
, const_tree type
,
7837 unsigned int nwords
)
7840 unsigned int parm_offset
;
7842 align
= function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
7843 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
7844 return nwords
+ (-(parm_offset
+ nwords
) & align
);
7847 /* Compute the size (in words) of a function argument. */
7849 static unsigned long
7850 rs6000_arg_size (enum machine_mode mode
, const_tree type
)
7854 if (mode
!= BLKmode
)
7855 size
= GET_MODE_SIZE (mode
);
7857 size
= int_size_in_bytes (type
);
7860 return (size
+ 3) >> 2;
7862 return (size
+ 7) >> 3;
7865 /* Use this to flush pending int fields. */
7868 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
7869 HOST_WIDE_INT bitpos
, int final
)
7871 unsigned int startbit
, endbit
;
7872 int intregs
, intoffset
;
7873 enum machine_mode mode
;
7875 /* Handle the situations where a float is taking up the first half
7876 of the GPR, and the other half is empty (typically due to
7877 alignment restrictions). We can detect this by a 8-byte-aligned
7878 int field, or by seeing that this is the final flush for this
7879 argument. Count the word and continue on. */
7880 if (cum
->floats_in_gpr
== 1
7881 && (cum
->intoffset
% 64 == 0
7882 || (cum
->intoffset
== -1 && final
)))
7885 cum
->floats_in_gpr
= 0;
7888 if (cum
->intoffset
== -1)
7891 intoffset
= cum
->intoffset
;
7892 cum
->intoffset
= -1;
7893 cum
->floats_in_gpr
= 0;
7895 if (intoffset
% BITS_PER_WORD
!= 0)
7897 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
7899 if (mode
== BLKmode
)
7901 /* We couldn't find an appropriate mode, which happens,
7902 e.g., in packed structs when there are 3 bytes to load.
7903 Back intoffset back to the beginning of the word in this
7905 intoffset
= intoffset
& -BITS_PER_WORD
;
7909 startbit
= intoffset
& -BITS_PER_WORD
;
7910 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
7911 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
7912 cum
->words
+= intregs
;
7913 /* words should be unsigned. */
7914 if ((unsigned)cum
->words
< (endbit
/BITS_PER_WORD
))
7916 int pad
= (endbit
/BITS_PER_WORD
) - cum
->words
;
7921 /* The darwin64 ABI calls for us to recurse down through structs,
7922 looking for elements passed in registers. Unfortunately, we have
7923 to track int register count here also because of misalignments
7924 in powerpc alignment mode. */
7927 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
7929 HOST_WIDE_INT startbitpos
)
7933 for (f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
7934 if (TREE_CODE (f
) == FIELD_DECL
)
7936 HOST_WIDE_INT bitpos
= startbitpos
;
7937 tree ftype
= TREE_TYPE (f
);
7938 enum machine_mode mode
;
7939 if (ftype
== error_mark_node
)
7941 mode
= TYPE_MODE (ftype
);
7943 if (DECL_SIZE (f
) != 0
7944 && host_integerp (bit_position (f
), 1))
7945 bitpos
+= int_bit_position (f
);
7947 /* ??? FIXME: else assume zero offset. */
7949 if (TREE_CODE (ftype
) == RECORD_TYPE
)
7950 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
7951 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
7953 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
, 0);
7954 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
7955 /* Single-precision floats present a special problem for
7956 us, because they are smaller than an 8-byte GPR, and so
7957 the structure-packing rules combined with the standard
7958 varargs behavior mean that we want to pack float/float
7959 and float/int combinations into a single register's
7960 space. This is complicated by the arg advance flushing,
7961 which works on arbitrarily large groups of int-type
7965 if (cum
->floats_in_gpr
== 1)
7967 /* Two floats in a word; count the word and reset
7970 cum
->floats_in_gpr
= 0;
7972 else if (bitpos
% 64 == 0)
7974 /* A float at the beginning of an 8-byte word;
7975 count it and put off adjusting cum->words until
7976 we see if a arg advance flush is going to do it
7978 cum
->floats_in_gpr
++;
7982 /* The float is at the end of a word, preceded
7983 by integer fields, so the arg advance flush
7984 just above has already set cum->words and
7985 everything is taken care of. */
7989 cum
->words
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
7991 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
7993 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
, 0);
7997 else if (cum
->intoffset
== -1)
7998 cum
->intoffset
= bitpos
;
8002 /* Check for an item that needs to be considered specially under the darwin 64
8003 bit ABI. These are record types where the mode is BLK or the structure is
8006 rs6000_darwin64_struct_check_p (enum machine_mode mode
, const_tree type
)
8008 return rs6000_darwin64_abi
8009 && ((mode
== BLKmode
8010 && TREE_CODE (type
) == RECORD_TYPE
8011 && int_size_in_bytes (type
) > 0)
8012 || (type
&& TREE_CODE (type
) == RECORD_TYPE
8013 && int_size_in_bytes (type
) == 8)) ? 1 : 0;
8016 /* Update the data in CUM to advance over an argument
8017 of mode MODE and data type TYPE.
8018 (TYPE is null for libcalls where that information may not be available.)
8020 Note that for args passed by reference, function_arg will be called
8021 with MODE and TYPE set to that of the pointer to the arg, not the arg
8025 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8026 const_tree type
, bool named
, int depth
)
8029 /* Only tick off an argument if we're not recursing. */
8031 cum
->nargs_prototype
--;
8033 if (TARGET_ALTIVEC_ABI
8034 && (ALTIVEC_VECTOR_MODE (mode
)
8035 || VSX_VECTOR_MODE (mode
)
8036 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
8037 && int_size_in_bytes (type
) == 16)))
8041 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
8044 if (!TARGET_ALTIVEC
)
8045 error ("cannot pass argument in vector register because"
8046 " altivec instructions are disabled, use -maltivec"
8049 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8050 even if it is going to be passed in a vector register.
8051 Darwin does the same for variable-argument functions. */
8052 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
8053 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
8063 /* Vector parameters must be 16-byte aligned. This places
8064 them at 2 mod 4 in terms of words in 32-bit mode, since
8065 the parameter save area starts at offset 24 from the
8066 stack. In 64-bit mode, they just have to start on an
8067 even word, since the parameter save area is 16-byte
8068 aligned. Space for GPRs is reserved even if the argument
8069 will be passed in memory. */
8071 align
= (2 - cum
->words
) & 3;
8073 align
= cum
->words
& 1;
8074 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
8076 if (TARGET_DEBUG_ARG
)
8078 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
8080 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
8081 cum
->nargs_prototype
, cum
->prototype
,
8082 GET_MODE_NAME (mode
));
8086 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
8088 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
8091 else if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
8093 int size
= int_size_in_bytes (type
);
8094 /* Variable sized types have size == -1 and are
8095 treated as if consisting entirely of ints.
8096 Pad to 16 byte boundary if needed. */
8097 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
8098 && (cum
->words
% 2) != 0)
8100 /* For varargs, we can just go up by the size of the struct. */
8102 cum
->words
+= (size
+ 7) / 8;
8105 /* It is tempting to say int register count just goes up by
8106 sizeof(type)/8, but this is wrong in a case such as
8107 { int; double; int; } [powerpc alignment]. We have to
8108 grovel through the fields for these too. */
8110 cum
->floats_in_gpr
= 0;
8111 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
8112 rs6000_darwin64_record_arg_advance_flush (cum
,
8113 size
* BITS_PER_UNIT
, 1);
8115 if (TARGET_DEBUG_ARG
)
8117 fprintf (stderr
, "function_adv: words = %2d, align=%d, size=%d",
8118 cum
->words
, TYPE_ALIGN (type
), size
);
8120 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8121 cum
->nargs_prototype
, cum
->prototype
,
8122 GET_MODE_NAME (mode
));
8125 else if (DEFAULT_ABI
== ABI_V4
)
8127 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
8128 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
8129 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
8130 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
8131 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
8133 /* _Decimal128 must use an even/odd register pair. This assumes
8134 that the register number is odd when fregno is odd. */
8135 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
8138 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
8139 <= FP_ARG_V4_MAX_REG
)
8140 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
8143 cum
->fregno
= FP_ARG_V4_MAX_REG
+ 1;
8144 if (mode
== DFmode
|| mode
== TFmode
8145 || mode
== DDmode
|| mode
== TDmode
)
8146 cum
->words
+= cum
->words
& 1;
8147 cum
->words
+= rs6000_arg_size (mode
, type
);
8152 int n_words
= rs6000_arg_size (mode
, type
);
8153 int gregno
= cum
->sysv_gregno
;
8155 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8156 (r7,r8) or (r9,r10). As does any other 2 word item such
8157 as complex int due to a historical mistake. */
8159 gregno
+= (1 - gregno
) & 1;
8161 /* Multi-reg args are not split between registers and stack. */
8162 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
8164 /* Long long and SPE vectors are aligned on the stack.
8165 So are other 2 word items such as complex int due to
8166 a historical mistake. */
8168 cum
->words
+= cum
->words
& 1;
8169 cum
->words
+= n_words
;
8172 /* Note: continuing to accumulate gregno past when we've started
8173 spilling to the stack indicates the fact that we've started
8174 spilling to the stack to expand_builtin_saveregs. */
8175 cum
->sysv_gregno
= gregno
+ n_words
;
8178 if (TARGET_DEBUG_ARG
)
8180 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
8181 cum
->words
, cum
->fregno
);
8182 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
8183 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
8184 fprintf (stderr
, "mode = %4s, named = %d\n",
8185 GET_MODE_NAME (mode
), named
);
8190 int n_words
= rs6000_arg_size (mode
, type
);
8191 int start_words
= cum
->words
;
8192 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
8194 cum
->words
= align_words
+ n_words
;
8196 if (SCALAR_FLOAT_MODE_P (mode
)
8197 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
8199 /* _Decimal128 must be passed in an even/odd float register pair.
8200 This assumes that the register number is odd when fregno is
8202 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
8204 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
8207 if (TARGET_DEBUG_ARG
)
8209 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
8210 cum
->words
, cum
->fregno
);
8211 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
8212 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
8213 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
8214 named
, align_words
- start_words
, depth
);
8220 rs6000_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8221 const_tree type
, bool named
)
8223 rs6000_function_arg_advance_1 (cum
, mode
, type
, named
, 0);
8227 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
8234 r1
= gen_rtx_REG (DImode
, gregno
);
8235 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
8236 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
8240 r1
= gen_rtx_REG (DImode
, gregno
);
8241 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
8242 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
8243 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
8244 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
8247 r1
= gen_rtx_REG (DImode
, gregno
);
8248 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
8249 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
8250 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
8251 r5
= gen_rtx_REG (DImode
, gregno
+ 4);
8252 r5
= gen_rtx_EXPR_LIST (VOIDmode
, r5
, GEN_INT (16));
8253 r7
= gen_rtx_REG (DImode
, gregno
+ 6);
8254 r7
= gen_rtx_EXPR_LIST (VOIDmode
, r7
, GEN_INT (24));
8255 return gen_rtx_PARALLEL (mode
, gen_rtvec (4, r1
, r3
, r5
, r7
));
8262 /* Determine where to put a SIMD argument on the SPE. */
8264 rs6000_spe_function_arg (const CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8267 int gregno
= cum
->sysv_gregno
;
8269 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8270 are passed and returned in a pair of GPRs for ABI compatibility. */
8271 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
8272 || mode
== DCmode
|| mode
== TCmode
))
8274 int n_words
= rs6000_arg_size (mode
, type
);
8276 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8278 gregno
+= (1 - gregno
) & 1;
8280 /* Multi-reg args are not split between registers and stack. */
8281 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
8284 return spe_build_register_parallel (mode
, gregno
);
8288 int n_words
= rs6000_arg_size (mode
, type
);
8290 /* SPE vectors are put in odd registers. */
8291 if (n_words
== 2 && (gregno
& 1) == 0)
8294 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
8297 enum machine_mode m
= SImode
;
8299 r1
= gen_rtx_REG (m
, gregno
);
8300 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
8301 r2
= gen_rtx_REG (m
, gregno
+ 1);
8302 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
8303 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
8310 if (gregno
<= GP_ARG_MAX_REG
)
8311 return gen_rtx_REG (mode
, gregno
);
8317 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8318 structure between cum->intoffset and bitpos to integer registers. */
8321 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
8322 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
8324 enum machine_mode mode
;
8326 unsigned int startbit
, endbit
;
8327 int this_regno
, intregs
, intoffset
;
8330 if (cum
->intoffset
== -1)
8333 intoffset
= cum
->intoffset
;
8334 cum
->intoffset
= -1;
8336 /* If this is the trailing part of a word, try to only load that
8337 much into the register. Otherwise load the whole register. Note
8338 that in the latter case we may pick up unwanted bits. It's not a
8339 problem at the moment but may wish to revisit. */
8341 if (intoffset
% BITS_PER_WORD
!= 0)
8343 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
8345 if (mode
== BLKmode
)
8347 /* We couldn't find an appropriate mode, which happens,
8348 e.g., in packed structs when there are 3 bytes to load.
8349 Back intoffset back to the beginning of the word in this
8351 intoffset
= intoffset
& -BITS_PER_WORD
;
8358 startbit
= intoffset
& -BITS_PER_WORD
;
8359 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
8360 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
8361 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
8363 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
8366 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
8370 intoffset
/= BITS_PER_UNIT
;
8373 regno
= GP_ARG_MIN_REG
+ this_regno
;
8374 reg
= gen_rtx_REG (mode
, regno
);
8376 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
8379 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
8383 while (intregs
> 0);
8386 /* Recursive workhorse for the following. */
8389 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, const_tree type
,
8390 HOST_WIDE_INT startbitpos
, rtx rvec
[],
8395 for (f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
8396 if (TREE_CODE (f
) == FIELD_DECL
)
8398 HOST_WIDE_INT bitpos
= startbitpos
;
8399 tree ftype
= TREE_TYPE (f
);
8400 enum machine_mode mode
;
8401 if (ftype
== error_mark_node
)
8403 mode
= TYPE_MODE (ftype
);
8405 if (DECL_SIZE (f
) != 0
8406 && host_integerp (bit_position (f
), 1))
8407 bitpos
+= int_bit_position (f
);
8409 /* ??? FIXME: else assume zero offset. */
8411 if (TREE_CODE (ftype
) == RECORD_TYPE
)
8412 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
8413 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
8418 case SCmode
: mode
= SFmode
; break;
8419 case DCmode
: mode
= DFmode
; break;
8420 case TCmode
: mode
= TFmode
; break;
8424 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
8426 = gen_rtx_EXPR_LIST (VOIDmode
,
8427 gen_rtx_REG (mode
, cum
->fregno
++),
8428 GEN_INT (bitpos
/ BITS_PER_UNIT
));
8429 if (mode
== TFmode
|| mode
== TDmode
)
8432 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
8434 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
8436 = gen_rtx_EXPR_LIST (VOIDmode
,
8437 gen_rtx_REG (mode
, cum
->vregno
++),
8438 GEN_INT (bitpos
/ BITS_PER_UNIT
));
8440 else if (cum
->intoffset
== -1)
8441 cum
->intoffset
= bitpos
;
8445 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8446 the register(s) to be used for each field and subfield of a struct
8447 being passed by value, along with the offset of where the
8448 register's value may be found in the block. FP fields go in FP
8449 register, vector fields go in vector registers, and everything
8450 else goes in int registers, packed as in memory.
8452 This code is also used for function return values. RETVAL indicates
8453 whether this is the case.
8455 Much of this is taken from the SPARC V9 port, which has a similar
8456 calling convention. */
8459 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, const_tree type
,
8460 bool named
, bool retval
)
8462 rtx rvec
[FIRST_PSEUDO_REGISTER
];
8463 int k
= 1, kbase
= 1;
8464 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
8465 /* This is a copy; modifications are not visible to our caller. */
8466 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
8467 CUMULATIVE_ARGS
*cum
= ©_cum
;
8469 /* Pad to 16 byte boundary if needed. */
8470 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
8471 && (cum
->words
% 2) != 0)
8478 /* Put entries into rvec[] for individual FP and vector fields, and
8479 for the chunks of memory that go in int regs. Note we start at
8480 element 1; 0 is reserved for an indication of using memory, and
8481 may or may not be filled in below. */
8482 rs6000_darwin64_record_arg_recurse (cum
, type
, 0, rvec
, &k
);
8483 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
8485 /* If any part of the struct went on the stack put all of it there.
8486 This hack is because the generic code for
8487 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8488 parts of the struct are not at the beginning. */
8492 return NULL_RTX
; /* doesn't go in registers at all */
8494 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
8496 if (k
> 1 || cum
->use_stack
)
8497 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
8502 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8505 rs6000_mixed_function_arg (enum machine_mode mode
, const_tree type
,
8510 rtx rvec
[GP_ARG_NUM_REG
+ 1];
8512 if (align_words
>= GP_ARG_NUM_REG
)
8515 n_units
= rs6000_arg_size (mode
, type
);
8517 /* Optimize the simple case where the arg fits in one gpr, except in
8518 the case of BLKmode due to assign_parms assuming that registers are
8519 BITS_PER_WORD wide. */
8521 || (n_units
== 1 && mode
!= BLKmode
))
8522 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
8525 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
8526 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8527 using a magic NULL_RTX component.
8528 This is not strictly correct. Only some of the arg belongs in
8529 memory, not all of it. However, the normal scheme using
8530 function_arg_partial_nregs can result in unusual subregs, eg.
8531 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8532 store the whole arg to memory is often more efficient than code
8533 to store pieces, and we know that space is available in the right
8534 place for the whole arg. */
8535 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
8540 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
8541 rtx off
= GEN_INT (i
++ * 4);
8542 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
8544 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
8546 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
8549 /* Determine where to put an argument to a function.
8550 Value is zero to push the argument on the stack,
8551 or a hard register in which to store the argument.
8553 MODE is the argument's machine mode.
8554 TYPE is the data type of the argument (as a tree).
8555 This is null for libcalls where that information may
8557 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8558 the preceding args and about the function being called. It is
8559 not modified in this routine.
8560 NAMED is nonzero if this argument is a named parameter
8561 (otherwise it is an extra parameter matching an ellipsis).
8563 On RS/6000 the first eight words of non-FP are normally in registers
8564 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8565 Under V.4, the first 8 FP args are in registers.
8567 If this is floating-point and no prototype is specified, we use
8568 both an FP and integer register (or possibly FP reg and stack). Library
8569 functions (when CALL_LIBCALL is set) always have the proper types for args,
8570 so we can pass the FP value just in one register. emit_library_function
8571 doesn't support PARALLEL anyway.
8573 Note that for args passed by reference, function_arg will be called
8574 with MODE and TYPE set to that of the pointer to the arg, not the arg
8578 rs6000_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8579 const_tree type
, bool named
)
8581 enum rs6000_abi abi
= DEFAULT_ABI
;
8583 /* Return a marker to indicate whether CR1 needs to set or clear the
8584 bit that V.4 uses to say fp args were passed in registers.
8585 Assume that we don't need the marker for software floating point,
8586 or compiler generated library calls. */
8587 if (mode
== VOIDmode
)
8590 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
8592 || (cum
->nargs_prototype
< 0
8593 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))))
8595 /* For the SPE, we need to crxor CR6 always. */
8597 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
8598 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
8599 return GEN_INT (cum
->call_cookie
8600 | ((cum
->fregno
== FP_ARG_MIN_REG
)
8601 ? CALL_V4_SET_FP_ARGS
8602 : CALL_V4_CLEAR_FP_ARGS
));
8605 return GEN_INT (cum
->call_cookie
);
8608 if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
8610 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, false);
8611 if (rslt
!= NULL_RTX
)
8613 /* Else fall through to usual handling. */
8616 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
8617 if (TARGET_64BIT
&& ! cum
->prototype
)
8619 /* Vector parameters get passed in vector register
8620 and also in GPRs or memory, in absence of prototype. */
8623 align_words
= (cum
->words
+ 1) & ~1;
8625 if (align_words
>= GP_ARG_NUM_REG
)
8631 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
8633 return gen_rtx_PARALLEL (mode
,
8635 gen_rtx_EXPR_LIST (VOIDmode
,
8637 gen_rtx_EXPR_LIST (VOIDmode
,
8638 gen_rtx_REG (mode
, cum
->vregno
),
8642 return gen_rtx_REG (mode
, cum
->vregno
);
8643 else if (TARGET_ALTIVEC_ABI
8644 && (ALTIVEC_VECTOR_MODE (mode
)
8645 || VSX_VECTOR_MODE (mode
)
8646 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
8647 && int_size_in_bytes (type
) == 16)))
8649 if (named
|| abi
== ABI_V4
)
8653 /* Vector parameters to varargs functions under AIX or Darwin
8654 get passed in memory and possibly also in GPRs. */
8655 int align
, align_words
, n_words
;
8656 enum machine_mode part_mode
;
8658 /* Vector parameters must be 16-byte aligned. This places them at
8659 2 mod 4 in terms of words in 32-bit mode, since the parameter
8660 save area starts at offset 24 from the stack. In 64-bit mode,
8661 they just have to start on an even word, since the parameter
8662 save area is 16-byte aligned. */
8664 align
= (2 - cum
->words
) & 3;
8666 align
= cum
->words
& 1;
8667 align_words
= cum
->words
+ align
;
8669 /* Out of registers? Memory, then. */
8670 if (align_words
>= GP_ARG_NUM_REG
)
8673 if (TARGET_32BIT
&& TARGET_POWERPC64
)
8674 return rs6000_mixed_function_arg (mode
, type
, align_words
);
8676 /* The vector value goes in GPRs. Only the part of the
8677 value in GPRs is reported here. */
8679 n_words
= rs6000_arg_size (mode
, type
);
8680 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
8681 /* Fortunately, there are only two possibilities, the value
8682 is either wholly in GPRs or half in GPRs and half not. */
8685 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
8688 else if (TARGET_SPE_ABI
&& TARGET_SPE
8689 && (SPE_VECTOR_MODE (mode
)
8690 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
8693 || mode
== TCmode
))))
8694 return rs6000_spe_function_arg (cum
, mode
, type
);
8696 else if (abi
== ABI_V4
)
8698 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
8699 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
8700 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
8701 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
8702 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
8704 /* _Decimal128 must use an even/odd register pair. This assumes
8705 that the register number is odd when fregno is odd. */
8706 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
8709 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
8710 <= FP_ARG_V4_MAX_REG
)
8711 return gen_rtx_REG (mode
, cum
->fregno
);
8717 int n_words
= rs6000_arg_size (mode
, type
);
8718 int gregno
= cum
->sysv_gregno
;
8720 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8721 (r7,r8) or (r9,r10). As does any other 2 word item such
8722 as complex int due to a historical mistake. */
8724 gregno
+= (1 - gregno
) & 1;
8726 /* Multi-reg args are not split between registers and stack. */
8727 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
8730 if (TARGET_32BIT
&& TARGET_POWERPC64
)
8731 return rs6000_mixed_function_arg (mode
, type
,
8732 gregno
- GP_ARG_MIN_REG
);
8733 return gen_rtx_REG (mode
, gregno
);
8738 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
8740 /* _Decimal128 must be passed in an even/odd float register pair.
8741 This assumes that the register number is odd when fregno is odd. */
8742 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
8745 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
8747 rtx rvec
[GP_ARG_NUM_REG
+ 1];
8751 enum machine_mode fmode
= mode
;
8752 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
8754 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
8756 /* Currently, we only ever need one reg here because complex
8757 doubles are split. */
8758 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
8759 && (fmode
== TFmode
|| fmode
== TDmode
));
8761 /* Long double or _Decimal128 split over regs and memory. */
8762 fmode
= DECIMAL_FLOAT_MODE_P (fmode
) ? DDmode
: DFmode
;
8765 /* Do we also need to pass this arg in the parameter save
8768 && (cum
->nargs_prototype
<= 0
8769 || (DEFAULT_ABI
== ABI_AIX
8771 && align_words
>= GP_ARG_NUM_REG
)));
8773 if (!needs_psave
&& mode
== fmode
)
8774 return gen_rtx_REG (fmode
, cum
->fregno
);
8779 /* Describe the part that goes in gprs or the stack.
8780 This piece must come first, before the fprs. */
8781 if (align_words
< GP_ARG_NUM_REG
)
8783 unsigned long n_words
= rs6000_arg_size (mode
, type
);
8785 if (align_words
+ n_words
> GP_ARG_NUM_REG
8786 || (TARGET_32BIT
&& TARGET_POWERPC64
))
8788 /* If this is partially on the stack, then we only
8789 include the portion actually in registers here. */
8790 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
8793 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
8794 /* Not all of the arg fits in gprs. Say that it
8795 goes in memory too, using a magic NULL_RTX
8796 component. Also see comment in
8797 rs6000_mixed_function_arg for why the normal
8798 function_arg_partial_nregs scheme doesn't work
8800 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
8804 r
= gen_rtx_REG (rmode
,
8805 GP_ARG_MIN_REG
+ align_words
);
8806 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
8807 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
8809 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
8813 /* The whole arg fits in gprs. */
8814 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
8815 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
8819 /* It's entirely in memory. */
8820 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
8823 /* Describe where this piece goes in the fprs. */
8824 r
= gen_rtx_REG (fmode
, cum
->fregno
);
8825 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
8827 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
8829 else if (align_words
< GP_ARG_NUM_REG
)
8831 if (TARGET_32BIT
&& TARGET_POWERPC64
)
8832 return rs6000_mixed_function_arg (mode
, type
, align_words
);
8834 if (mode
== BLKmode
)
8837 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
8844 /* For an arg passed partly in registers and partly in memory, this is
8845 the number of bytes passed in registers. For args passed entirely in
8846 registers or entirely in memory, zero. When an arg is described by a
8847 PARALLEL, perhaps using more than one register type, this function
8848 returns the number of bytes used by the first element of the PARALLEL. */
8851 rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8852 tree type
, bool named
)
8857 if (DEFAULT_ABI
== ABI_V4
)
8860 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
8861 && cum
->nargs_prototype
>= 0)
8864 /* In this complicated case we just disable the partial_nregs code. */
8865 if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
8868 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
8870 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
8872 /* If we are passing this arg in the fixed parameter save area
8873 (gprs or memory) as well as fprs, then this function should
8874 return the number of partial bytes passed in the parameter
8875 save area rather than partial bytes passed in fprs. */
8877 && (cum
->nargs_prototype
<= 0
8878 || (DEFAULT_ABI
== ABI_AIX
8880 && align_words
>= GP_ARG_NUM_REG
)))
8882 else if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3)
8883 > FP_ARG_MAX_REG
+ 1)
8884 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
8885 else if (cum
->nargs_prototype
>= 0)
8889 if (align_words
< GP_ARG_NUM_REG
8890 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
8891 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
8893 if (ret
!= 0 && TARGET_DEBUG_ARG
)
8894 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
8899 /* A C expression that indicates when an argument must be passed by
8900 reference. If nonzero for an argument, a copy of that argument is
8901 made in memory and a pointer to the argument is passed instead of
8902 the argument itself. The pointer is passed in whatever way is
8903 appropriate for passing a pointer to that type.
8905 Under V.4, aggregates and long double are passed by reference.
8907 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8908 reference unless the AltiVec vector extension ABI is in force.
8910 As an extension to all ABIs, variable sized types are passed by
8914 rs6000_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
8915 enum machine_mode mode
, const_tree type
,
8916 bool named ATTRIBUTE_UNUSED
)
8918 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& mode
== TFmode
)
8920 if (TARGET_DEBUG_ARG
)
8921 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
8928 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
8930 if (TARGET_DEBUG_ARG
)
8931 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
8935 if (int_size_in_bytes (type
) < 0)
8937 if (TARGET_DEBUG_ARG
)
8938 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
8942 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8943 modes only exist for GCC vector types if -maltivec. */
8944 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
8946 if (TARGET_DEBUG_ARG
)
8947 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
8951 /* Pass synthetic vectors in memory. */
8952 if (TREE_CODE (type
) == VECTOR_TYPE
8953 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
8955 static bool warned_for_pass_big_vectors
= false;
8956 if (TARGET_DEBUG_ARG
)
8957 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
8958 if (!warned_for_pass_big_vectors
)
8960 warning (0, "GCC vector passed by reference: "
8961 "non-standard ABI extension with no compatibility guarantee");
8962 warned_for_pass_big_vectors
= true;
8971 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
8974 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
8979 for (i
= 0; i
< nregs
; i
++)
8981 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
8982 if (reload_completed
)
8984 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
8987 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
8988 i
* GET_MODE_SIZE (reg_mode
));
8991 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
8995 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
8999 /* Perform any needed actions needed for a function that is receiving a
9000 variable number of arguments.
9004 MODE and TYPE are the mode and type of the current parameter.
9006 PRETEND_SIZE is a variable that should be set to the amount of stack
9007 that must be pushed by the prolog to pretend that our caller pushed
9010 Normally, this macro will push all remaining incoming registers on the
9011 stack and set PRETEND_SIZE to the length of the registers pushed. */
9014 setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
9015 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
9018 CUMULATIVE_ARGS next_cum
;
9019 int reg_size
= TARGET_32BIT
? 4 : 8;
9020 rtx save_area
= NULL_RTX
, mem
;
9021 int first_reg_offset
;
9024 /* Skip the last named argument. */
9026 rs6000_function_arg_advance_1 (&next_cum
, mode
, type
, true, 0);
9028 if (DEFAULT_ABI
== ABI_V4
)
9030 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
9034 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
9035 HOST_WIDE_INT offset
= 0;
9037 /* Try to optimize the size of the varargs save area.
9038 The ABI requires that ap.reg_save_area is doubleword
9039 aligned, but we don't need to allocate space for all
9040 the bytes, only those to which we actually will save
9042 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
9043 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
9044 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
9045 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
9046 && cfun
->va_list_fpr_size
)
9049 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
9050 * UNITS_PER_FP_WORD
;
9051 if (cfun
->va_list_fpr_size
9052 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
9053 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
9055 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
9056 * UNITS_PER_FP_WORD
;
9060 offset
= -((first_reg_offset
* reg_size
) & ~7);
9061 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
9063 gpr_reg_num
= cfun
->va_list_gpr_size
;
9064 if (reg_size
== 4 && (first_reg_offset
& 1))
9067 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
9070 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
9072 - (int) (GP_ARG_NUM_REG
* reg_size
);
9074 if (gpr_size
+ fpr_size
)
9077 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
9078 gcc_assert (GET_CODE (reg_save_area
) == MEM
);
9079 reg_save_area
= XEXP (reg_save_area
, 0);
9080 if (GET_CODE (reg_save_area
) == PLUS
)
9082 gcc_assert (XEXP (reg_save_area
, 0)
9083 == virtual_stack_vars_rtx
);
9084 gcc_assert (GET_CODE (XEXP (reg_save_area
, 1)) == CONST_INT
);
9085 offset
+= INTVAL (XEXP (reg_save_area
, 1));
9088 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
9091 cfun
->machine
->varargs_save_offset
= offset
;
9092 save_area
= plus_constant (virtual_stack_vars_rtx
, offset
);
9097 first_reg_offset
= next_cum
.words
;
9098 save_area
= virtual_incoming_args_rtx
;
9100 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
9101 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
9104 set
= get_varargs_alias_set ();
9105 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
9106 && cfun
->va_list_gpr_size
)
9108 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
9110 if (va_list_gpr_counter_field
)
9112 /* V4 va_list_gpr_size counts number of registers needed. */
9113 if (nregs
> cfun
->va_list_gpr_size
)
9114 nregs
= cfun
->va_list_gpr_size
;
9118 /* char * va_list instead counts number of bytes needed. */
9119 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
9120 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
9123 mem
= gen_rtx_MEM (BLKmode
,
9124 plus_constant (save_area
,
9125 first_reg_offset
* reg_size
));
9126 MEM_NOTRAP_P (mem
) = 1;
9127 set_mem_alias_set (mem
, set
);
9128 set_mem_align (mem
, BITS_PER_WORD
);
9130 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
9134 /* Save FP registers if needed. */
9135 if (DEFAULT_ABI
== ABI_V4
9136 && TARGET_HARD_FLOAT
&& TARGET_FPRS
9138 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
9139 && cfun
->va_list_fpr_size
)
9141 int fregno
= next_cum
.fregno
, nregs
;
9142 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
9143 rtx lab
= gen_label_rtx ();
9144 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
9145 * UNITS_PER_FP_WORD
);
9148 (gen_rtx_SET (VOIDmode
,
9150 gen_rtx_IF_THEN_ELSE (VOIDmode
,
9151 gen_rtx_NE (VOIDmode
, cr1
,
9153 gen_rtx_LABEL_REF (VOIDmode
, lab
),
9157 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
9158 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
9160 mem
= gen_rtx_MEM ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
9162 plus_constant (save_area
, off
));
9163 MEM_NOTRAP_P (mem
) = 1;
9164 set_mem_alias_set (mem
, set
);
9165 set_mem_align (mem
, GET_MODE_ALIGNMENT (
9166 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
9167 ? DFmode
: SFmode
));
9168 emit_move_insn (mem
, gen_rtx_REG (
9169 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
9170 ? DFmode
: SFmode
, fregno
));
9177 /* Create the va_list data type. */
9180 rs6000_build_builtin_va_list (void)
9182 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
9184 /* For AIX, prefer 'char *' because that's what the system
9185 header files like. */
9186 if (DEFAULT_ABI
!= ABI_V4
)
9187 return build_pointer_type (char_type_node
);
9189 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
9190 type_decl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
9191 get_identifier ("__va_list_tag"), record
);
9193 f_gpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("gpr"),
9194 unsigned_char_type_node
);
9195 f_fpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("fpr"),
9196 unsigned_char_type_node
);
9197 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9199 f_res
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
9200 get_identifier ("reserved"), short_unsigned_type_node
);
9201 f_ovf
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
9202 get_identifier ("overflow_arg_area"),
9204 f_sav
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
9205 get_identifier ("reg_save_area"),
9208 va_list_gpr_counter_field
= f_gpr
;
9209 va_list_fpr_counter_field
= f_fpr
;
9211 DECL_FIELD_CONTEXT (f_gpr
) = record
;
9212 DECL_FIELD_CONTEXT (f_fpr
) = record
;
9213 DECL_FIELD_CONTEXT (f_res
) = record
;
9214 DECL_FIELD_CONTEXT (f_ovf
) = record
;
9215 DECL_FIELD_CONTEXT (f_sav
) = record
;
9217 TREE_CHAIN (record
) = type_decl
;
9218 TYPE_NAME (record
) = type_decl
;
9219 TYPE_FIELDS (record
) = f_gpr
;
9220 DECL_CHAIN (f_gpr
) = f_fpr
;
9221 DECL_CHAIN (f_fpr
) = f_res
;
9222 DECL_CHAIN (f_res
) = f_ovf
;
9223 DECL_CHAIN (f_ovf
) = f_sav
;
9225 layout_type (record
);
9227 /* The correct type is an array type of one element. */
9228 return build_array_type (record
, build_index_type (size_zero_node
));
9231 /* Implement va_start. */
9234 rs6000_va_start (tree valist
, rtx nextarg
)
9236 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
9237 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
9238 tree gpr
, fpr
, ovf
, sav
, t
;
9240 /* Only SVR4 needs something special. */
9241 if (DEFAULT_ABI
!= ABI_V4
)
9243 std_expand_builtin_va_start (valist
, nextarg
);
9247 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
9248 f_fpr
= DECL_CHAIN (f_gpr
);
9249 f_res
= DECL_CHAIN (f_fpr
);
9250 f_ovf
= DECL_CHAIN (f_res
);
9251 f_sav
= DECL_CHAIN (f_ovf
);
9253 valist
= build_va_arg_indirect_ref (valist
);
9254 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
9255 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
9257 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
9259 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
9262 /* Count number of gp and fp argument registers used. */
9263 words
= crtl
->args
.info
.words
;
9264 n_gpr
= MIN (crtl
->args
.info
.sysv_gregno
- GP_ARG_MIN_REG
,
9266 n_fpr
= MIN (crtl
->args
.info
.fregno
- FP_ARG_MIN_REG
,
9269 if (TARGET_DEBUG_ARG
)
9270 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
9271 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
9272 words
, n_gpr
, n_fpr
);
9274 if (cfun
->va_list_gpr_size
)
9276 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
9277 build_int_cst (NULL_TREE
, n_gpr
));
9278 TREE_SIDE_EFFECTS (t
) = 1;
9279 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9282 if (cfun
->va_list_fpr_size
)
9284 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
9285 build_int_cst (NULL_TREE
, n_fpr
));
9286 TREE_SIDE_EFFECTS (t
) = 1;
9287 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9290 /* Find the overflow area. */
9291 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
9293 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ovf
), t
,
9294 size_int (words
* UNITS_PER_WORD
));
9295 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
9296 TREE_SIDE_EFFECTS (t
) = 1;
9297 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9299 /* If there were no va_arg invocations, don't set up the register
9301 if (!cfun
->va_list_gpr_size
9302 && !cfun
->va_list_fpr_size
9303 && n_gpr
< GP_ARG_NUM_REG
9304 && n_fpr
< FP_ARG_V4_MAX_REG
)
9307 /* Find the register save area. */
9308 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
9309 if (cfun
->machine
->varargs_save_offset
)
9310 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (sav
), t
,
9311 size_int (cfun
->machine
->varargs_save_offset
));
9312 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
9313 TREE_SIDE_EFFECTS (t
) = 1;
9314 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9317 /* Implement va_arg. */
9320 rs6000_gimplify_va_arg (tree valist
, tree type
, gimple_seq
*pre_p
,
9323 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
9324 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
9325 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
9326 tree lab_false
, lab_over
, addr
;
9328 tree ptrtype
= build_pointer_type_for_mode (type
, ptr_mode
, true);
9332 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
9334 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
9335 return build_va_arg_indirect_ref (t
);
9338 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9339 earlier version of gcc, with the property that it always applied alignment
9340 adjustments to the va-args (even for zero-sized types). The cheapest way
9341 to deal with this is to replicate the effect of the part of
9342 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9344 We don't need to check for pass-by-reference because of the test above.
9345 We can return a simplifed answer, since we know there's no offset to add. */
9348 && rs6000_darwin64_abi
9349 && integer_zerop (TYPE_SIZE (type
)))
9351 unsigned HOST_WIDE_INT align
, boundary
;
9352 tree valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
9353 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
9354 boundary
= FUNCTION_ARG_BOUNDARY (TYPE_MODE (type
), type
);
9355 if (boundary
> MAX_SUPPORTED_STACK_ALIGNMENT
)
9356 boundary
= MAX_SUPPORTED_STACK_ALIGNMENT
;
9357 boundary
/= BITS_PER_UNIT
;
9358 if (boundary
> align
)
9361 /* This updates arg ptr by the amount that would be necessary
9362 to align the zero-sized (but not zero-alignment) item. */
9363 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
9364 fold_build2 (POINTER_PLUS_EXPR
,
9366 valist_tmp
, size_int (boundary
- 1)));
9367 gimplify_and_add (t
, pre_p
);
9369 t
= fold_convert (sizetype
, valist_tmp
);
9370 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
9371 fold_convert (TREE_TYPE (valist
),
9372 fold_build2 (BIT_AND_EXPR
, sizetype
, t
,
9373 size_int (-boundary
))));
9374 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
9375 gimplify_and_add (t
, pre_p
);
9377 /* Since it is zero-sized there's no increment for the item itself. */
9378 valist_tmp
= fold_convert (build_pointer_type (type
), valist_tmp
);
9379 return build_va_arg_indirect_ref (valist_tmp
);
9382 if (DEFAULT_ABI
!= ABI_V4
)
9384 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
9386 tree elem_type
= TREE_TYPE (type
);
9387 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
9388 int elem_size
= GET_MODE_SIZE (elem_mode
);
9390 if (elem_size
< UNITS_PER_WORD
)
9392 tree real_part
, imag_part
;
9393 gimple_seq post
= NULL
;
9395 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
9397 /* Copy the value into a temporary, lest the formal temporary
9398 be reused out from under us. */
9399 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
9400 gimple_seq_add_seq (pre_p
, post
);
9402 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
9405 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
9409 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
9412 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
9413 f_fpr
= DECL_CHAIN (f_gpr
);
9414 f_res
= DECL_CHAIN (f_fpr
);
9415 f_ovf
= DECL_CHAIN (f_res
);
9416 f_sav
= DECL_CHAIN (f_ovf
);
9418 valist
= build_va_arg_indirect_ref (valist
);
9419 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
9420 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
9422 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
9424 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
9427 size
= int_size_in_bytes (type
);
9428 rsize
= (size
+ 3) / 4;
9431 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
9432 && ((TARGET_SINGLE_FLOAT
&& TYPE_MODE (type
) == SFmode
)
9433 || (TARGET_DOUBLE_FLOAT
9434 && (TYPE_MODE (type
) == DFmode
9435 || TYPE_MODE (type
) == TFmode
9436 || TYPE_MODE (type
) == SDmode
9437 || TYPE_MODE (type
) == DDmode
9438 || TYPE_MODE (type
) == TDmode
))))
9440 /* FP args go in FP registers, if present. */
9442 n_reg
= (size
+ 7) / 8;
9443 sav_ofs
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4) * 4;
9444 sav_scale
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4);
9445 if (TYPE_MODE (type
) != SFmode
&& TYPE_MODE (type
) != SDmode
)
9450 /* Otherwise into GP registers. */
9459 /* Pull the value out of the saved registers.... */
9462 addr
= create_tmp_var (ptr_type_node
, "addr");
9464 /* AltiVec vectors never go in registers when -mabi=altivec. */
9465 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
9469 lab_false
= create_artificial_label (input_location
);
9470 lab_over
= create_artificial_label (input_location
);
9472 /* Long long and SPE vectors are aligned in the registers.
9473 As are any other 2 gpr item such as complex int due to a
9474 historical mistake. */
9476 if (n_reg
== 2 && reg
== gpr
)
9479 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
9480 build_int_cst (TREE_TYPE (reg
), n_reg
- 1));
9481 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
),
9482 unshare_expr (reg
), u
);
9484 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9485 reg number is 0 for f1, so we want to make it odd. */
9486 else if (reg
== fpr
&& TYPE_MODE (type
) == TDmode
)
9488 t
= build2 (BIT_IOR_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
9489 build_int_cst (TREE_TYPE (reg
), 1));
9490 u
= build2 (MODIFY_EXPR
, void_type_node
, unshare_expr (reg
), t
);
9493 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
9494 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
9495 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
9496 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
9497 gimplify_and_add (t
, pre_p
);
9501 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, sav
, size_int (sav_ofs
));
9503 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
9504 build_int_cst (TREE_TYPE (reg
), n_reg
));
9505 u
= fold_convert (sizetype
, u
);
9506 u
= build2 (MULT_EXPR
, sizetype
, u
, size_int (sav_scale
));
9507 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
, u
);
9509 /* _Decimal32 varargs are located in the second word of the 64-bit
9510 FP register for 32-bit binaries. */
9511 if (!TARGET_POWERPC64
9512 && TARGET_HARD_FLOAT
&& TARGET_FPRS
9513 && TYPE_MODE (type
) == SDmode
)
9514 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
9516 gimplify_assign (addr
, t
, pre_p
);
9518 gimple_seq_add_stmt (pre_p
, gimple_build_goto (lab_over
));
9520 stmt
= gimple_build_label (lab_false
);
9521 gimple_seq_add_stmt (pre_p
, stmt
);
9523 if ((n_reg
== 2 && !regalign
) || n_reg
> 2)
9525 /* Ensure that we don't find any more args in regs.
9526 Alignment has taken care of for special cases. */
9527 gimplify_assign (reg
, build_int_cst (TREE_TYPE (reg
), 8), pre_p
);
9531 /* ... otherwise out of the overflow area. */
9533 /* Care for on-stack alignment if needed. */
9537 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (align
- 1));
9538 t
= fold_convert (sizetype
, t
);
9539 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
9541 t
= fold_convert (TREE_TYPE (ovf
), t
);
9543 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
9545 gimplify_assign (unshare_expr (addr
), t
, pre_p
);
9547 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
9548 gimplify_assign (unshare_expr (ovf
), t
, pre_p
);
9552 stmt
= gimple_build_label (lab_over
);
9553 gimple_seq_add_stmt (pre_p
, stmt
);
9556 if (STRICT_ALIGNMENT
9557 && (TYPE_ALIGN (type
)
9558 > (unsigned) BITS_PER_UNIT
* (align
< 4 ? 4 : align
)))
9560 /* The value (of type complex double, for example) may not be
9561 aligned in memory in the saved registers, so copy via a
9562 temporary. (This is the same code as used for SPARC.) */
9563 tree tmp
= create_tmp_var (type
, "va_arg_tmp");
9564 tree dest_addr
= build_fold_addr_expr (tmp
);
9566 tree copy
= build_call_expr (implicit_built_in_decls
[BUILT_IN_MEMCPY
],
9567 3, dest_addr
, addr
, size_int (rsize
* 4));
9569 gimplify_and_add (copy
, pre_p
);
9573 addr
= fold_convert (ptrtype
, addr
);
9574 return build_va_arg_indirect_ref (addr
);
9580 def_builtin (int mask
, const char *name
, tree type
, int code
)
9582 if ((mask
& target_flags
) || TARGET_PAIRED_FLOAT
)
9585 if (rs6000_builtin_decls
[code
])
9586 fatal_error ("internal error: builtin function to %s already processed.",
9589 rs6000_builtin_decls
[code
] = t
=
9590 add_builtin_function (name
, type
, code
, BUILT_IN_MD
,
9593 gcc_assert (code
>= 0 && code
< (int)RS6000_BUILTIN_COUNT
);
9594 switch (builtin_classify
[code
])
9599 /* assume builtin can do anything. */
9600 case RS6000_BTC_MISC
:
9603 /* const function, function only depends on the inputs. */
9604 case RS6000_BTC_CONST
:
9605 TREE_READONLY (t
) = 1;
9606 TREE_NOTHROW (t
) = 1;
9609 /* pure function, function can read global memory. */
9610 case RS6000_BTC_PURE
:
9611 DECL_PURE_P (t
) = 1;
9612 TREE_NOTHROW (t
) = 1;
9615 /* Function is a math function. If rounding mode is on, then treat
9616 the function as not reading global memory, but it can have
9617 arbitrary side effects. If it is off, then assume the function is
9618 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9619 attribute in builtin-attribute.def that is used for the math
9621 case RS6000_BTC_FP_PURE
:
9622 TREE_NOTHROW (t
) = 1;
9623 if (flag_rounding_math
)
9625 DECL_PURE_P (t
) = 1;
9626 DECL_IS_NOVOPS (t
) = 1;
9629 TREE_READONLY (t
) = 1;
9635 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9637 static const struct builtin_description bdesc_3arg
[] =
9639 { MASK_ALTIVEC
, CODE_FOR_altivec_vmaddfp
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
9640 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
9641 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
9642 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
9643 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
9644 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
9645 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
9646 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
9647 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
9648 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
9649 { MASK_ALTIVEC
, CODE_FOR_altivec_vnmsubfp
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
9650 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2df
, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF
},
9651 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2di
, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI
},
9652 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
9653 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
9654 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
9655 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
9656 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2di_uns
, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS
},
9657 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si_uns
, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS
},
9658 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi_uns
, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS
},
9659 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS
},
9660 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
9661 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
9662 { MASK_ALTIVEC
, CODE_FOR_vector_select_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
9663 { MASK_ALTIVEC
, CODE_FOR_vector_select_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
9664 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2df
, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF
},
9665 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2di
, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI
},
9666 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4si_uns
, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS
},
9667 { MASK_ALTIVEC
, CODE_FOR_vector_select_v8hi_uns
, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS
},
9668 { MASK_ALTIVEC
, CODE_FOR_vector_select_v16qi_uns
, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS
},
9669 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2di_uns
, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS
},
9670 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
9671 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
9672 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
9673 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
9675 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
9676 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
9677 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
9678 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
9679 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
9680 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
9681 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
9682 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
9683 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
9684 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
9685 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
9686 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
9687 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
9688 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
9689 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
9691 { MASK_VSX
, CODE_FOR_vsx_fmaddv2df4
, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP
},
9692 { MASK_VSX
, CODE_FOR_vsx_fmsubv2df4
, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP
},
9693 { MASK_VSX
, CODE_FOR_vsx_fnmaddv2df4
, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP
},
9694 { MASK_VSX
, CODE_FOR_vsx_fnmsubv2df4
, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP
},
9696 { MASK_VSX
, CODE_FOR_vsx_fmaddv4sf4
, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP
},
9697 { MASK_VSX
, CODE_FOR_vsx_fmsubv4sf4
, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP
},
9698 { MASK_VSX
, CODE_FOR_vsx_fnmaddv4sf4
, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP
},
9699 { MASK_VSX
, CODE_FOR_vsx_fnmsubv4sf4
, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP
},
9701 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB
},
9702 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD
},
9704 { MASK_VSX
, CODE_FOR_vector_select_v2di
, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI
},
9705 { MASK_VSX
, CODE_FOR_vector_select_v2df
, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF
},
9706 { MASK_VSX
, CODE_FOR_vector_select_v4sf
, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF
},
9707 { MASK_VSX
, CODE_FOR_vector_select_v4si
, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI
},
9708 { MASK_VSX
, CODE_FOR_vector_select_v8hi
, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI
},
9709 { MASK_VSX
, CODE_FOR_vector_select_v16qi
, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI
},
9710 { MASK_VSX
, CODE_FOR_vector_select_v2di_uns
, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS
},
9711 { MASK_VSX
, CODE_FOR_vector_select_v4si_uns
, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS
},
9712 { MASK_VSX
, CODE_FOR_vector_select_v8hi_uns
, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS
},
9713 { MASK_VSX
, CODE_FOR_vector_select_v16qi_uns
, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS
},
9715 { MASK_VSX
, CODE_FOR_altivec_vperm_v2di
, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI
},
9716 { MASK_VSX
, CODE_FOR_altivec_vperm_v2df
, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF
},
9717 { MASK_VSX
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF
},
9718 { MASK_VSX
, CODE_FOR_altivec_vperm_v4si
, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI
},
9719 { MASK_VSX
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI
},
9720 { MASK_VSX
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI
},
9721 { MASK_VSX
, CODE_FOR_altivec_vperm_v2di_uns
, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS
},
9722 { MASK_VSX
, CODE_FOR_altivec_vperm_v4si_uns
, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS
},
9723 { MASK_VSX
, CODE_FOR_altivec_vperm_v8hi_uns
, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS
},
9724 { MASK_VSX
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS
},
9726 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v2df
, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF
},
9727 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v2di
, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI
},
9728 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v4sf
, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF
},
9729 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v4si
, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI
},
9730 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v8hi
, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI
},
9731 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v16qi
, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI
},
9732 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI
},
9733 { MASK_VSX
, CODE_FOR_vsx_set_v2df
, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF
},
9734 { MASK_VSX
, CODE_FOR_vsx_set_v2di
, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI
},
9736 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v2di
, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI
},
9737 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v2df
, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF
},
9738 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v4sf
, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF
},
9739 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v4si
, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI
},
9740 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v8hi
, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI
},
9741 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v16qi
, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI
},
9742 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI
},
9744 { 0, CODE_FOR_paired_msub
, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB
},
9745 { 0, CODE_FOR_paired_madd
, "__builtin_paired_madd", PAIRED_BUILTIN_MADD
},
9746 { 0, CODE_FOR_paired_madds0
, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0
},
9747 { 0, CODE_FOR_paired_madds1
, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1
},
9748 { 0, CODE_FOR_paired_nmsub
, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB
},
9749 { 0, CODE_FOR_paired_nmadd
, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD
},
9750 { 0, CODE_FOR_paired_sum0
, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0
},
9751 { 0, CODE_FOR_paired_sum1
, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1
},
9752 { 0, CODE_FOR_selv2sf4
, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4
},
9755 /* DST operations: void foo (void *, const int, const char). */
9757 static const struct builtin_description bdesc_dst
[] =
9759 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
9760 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
9761 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
9762 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
9764 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
9765 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
9766 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
9767 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
9770 /* Simple binary operations: VECc = foo (VECa, VECb). */
9772 static struct builtin_description bdesc_2arg
[] =
9774 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
9775 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
9776 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
9777 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
9778 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
9779 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
9780 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
9781 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
9782 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
9783 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
9784 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
9785 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
9786 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
9787 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
9788 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
9789 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
9790 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
9791 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
9792 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
9793 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
9794 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
9795 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
9796 { MASK_ALTIVEC
, CODE_FOR_vector_eqv16qi
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
9797 { MASK_ALTIVEC
, CODE_FOR_vector_eqv8hi
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
9798 { MASK_ALTIVEC
, CODE_FOR_vector_eqv4si
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
9799 { MASK_ALTIVEC
, CODE_FOR_vector_eqv4sf
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
9800 { MASK_ALTIVEC
, CODE_FOR_vector_gev4sf
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
9801 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv16qi
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
9802 { MASK_ALTIVEC
, CODE_FOR_vector_gtv16qi
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
9803 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv8hi
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
9804 { MASK_ALTIVEC
, CODE_FOR_vector_gtv8hi
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
9805 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv4si
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
9806 { MASK_ALTIVEC
, CODE_FOR_vector_gtv4si
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
9807 { MASK_ALTIVEC
, CODE_FOR_vector_gtv4sf
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
9808 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
9809 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
9810 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
9811 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
9812 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
9813 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
9814 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
9815 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
9816 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
9817 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
9818 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
9819 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
9820 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
9821 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
9822 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
9823 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
9824 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
9825 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
9826 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
9827 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
9828 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
9829 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
9830 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
9831 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS
},
9832 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
9833 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
9834 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS
},
9835 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
9836 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
9837 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS
},
9838 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
9839 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
9840 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS
},
9841 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
9842 { MASK_ALTIVEC
, CODE_FOR_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
9843 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
9844 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
9845 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
9846 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
9847 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
9848 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
9849 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
9850 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
9851 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
9852 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
9853 { MASK_ALTIVEC
, CODE_FOR_recipv4sf3
, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP
},
9854 { MASK_ALTIVEC
, CODE_FOR_vrotlv16qi3
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
9855 { MASK_ALTIVEC
, CODE_FOR_vrotlv8hi3
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
9856 { MASK_ALTIVEC
, CODE_FOR_vrotlv4si3
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
9857 { MASK_ALTIVEC
, CODE_FOR_vashlv16qi3
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
9858 { MASK_ALTIVEC
, CODE_FOR_vashlv8hi3
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
9859 { MASK_ALTIVEC
, CODE_FOR_vashlv4si3
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
9860 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
9861 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
9862 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
9863 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
9864 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
9865 { MASK_ALTIVEC
, CODE_FOR_vlshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
9866 { MASK_ALTIVEC
, CODE_FOR_vlshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
9867 { MASK_ALTIVEC
, CODE_FOR_vlshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
9868 { MASK_ALTIVEC
, CODE_FOR_vashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
9869 { MASK_ALTIVEC
, CODE_FOR_vashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
9870 { MASK_ALTIVEC
, CODE_FOR_vashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
9871 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
9872 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
9873 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
9874 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
9875 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
9876 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
9877 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
9878 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
9879 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
9880 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
9881 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
9882 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
9883 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
9884 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
9885 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
9886 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
9887 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
9888 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
9889 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
9890 { MASK_ALTIVEC
, CODE_FOR_vector_copysignv4sf3
, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF
},
9892 { MASK_VSX
, CODE_FOR_addv2df3
, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP
},
9893 { MASK_VSX
, CODE_FOR_subv2df3
, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP
},
9894 { MASK_VSX
, CODE_FOR_mulv2df3
, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP
},
9895 { MASK_VSX
, CODE_FOR_divv2df3
, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP
},
9896 { MASK_VSX
, CODE_FOR_recipv2df3
, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF
},
9897 { MASK_VSX
, CODE_FOR_sminv2df3
, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP
},
9898 { MASK_VSX
, CODE_FOR_smaxv2df3
, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP
},
9899 { MASK_VSX
, CODE_FOR_vsx_tdivv2df3_fe
, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE
},
9900 { MASK_VSX
, CODE_FOR_vsx_tdivv2df3_fg
, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG
},
9901 { MASK_VSX
, CODE_FOR_vector_eqv2df
, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP
},
9902 { MASK_VSX
, CODE_FOR_vector_gtv2df
, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP
},
9903 { MASK_VSX
, CODE_FOR_vector_gev2df
, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP
},
9905 { MASK_VSX
, CODE_FOR_addv4sf3
, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP
},
9906 { MASK_VSX
, CODE_FOR_subv4sf3
, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP
},
9907 { MASK_VSX
, CODE_FOR_mulv4sf3
, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP
},
9908 { MASK_VSX
, CODE_FOR_divv4sf3
, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP
},
9909 { MASK_VSX
, CODE_FOR_recipv4sf3
, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF
},
9910 { MASK_VSX
, CODE_FOR_sminv4sf3
, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP
},
9911 { MASK_VSX
, CODE_FOR_smaxv4sf3
, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP
},
9912 { MASK_VSX
, CODE_FOR_vsx_tdivv4sf3_fe
, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE
},
9913 { MASK_VSX
, CODE_FOR_vsx_tdivv4sf3_fg
, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG
},
9914 { MASK_VSX
, CODE_FOR_vector_eqv4sf
, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP
},
9915 { MASK_VSX
, CODE_FOR_vector_gtv4sf
, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP
},
9916 { MASK_VSX
, CODE_FOR_vector_gev4sf
, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP
},
9918 { MASK_VSX
, CODE_FOR_smindf3
, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP
},
9919 { MASK_VSX
, CODE_FOR_smaxdf3
, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP
},
9920 { MASK_VSX
, CODE_FOR_vsx_tdivdf3_fe
, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE
},
9921 { MASK_VSX
, CODE_FOR_vsx_tdivdf3_fg
, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG
},
9922 { MASK_VSX
, CODE_FOR_vector_copysignv2df3
, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP
},
9923 { MASK_VSX
, CODE_FOR_vector_copysignv4sf3
, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP
},
9925 { MASK_VSX
, CODE_FOR_vsx_concat_v2df
, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF
},
9926 { MASK_VSX
, CODE_FOR_vsx_concat_v2di
, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI
},
9927 { MASK_VSX
, CODE_FOR_vsx_splat_v2df
, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF
},
9928 { MASK_VSX
, CODE_FOR_vsx_splat_v2di
, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI
},
9929 { MASK_VSX
, CODE_FOR_vsx_xxmrghw_v4sf
, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF
},
9930 { MASK_VSX
, CODE_FOR_vsx_xxmrghw_v4si
, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI
},
9931 { MASK_VSX
, CODE_FOR_vsx_xxmrglw_v4sf
, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF
},
9932 { MASK_VSX
, CODE_FOR_vsx_xxmrglw_v4si
, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI
},
9933 { MASK_VSX
, CODE_FOR_vec_interleave_lowv2df
, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF
},
9934 { MASK_VSX
, CODE_FOR_vec_interleave_lowv2di
, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI
},
9935 { MASK_VSX
, CODE_FOR_vec_interleave_highv2df
, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF
},
9936 { MASK_VSX
, CODE_FOR_vec_interleave_highv2di
, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI
},
9938 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
9939 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
9940 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
9941 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
9942 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
9943 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
9944 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
9945 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
9946 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
9947 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
9948 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
9949 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
9950 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
9951 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
9952 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
9953 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
9954 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
9955 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
9956 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
9957 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
9958 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
9959 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
9960 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
9961 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
9962 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
9963 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
9964 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
9965 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
9966 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
9967 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
9968 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
9969 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
9970 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
9971 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
9972 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
9973 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
9974 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
9975 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
9976 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
9977 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN
},
9978 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
9979 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
9980 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
9981 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
9982 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
9983 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
9984 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
9985 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
9986 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
9987 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
9988 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
9989 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
9990 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
9991 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
9992 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
9993 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
9994 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
9995 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
9996 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
9997 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
9998 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
9999 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
10000 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
10001 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
10002 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
10003 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
10004 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
10005 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
10006 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
10007 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
10008 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
10009 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
10010 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
10011 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
10012 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
10013 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
10014 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
10015 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
10016 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
10017 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
10018 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
10019 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
10020 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
10021 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
10022 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
10023 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
10024 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
10025 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
10026 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP
},
10027 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
10028 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
10029 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
10030 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
10031 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
10032 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
10033 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
10034 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
10035 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
10036 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
10037 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
10038 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
10039 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
10040 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
10041 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
10042 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
10043 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
10044 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
10045 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
10046 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
10047 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
10048 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
10049 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
10050 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
10051 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
10052 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
10053 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
10054 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
10055 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
10056 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
10057 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
10058 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
10059 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
10060 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
10061 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
10062 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
10063 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
10064 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
10065 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
10066 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
10068 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL
},
10069 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV
},
10071 { 0, CODE_FOR_paired_divv2sf3
, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3
},
10072 { 0, CODE_FOR_paired_addv2sf3
, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3
},
10073 { 0, CODE_FOR_paired_subv2sf3
, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3
},
10074 { 0, CODE_FOR_paired_mulv2sf3
, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3
},
10075 { 0, CODE_FOR_paired_muls0
, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0
},
10076 { 0, CODE_FOR_paired_muls1
, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1
},
10077 { 0, CODE_FOR_paired_merge00
, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00
},
10078 { 0, CODE_FOR_paired_merge01
, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01
},
10079 { 0, CODE_FOR_paired_merge10
, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10
},
10080 { 0, CODE_FOR_paired_merge11
, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11
},
10082 /* Place holder, leave as first spe builtin. */
10083 { 0, CODE_FOR_addv2si3
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
10084 { 0, CODE_FOR_andv2si3
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
10085 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
10086 { 0, CODE_FOR_divv2si3
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
10087 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
10088 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
10089 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
10090 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
10091 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
10092 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
10093 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
10094 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
10095 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
10096 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
10097 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
10098 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
10099 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
10100 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
10101 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
10102 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
10103 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
10104 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
10105 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
10106 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
10107 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
10108 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
10109 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
10110 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
10111 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
10112 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
10113 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
10114 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
10115 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
10116 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
10117 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
10118 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
10119 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
10120 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
10121 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
10122 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
10123 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
10124 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
10125 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
10126 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
10127 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
10128 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
10129 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
10130 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
10131 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
10132 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
10133 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
10134 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
10135 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
10136 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
10137 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
10138 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
10139 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
10140 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
10141 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
10142 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
10143 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
10144 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
10145 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
10146 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
10147 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
10148 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
10149 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
10150 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
10151 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
10152 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
10153 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
10154 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
10155 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
10156 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
10157 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
10158 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
10159 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
10160 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
10161 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
10162 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
10163 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
10164 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
10165 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
10166 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
10167 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
10168 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
10169 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
10170 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
10171 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
10172 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
10173 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
10174 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
10175 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
10176 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
10177 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
10178 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
10179 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
10180 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
10181 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
10182 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
10183 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
10184 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
10185 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
10186 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
10187 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
10188 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
10189 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
10190 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
10191 { 0, CODE_FOR_subv2si3
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
10193 /* SPE binary operations expecting a 5-bit unsigned literal. */
10194 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
10196 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
10197 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
10198 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
10199 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
10200 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
10201 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
10202 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
10203 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
10204 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
10205 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
10206 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
10207 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
10208 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
10209 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
10210 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
10211 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
10212 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
10213 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
10214 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
10215 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
10216 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
10217 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
10218 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
10219 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
10220 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
10221 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
10223 /* Place-holder. Leave as last binary SPE builtin. */
10224 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
10227 /* AltiVec predicates. */
10229 struct builtin_description_predicates
10231 const unsigned int mask
;
10232 const enum insn_code icode
;
10233 const char *const name
;
10234 const enum rs6000_builtins code
;
10237 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
10239 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp_p
, "__builtin_altivec_vcmpbfp_p",
10240 ALTIVEC_BUILTIN_VCMPBFP_P
},
10241 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_eq_v4sf_p
,
10242 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
10243 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_ge_v4sf_p
,
10244 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
10245 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_gt_v4sf_p
,
10246 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
10247 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v4si_p
, "__builtin_altivec_vcmpequw_p",
10248 ALTIVEC_BUILTIN_VCMPEQUW_P
},
10249 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v4si_p
, "__builtin_altivec_vcmpgtsw_p",
10250 ALTIVEC_BUILTIN_VCMPGTSW_P
},
10251 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v4si_p
, "__builtin_altivec_vcmpgtuw_p",
10252 ALTIVEC_BUILTIN_VCMPGTUW_P
},
10253 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v8hi_p
, "__builtin_altivec_vcmpequh_p",
10254 ALTIVEC_BUILTIN_VCMPEQUH_P
},
10255 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v8hi_p
, "__builtin_altivec_vcmpgtsh_p",
10256 ALTIVEC_BUILTIN_VCMPGTSH_P
},
10257 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v8hi_p
, "__builtin_altivec_vcmpgtuh_p",
10258 ALTIVEC_BUILTIN_VCMPGTUH_P
},
10259 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v16qi_p
, "__builtin_altivec_vcmpequb_p",
10260 ALTIVEC_BUILTIN_VCMPEQUB_P
},
10261 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v16qi_p
, "__builtin_altivec_vcmpgtsb_p",
10262 ALTIVEC_BUILTIN_VCMPGTSB_P
},
10263 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v16qi_p
, "__builtin_altivec_vcmpgtub_p",
10264 ALTIVEC_BUILTIN_VCMPGTUB_P
},
10266 { MASK_VSX
, CODE_FOR_vector_eq_v4sf_p
, "__builtin_vsx_xvcmpeqsp_p",
10267 VSX_BUILTIN_XVCMPEQSP_P
},
10268 { MASK_VSX
, CODE_FOR_vector_ge_v4sf_p
, "__builtin_vsx_xvcmpgesp_p",
10269 VSX_BUILTIN_XVCMPGESP_P
},
10270 { MASK_VSX
, CODE_FOR_vector_gt_v4sf_p
, "__builtin_vsx_xvcmpgtsp_p",
10271 VSX_BUILTIN_XVCMPGTSP_P
},
10272 { MASK_VSX
, CODE_FOR_vector_eq_v2df_p
, "__builtin_vsx_xvcmpeqdp_p",
10273 VSX_BUILTIN_XVCMPEQDP_P
},
10274 { MASK_VSX
, CODE_FOR_vector_ge_v2df_p
, "__builtin_vsx_xvcmpgedp_p",
10275 VSX_BUILTIN_XVCMPGEDP_P
},
10276 { MASK_VSX
, CODE_FOR_vector_gt_v2df_p
, "__builtin_vsx_xvcmpgtdp_p",
10277 VSX_BUILTIN_XVCMPGTDP_P
},
10279 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpeq_p",
10280 ALTIVEC_BUILTIN_VCMPEQ_P
},
10281 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpgt_p",
10282 ALTIVEC_BUILTIN_VCMPGT_P
},
10283 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpge_p",
10284 ALTIVEC_BUILTIN_VCMPGE_P
}
10287 /* SPE predicates. */
10288 static struct builtin_description bdesc_spe_predicates
[] =
10290 /* Place-holder. Leave as first. */
10291 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
10292 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
10293 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
10294 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
10295 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
10296 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
10297 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
10298 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
10299 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
10300 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
10301 /* Place-holder. Leave as last. */
10302 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
10305 /* SPE evsel predicates. */
10306 static struct builtin_description bdesc_spe_evsel
[] =
10308 /* Place-holder. Leave as first. */
10309 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
10310 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
10311 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
10312 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
10313 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
10314 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
10315 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
10316 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
10317 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
10318 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
10319 /* Place-holder. Leave as last. */
10320 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
10323 /* PAIRED predicates. */
10324 static const struct builtin_description bdesc_paired_preds
[] =
10326 /* Place-holder. Leave as first. */
10327 { 0, CODE_FOR_paired_cmpu0
, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0
},
10328 /* Place-holder. Leave as last. */
10329 { 0, CODE_FOR_paired_cmpu1
, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1
},
10332 /* ABS* operations. */
10334 static const struct builtin_description bdesc_abs
[] =
10336 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
10337 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
10338 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
10339 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
10340 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
10341 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
10342 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
},
10343 { MASK_VSX
, CODE_FOR_absv2df2
, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP
},
10344 { MASK_VSX
, CODE_FOR_vsx_nabsv2df2
, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP
},
10345 { MASK_VSX
, CODE_FOR_absv4sf2
, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP
},
10346 { MASK_VSX
, CODE_FOR_vsx_nabsv4sf2
, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP
},
10349 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10352 static struct builtin_description bdesc_1arg
[] =
10354 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
10355 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
10356 { MASK_ALTIVEC
, CODE_FOR_rev4sf2
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
10357 { MASK_ALTIVEC
, CODE_FOR_vector_floorv4sf2
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
10358 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
10359 { MASK_ALTIVEC
, CODE_FOR_vector_ceilv4sf2
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
10360 { MASK_ALTIVEC
, CODE_FOR_vector_btruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
10361 { MASK_ALTIVEC
, CODE_FOR_rsqrtv4sf2
, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP
},
10362 { MASK_ALTIVEC
, CODE_FOR_rsqrtev4sf2
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
10363 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
10364 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
10365 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
10366 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
10367 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
10368 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
10369 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
10370 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
10371 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
10373 { MASK_VSX
, CODE_FOR_negv2df2
, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP
},
10374 { MASK_VSX
, CODE_FOR_sqrtv2df2
, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP
},
10375 { MASK_VSX
, CODE_FOR_rsqrtv2df2
, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF
},
10376 { MASK_VSX
, CODE_FOR_rsqrtev2df2
, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP
},
10377 { MASK_VSX
, CODE_FOR_vsx_tsqrtv2df2_fe
, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE
},
10378 { MASK_VSX
, CODE_FOR_vsx_tsqrtv2df2_fg
, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG
},
10379 { MASK_VSX
, CODE_FOR_vsx_frev2df2
, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP
},
10381 { MASK_VSX
, CODE_FOR_negv4sf2
, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP
},
10382 { MASK_VSX
, CODE_FOR_sqrtv4sf2
, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP
},
10383 { MASK_VSX
, CODE_FOR_rsqrtv4sf2
, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF
},
10384 { MASK_VSX
, CODE_FOR_rsqrtev4sf2
, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP
},
10385 { MASK_VSX
, CODE_FOR_vsx_tsqrtv4sf2_fe
, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE
},
10386 { MASK_VSX
, CODE_FOR_vsx_tsqrtv4sf2_fg
, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG
},
10387 { MASK_VSX
, CODE_FOR_vsx_frev4sf2
, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP
},
10389 { MASK_VSX
, CODE_FOR_vsx_xscvdpsp
, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP
},
10390 { MASK_VSX
, CODE_FOR_vsx_xscvdpsp
, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP
},
10391 { MASK_VSX
, CODE_FOR_vsx_xvcvdpsp
, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP
},
10392 { MASK_VSX
, CODE_FOR_vsx_xvcvspdp
, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP
},
10393 { MASK_VSX
, CODE_FOR_vsx_tsqrtdf2_fe
, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE
},
10394 { MASK_VSX
, CODE_FOR_vsx_tsqrtdf2_fg
, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG
},
10396 { MASK_VSX
, CODE_FOR_vsx_fix_truncv2dfv2di2
, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS
},
10397 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv2dfv2di2
, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS
},
10398 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv2dfv2di2
, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS
},
10399 { MASK_VSX
, CODE_FOR_vsx_floatv2div2df2
, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP
},
10400 { MASK_VSX
, CODE_FOR_vsx_floatunsv2div2df2
, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP
},
10401 { MASK_VSX
, CODE_FOR_vsx_floatunsv2div2df2
, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS
},
10403 { MASK_VSX
, CODE_FOR_vsx_fix_truncv4sfv4si2
, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS
},
10404 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv4sfv4si2
, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS
},
10405 { MASK_VSX
, CODE_FOR_vsx_floatv4siv4sf2
, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP
},
10406 { MASK_VSX
, CODE_FOR_vsx_floatunsv4siv4sf2
, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP
},
10408 { MASK_VSX
, CODE_FOR_vsx_xvcvdpsxws
, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS
},
10409 { MASK_VSX
, CODE_FOR_vsx_xvcvdpuxws
, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS
},
10410 { MASK_VSX
, CODE_FOR_vsx_xvcvsxwdp
, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP
},
10411 { MASK_VSX
, CODE_FOR_vsx_xvcvuxwdp
, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP
},
10412 { MASK_VSX
, CODE_FOR_vsx_xvrdpi
, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI
},
10413 { MASK_VSX
, CODE_FOR_vsx_xvrdpic
, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC
},
10414 { MASK_VSX
, CODE_FOR_vsx_floorv2df2
, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM
},
10415 { MASK_VSX
, CODE_FOR_vsx_ceilv2df2
, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP
},
10416 { MASK_VSX
, CODE_FOR_vsx_btruncv2df2
, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ
},
10418 { MASK_VSX
, CODE_FOR_vsx_xvcvspsxds
, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS
},
10419 { MASK_VSX
, CODE_FOR_vsx_xvcvspuxds
, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS
},
10420 { MASK_VSX
, CODE_FOR_vsx_xvcvsxdsp
, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP
},
10421 { MASK_VSX
, CODE_FOR_vsx_xvcvuxdsp
, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP
},
10422 { MASK_VSX
, CODE_FOR_vsx_xvrspi
, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI
},
10423 { MASK_VSX
, CODE_FOR_vsx_xvrspic
, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC
},
10424 { MASK_VSX
, CODE_FOR_vsx_floorv4sf2
, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM
},
10425 { MASK_VSX
, CODE_FOR_vsx_ceilv4sf2
, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP
},
10426 { MASK_VSX
, CODE_FOR_vsx_btruncv4sf2
, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ
},
10428 { MASK_VSX
, CODE_FOR_vsx_xsrdpi
, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI
},
10429 { MASK_VSX
, CODE_FOR_vsx_xsrdpic
, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC
},
10430 { MASK_VSX
, CODE_FOR_vsx_floordf2
, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM
},
10431 { MASK_VSX
, CODE_FOR_vsx_ceildf2
, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP
},
10432 { MASK_VSX
, CODE_FOR_vsx_btruncdf2
, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ
},
10434 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
10435 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
10436 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
10437 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
10438 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
10439 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
10440 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
10441 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
10442 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
10443 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT
},
10444 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
10445 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
10446 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
10447 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
10448 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
10449 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
10450 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
10451 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
10452 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
10453 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
10455 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT
},
10456 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT
},
10457 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT
},
10459 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_floatv4siv4sf2
, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF
},
10460 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_unsigned_floatv4siv4sf2
, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
},
10461 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_fix_truncv4sfv4si2
, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI
},
10462 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_fixuns_truncv4sfv4si2
, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
},
10464 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10465 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10466 { 0, CODE_FOR_absv2si2
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
10467 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
10468 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
10469 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
10470 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
10471 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
10472 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
10473 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
10474 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
10475 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
10476 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
10477 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
10478 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
10479 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
10480 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
10481 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
10482 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
10483 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
10484 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
10485 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
10486 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
10487 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
10488 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
10489 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
10490 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
10491 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
10492 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
10493 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
10495 /* Place-holder. Leave as last unary SPE builtin. */
10496 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
},
10498 { 0, CODE_FOR_paired_absv2sf2
, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2
},
10499 { 0, CODE_FOR_nabsv2sf2
, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2
},
10500 { 0, CODE_FOR_paired_negv2sf2
, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2
},
10501 { 0, CODE_FOR_sqrtv2sf2
, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2
},
10502 { 0, CODE_FOR_resv2sf2
, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2
}
10506 rs6000_expand_unop_builtin (enum insn_code icode
, tree exp
, rtx target
)
10509 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10510 rtx op0
= expand_normal (arg0
);
10511 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10512 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10514 if (icode
== CODE_FOR_nothing
)
10515 /* Builtin not supported on this processor. */
10518 /* If we got invalid arguments bail out before generating bad rtl. */
10519 if (arg0
== error_mark_node
)
10522 if (icode
== CODE_FOR_altivec_vspltisb
10523 || icode
== CODE_FOR_altivec_vspltish
10524 || icode
== CODE_FOR_altivec_vspltisw
10525 || icode
== CODE_FOR_spe_evsplatfi
10526 || icode
== CODE_FOR_spe_evsplati
)
10528 /* Only allow 5-bit *signed* literals. */
10529 if (GET_CODE (op0
) != CONST_INT
10530 || INTVAL (op0
) > 15
10531 || INTVAL (op0
) < -16)
10533 error ("argument 1 must be a 5-bit signed literal");
10539 || GET_MODE (target
) != tmode
10540 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10541 target
= gen_reg_rtx (tmode
);
10543 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10544 op0
= copy_to_mode_reg (mode0
, op0
);
10546 pat
= GEN_FCN (icode
) (target
, op0
);
10555 altivec_expand_abs_builtin (enum insn_code icode
, tree exp
, rtx target
)
10557 rtx pat
, scratch1
, scratch2
;
10558 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10559 rtx op0
= expand_normal (arg0
);
10560 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10561 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10563 /* If we have invalid arguments, bail out before generating bad rtl. */
10564 if (arg0
== error_mark_node
)
10568 || GET_MODE (target
) != tmode
10569 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10570 target
= gen_reg_rtx (tmode
);
10572 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10573 op0
= copy_to_mode_reg (mode0
, op0
);
10575 scratch1
= gen_reg_rtx (mode0
);
10576 scratch2
= gen_reg_rtx (mode0
);
10578 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
10587 rs6000_expand_binop_builtin (enum insn_code icode
, tree exp
, rtx target
)
10590 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10591 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10592 rtx op0
= expand_normal (arg0
);
10593 rtx op1
= expand_normal (arg1
);
10594 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10595 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10596 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
10598 if (icode
== CODE_FOR_nothing
)
10599 /* Builtin not supported on this processor. */
10602 /* If we got invalid arguments bail out before generating bad rtl. */
10603 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10606 if (icode
== CODE_FOR_altivec_vcfux
10607 || icode
== CODE_FOR_altivec_vcfsx
10608 || icode
== CODE_FOR_altivec_vctsxs
10609 || icode
== CODE_FOR_altivec_vctuxs
10610 || icode
== CODE_FOR_altivec_vspltb
10611 || icode
== CODE_FOR_altivec_vsplth
10612 || icode
== CODE_FOR_altivec_vspltw
10613 || icode
== CODE_FOR_spe_evaddiw
10614 || icode
== CODE_FOR_spe_evldd
10615 || icode
== CODE_FOR_spe_evldh
10616 || icode
== CODE_FOR_spe_evldw
10617 || icode
== CODE_FOR_spe_evlhhesplat
10618 || icode
== CODE_FOR_spe_evlhhossplat
10619 || icode
== CODE_FOR_spe_evlhhousplat
10620 || icode
== CODE_FOR_spe_evlwhe
10621 || icode
== CODE_FOR_spe_evlwhos
10622 || icode
== CODE_FOR_spe_evlwhou
10623 || icode
== CODE_FOR_spe_evlwhsplat
10624 || icode
== CODE_FOR_spe_evlwwsplat
10625 || icode
== CODE_FOR_spe_evrlwi
10626 || icode
== CODE_FOR_spe_evslwi
10627 || icode
== CODE_FOR_spe_evsrwis
10628 || icode
== CODE_FOR_spe_evsubifw
10629 || icode
== CODE_FOR_spe_evsrwiu
)
10631 /* Only allow 5-bit unsigned literals. */
10633 if (TREE_CODE (arg1
) != INTEGER_CST
10634 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
10636 error ("argument 2 must be a 5-bit unsigned literal");
10642 || GET_MODE (target
) != tmode
10643 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10644 target
= gen_reg_rtx (tmode
);
10646 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10647 op0
= copy_to_mode_reg (mode0
, op0
);
10648 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10649 op1
= copy_to_mode_reg (mode1
, op1
);
10651 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
10660 altivec_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
10663 tree cr6_form
= CALL_EXPR_ARG (exp
, 0);
10664 tree arg0
= CALL_EXPR_ARG (exp
, 1);
10665 tree arg1
= CALL_EXPR_ARG (exp
, 2);
10666 rtx op0
= expand_normal (arg0
);
10667 rtx op1
= expand_normal (arg1
);
10668 enum machine_mode tmode
= SImode
;
10669 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10670 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
10673 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
10675 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10679 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
10681 gcc_assert (mode0
== mode1
);
10683 /* If we have invalid arguments, bail out before generating bad rtl. */
10684 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10688 || GET_MODE (target
) != tmode
10689 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10690 target
= gen_reg_rtx (tmode
);
10692 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10693 op0
= copy_to_mode_reg (mode0
, op0
);
10694 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10695 op1
= copy_to_mode_reg (mode1
, op1
);
10697 scratch
= gen_reg_rtx (mode0
);
10699 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
10704 /* The vec_any* and vec_all* predicates use the same opcodes for two
10705 different operations, but the bits in CR6 will be different
10706 depending on what information we want. So we have to play tricks
10707 with CR6 to get the right bits out.
10709 If you think this is disgusting, look at the specs for the
10710 AltiVec predicates. */
10712 switch (cr6_form_int
)
10715 emit_insn (gen_cr6_test_for_zero (target
));
10718 emit_insn (gen_cr6_test_for_zero_reverse (target
));
10721 emit_insn (gen_cr6_test_for_lt (target
));
10724 emit_insn (gen_cr6_test_for_lt_reverse (target
));
10727 error ("argument 1 of __builtin_altivec_predicate is out of range");
10735 paired_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
)
10738 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10739 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10740 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10741 enum machine_mode mode0
= Pmode
;
10742 enum machine_mode mode1
= Pmode
;
10743 rtx op0
= expand_normal (arg0
);
10744 rtx op1
= expand_normal (arg1
);
10746 if (icode
== CODE_FOR_nothing
)
10747 /* Builtin not supported on this processor. */
10750 /* If we got invalid arguments bail out before generating bad rtl. */
10751 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10755 || GET_MODE (target
) != tmode
10756 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10757 target
= gen_reg_rtx (tmode
);
10759 op1
= copy_to_mode_reg (mode1
, op1
);
10761 if (op0
== const0_rtx
)
10763 addr
= gen_rtx_MEM (tmode
, op1
);
10767 op0
= copy_to_mode_reg (mode0
, op0
);
10768 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
10771 pat
= GEN_FCN (icode
) (target
, addr
);
10781 altivec_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
, bool blk
)
10784 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10785 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10786 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10787 enum machine_mode mode0
= Pmode
;
10788 enum machine_mode mode1
= Pmode
;
10789 rtx op0
= expand_normal (arg0
);
10790 rtx op1
= expand_normal (arg1
);
10792 if (icode
== CODE_FOR_nothing
)
10793 /* Builtin not supported on this processor. */
10796 /* If we got invalid arguments bail out before generating bad rtl. */
10797 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10801 || GET_MODE (target
) != tmode
10802 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10803 target
= gen_reg_rtx (tmode
);
10805 op1
= copy_to_mode_reg (mode1
, op1
);
10807 if (op0
== const0_rtx
)
10809 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, op1
);
10813 op0
= copy_to_mode_reg (mode0
, op0
);
10814 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
10817 pat
= GEN_FCN (icode
) (target
, addr
);
10827 spe_expand_stv_builtin (enum insn_code icode
, tree exp
)
10829 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10830 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10831 tree arg2
= CALL_EXPR_ARG (exp
, 2);
10832 rtx op0
= expand_normal (arg0
);
10833 rtx op1
= expand_normal (arg1
);
10834 rtx op2
= expand_normal (arg2
);
10836 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
10837 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
10838 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
10840 /* Invalid arguments. Bail before doing anything stoopid! */
10841 if (arg0
== error_mark_node
10842 || arg1
== error_mark_node
10843 || arg2
== error_mark_node
)
10846 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
10847 op0
= copy_to_mode_reg (mode2
, op0
);
10848 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
10849 op1
= copy_to_mode_reg (mode0
, op1
);
10850 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
10851 op2
= copy_to_mode_reg (mode1
, op2
);
10853 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
10860 paired_expand_stv_builtin (enum insn_code icode
, tree exp
)
10862 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10863 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10864 tree arg2
= CALL_EXPR_ARG (exp
, 2);
10865 rtx op0
= expand_normal (arg0
);
10866 rtx op1
= expand_normal (arg1
);
10867 rtx op2
= expand_normal (arg2
);
10869 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10870 enum machine_mode mode1
= Pmode
;
10871 enum machine_mode mode2
= Pmode
;
10873 /* Invalid arguments. Bail before doing anything stoopid! */
10874 if (arg0
== error_mark_node
10875 || arg1
== error_mark_node
10876 || arg2
== error_mark_node
)
10879 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
10880 op0
= copy_to_mode_reg (tmode
, op0
);
10882 op2
= copy_to_mode_reg (mode2
, op2
);
10884 if (op1
== const0_rtx
)
10886 addr
= gen_rtx_MEM (tmode
, op2
);
10890 op1
= copy_to_mode_reg (mode1
, op1
);
10891 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
10894 pat
= GEN_FCN (icode
) (addr
, op0
);
10901 altivec_expand_stv_builtin (enum insn_code icode
, tree exp
)
10903 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10904 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10905 tree arg2
= CALL_EXPR_ARG (exp
, 2);
10906 rtx op0
= expand_normal (arg0
);
10907 rtx op1
= expand_normal (arg1
);
10908 rtx op2
= expand_normal (arg2
);
10910 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10911 enum machine_mode mode1
= Pmode
;
10912 enum machine_mode mode2
= Pmode
;
10914 /* Invalid arguments. Bail before doing anything stoopid! */
10915 if (arg0
== error_mark_node
10916 || arg1
== error_mark_node
10917 || arg2
== error_mark_node
)
10920 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
10921 op0
= copy_to_mode_reg (tmode
, op0
);
10923 op2
= copy_to_mode_reg (mode2
, op2
);
10925 if (op1
== const0_rtx
)
10927 addr
= gen_rtx_MEM (tmode
, op2
);
10931 op1
= copy_to_mode_reg (mode1
, op1
);
10932 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
10935 pat
= GEN_FCN (icode
) (addr
, op0
);
10942 rs6000_expand_ternop_builtin (enum insn_code icode
, tree exp
, rtx target
)
10945 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10946 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10947 tree arg2
= CALL_EXPR_ARG (exp
, 2);
10948 rtx op0
= expand_normal (arg0
);
10949 rtx op1
= expand_normal (arg1
);
10950 rtx op2
= expand_normal (arg2
);
10951 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10952 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10953 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
10954 enum machine_mode mode2
= insn_data
[icode
].operand
[3].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
10962 || arg1
== error_mark_node
10963 || arg2
== error_mark_node
)
10966 /* Check and prepare argument depending on the instruction code.
10968 Note that a switch statement instead of the sequence of tests
10969 would be incorrect as many of the CODE_FOR values could be
10970 CODE_FOR_nothing and that would yield multiple alternatives
10971 with identical values. We'd never reach here at runtime in
10973 if (icode
== CODE_FOR_altivec_vsldoi_v4sf
10974 || icode
== CODE_FOR_altivec_vsldoi_v4si
10975 || icode
== CODE_FOR_altivec_vsldoi_v8hi
10976 || icode
== CODE_FOR_altivec_vsldoi_v16qi
)
10978 /* Only allow 4-bit unsigned literals. */
10980 if (TREE_CODE (arg2
) != INTEGER_CST
10981 || TREE_INT_CST_LOW (arg2
) & ~0xf)
10983 error ("argument 3 must be a 4-bit unsigned literal");
10987 else if (icode
== CODE_FOR_vsx_xxpermdi_v2df
10988 || icode
== CODE_FOR_vsx_xxpermdi_v2di
10989 || icode
== CODE_FOR_vsx_xxsldwi_v16qi
10990 || icode
== CODE_FOR_vsx_xxsldwi_v8hi
10991 || icode
== CODE_FOR_vsx_xxsldwi_v4si
10992 || icode
== CODE_FOR_vsx_xxsldwi_v4sf
10993 || icode
== CODE_FOR_vsx_xxsldwi_v2di
10994 || icode
== CODE_FOR_vsx_xxsldwi_v2df
)
10996 /* Only allow 2-bit unsigned literals. */
10998 if (TREE_CODE (arg2
) != INTEGER_CST
10999 || TREE_INT_CST_LOW (arg2
) & ~0x3)
11001 error ("argument 3 must be a 2-bit unsigned literal");
11005 else if (icode
== CODE_FOR_vsx_set_v2df
11006 || icode
== CODE_FOR_vsx_set_v2di
)
11008 /* Only allow 1-bit unsigned literals. */
11010 if (TREE_CODE (arg2
) != INTEGER_CST
11011 || TREE_INT_CST_LOW (arg2
) & ~0x1)
11013 error ("argument 3 must be a 1-bit unsigned literal");
11019 || GET_MODE (target
) != tmode
11020 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11021 target
= gen_reg_rtx (tmode
);
11023 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11024 op0
= copy_to_mode_reg (mode0
, op0
);
11025 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
11026 op1
= copy_to_mode_reg (mode1
, op1
);
11027 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
11028 op2
= copy_to_mode_reg (mode2
, op2
);
11030 if (TARGET_PAIRED_FLOAT
&& icode
== CODE_FOR_selv2sf4
)
11031 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
, CONST0_RTX (SFmode
));
11033 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
11041 /* Expand the lvx builtins. */
11043 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
11045 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11046 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11048 enum machine_mode tmode
, mode0
;
11050 enum insn_code icode
;
11054 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
11055 icode
= CODE_FOR_vector_load_v16qi
;
11057 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
11058 icode
= CODE_FOR_vector_load_v8hi
;
11060 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
11061 icode
= CODE_FOR_vector_load_v4si
;
11063 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
11064 icode
= CODE_FOR_vector_load_v4sf
;
11067 *expandedp
= false;
11073 arg0
= CALL_EXPR_ARG (exp
, 0);
11074 op0
= expand_normal (arg0
);
11075 tmode
= insn_data
[icode
].operand
[0].mode
;
11076 mode0
= insn_data
[icode
].operand
[1].mode
;
11079 || GET_MODE (target
) != tmode
11080 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11081 target
= gen_reg_rtx (tmode
);
11083 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11084 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
11086 pat
= GEN_FCN (icode
) (target
, op0
);
11093 /* Expand the stvx builtins. */
11095 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
11098 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11099 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11101 enum machine_mode mode0
, mode1
;
11103 enum insn_code icode
;
11107 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
11108 icode
= CODE_FOR_vector_store_v16qi
;
11110 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
11111 icode
= CODE_FOR_vector_store_v8hi
;
11113 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
11114 icode
= CODE_FOR_vector_store_v4si
;
11116 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
11117 icode
= CODE_FOR_vector_store_v4sf
;
11120 *expandedp
= false;
11124 arg0
= CALL_EXPR_ARG (exp
, 0);
11125 arg1
= CALL_EXPR_ARG (exp
, 1);
11126 op0
= expand_normal (arg0
);
11127 op1
= expand_normal (arg1
);
11128 mode0
= insn_data
[icode
].operand
[0].mode
;
11129 mode1
= insn_data
[icode
].operand
[1].mode
;
11131 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11132 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
11133 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
11134 op1
= copy_to_mode_reg (mode1
, op1
);
11136 pat
= GEN_FCN (icode
) (op0
, op1
);
11144 /* Expand the dst builtins. */
11146 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
11149 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11150 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11151 tree arg0
, arg1
, arg2
;
11152 enum machine_mode mode0
, mode1
;
11153 rtx pat
, op0
, op1
, op2
;
11154 const struct builtin_description
*d
;
11157 *expandedp
= false;
11159 /* Handle DST variants. */
11161 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
11162 if (d
->code
== fcode
)
11164 arg0
= CALL_EXPR_ARG (exp
, 0);
11165 arg1
= CALL_EXPR_ARG (exp
, 1);
11166 arg2
= CALL_EXPR_ARG (exp
, 2);
11167 op0
= expand_normal (arg0
);
11168 op1
= expand_normal (arg1
);
11169 op2
= expand_normal (arg2
);
11170 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
11171 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
11173 /* Invalid arguments, bail out before generating bad rtl. */
11174 if (arg0
== error_mark_node
11175 || arg1
== error_mark_node
11176 || arg2
== error_mark_node
)
11181 if (TREE_CODE (arg2
) != INTEGER_CST
11182 || TREE_INT_CST_LOW (arg2
) & ~0x3)
11184 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
11188 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
11189 op0
= copy_to_mode_reg (Pmode
, op0
);
11190 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
11191 op1
= copy_to_mode_reg (mode1
, op1
);
11193 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
11203 /* Expand vec_init builtin. */
11205 altivec_expand_vec_init_builtin (tree type
, tree exp
, rtx target
)
11207 enum machine_mode tmode
= TYPE_MODE (type
);
11208 enum machine_mode inner_mode
= GET_MODE_INNER (tmode
);
11209 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
11210 rtvec v
= rtvec_alloc (n_elt
);
11212 gcc_assert (VECTOR_MODE_P (tmode
));
11213 gcc_assert (n_elt
== call_expr_nargs (exp
));
11215 for (i
= 0; i
< n_elt
; ++i
)
11217 rtx x
= expand_normal (CALL_EXPR_ARG (exp
, i
));
11218 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
11221 if (!target
|| !register_operand (target
, tmode
))
11222 target
= gen_reg_rtx (tmode
);
11224 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
11228 /* Return the integer constant in ARG. Constrain it to be in the range
11229 of the subparts of VEC_TYPE; issue an error if not. */
11232 get_element_number (tree vec_type
, tree arg
)
11234 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
11236 if (!host_integerp (arg
, 1)
11237 || (elt
= tree_low_cst (arg
, 1), elt
> max
))
11239 error ("selector must be an integer constant in the range 0..%wi", max
);
11246 /* Expand vec_set builtin. */
11248 altivec_expand_vec_set_builtin (tree exp
)
11250 enum machine_mode tmode
, mode1
;
11251 tree arg0
, arg1
, arg2
;
11255 arg0
= CALL_EXPR_ARG (exp
, 0);
11256 arg1
= CALL_EXPR_ARG (exp
, 1);
11257 arg2
= CALL_EXPR_ARG (exp
, 2);
11259 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
11260 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
11261 gcc_assert (VECTOR_MODE_P (tmode
));
11263 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, EXPAND_NORMAL
);
11264 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, EXPAND_NORMAL
);
11265 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
11267 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
11268 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
11270 op0
= force_reg (tmode
, op0
);
11271 op1
= force_reg (mode1
, op1
);
11273 rs6000_expand_vector_set (op0
, op1
, elt
);
11278 /* Expand vec_ext builtin. */
11280 altivec_expand_vec_ext_builtin (tree exp
, rtx target
)
11282 enum machine_mode tmode
, mode0
;
11287 arg0
= CALL_EXPR_ARG (exp
, 0);
11288 arg1
= CALL_EXPR_ARG (exp
, 1);
11290 op0
= expand_normal (arg0
);
11291 elt
= get_element_number (TREE_TYPE (arg0
), arg1
);
11293 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
11294 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
11295 gcc_assert (VECTOR_MODE_P (mode0
));
11297 op0
= force_reg (mode0
, op0
);
11299 if (optimize
|| !target
|| !register_operand (target
, tmode
))
11300 target
= gen_reg_rtx (tmode
);
11302 rs6000_expand_vector_extract (target
, op0
, elt
);
11307 /* Expand the builtin in EXP and store the result in TARGET. Store
11308 true in *EXPANDEDP if we found a builtin to expand. */
11310 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
11312 const struct builtin_description
*d
;
11313 const struct builtin_description_predicates
*dp
;
11315 enum insn_code icode
;
11316 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11319 enum machine_mode tmode
, mode0
;
11320 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11322 if ((fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11323 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
11324 || (fcode
>= VSX_BUILTIN_OVERLOADED_FIRST
11325 && fcode
<= VSX_BUILTIN_OVERLOADED_LAST
))
11328 error ("unresolved overload for Altivec builtin %qF", fndecl
);
11332 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
11336 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
11340 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
11348 case ALTIVEC_BUILTIN_STVX
:
11349 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx
, exp
);
11350 case ALTIVEC_BUILTIN_STVEBX
:
11351 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, exp
);
11352 case ALTIVEC_BUILTIN_STVEHX
:
11353 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, exp
);
11354 case ALTIVEC_BUILTIN_STVEWX
:
11355 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, exp
);
11356 case ALTIVEC_BUILTIN_STVXL
:
11357 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, exp
);
11359 case ALTIVEC_BUILTIN_STVLX
:
11360 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx
, exp
);
11361 case ALTIVEC_BUILTIN_STVLXL
:
11362 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl
, exp
);
11363 case ALTIVEC_BUILTIN_STVRX
:
11364 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx
, exp
);
11365 case ALTIVEC_BUILTIN_STVRXL
:
11366 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl
, exp
);
11368 case ALTIVEC_BUILTIN_MFVSCR
:
11369 icode
= CODE_FOR_altivec_mfvscr
;
11370 tmode
= insn_data
[icode
].operand
[0].mode
;
11373 || GET_MODE (target
) != tmode
11374 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11375 target
= gen_reg_rtx (tmode
);
11377 pat
= GEN_FCN (icode
) (target
);
11383 case ALTIVEC_BUILTIN_MTVSCR
:
11384 icode
= CODE_FOR_altivec_mtvscr
;
11385 arg0
= CALL_EXPR_ARG (exp
, 0);
11386 op0
= expand_normal (arg0
);
11387 mode0
= insn_data
[icode
].operand
[0].mode
;
11389 /* If we got invalid arguments bail out before generating bad rtl. */
11390 if (arg0
== error_mark_node
)
11393 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11394 op0
= copy_to_mode_reg (mode0
, op0
);
11396 pat
= GEN_FCN (icode
) (op0
);
11401 case ALTIVEC_BUILTIN_DSSALL
:
11402 emit_insn (gen_altivec_dssall ());
11405 case ALTIVEC_BUILTIN_DSS
:
11406 icode
= CODE_FOR_altivec_dss
;
11407 arg0
= CALL_EXPR_ARG (exp
, 0);
11409 op0
= expand_normal (arg0
);
11410 mode0
= insn_data
[icode
].operand
[0].mode
;
11412 /* If we got invalid arguments bail out before generating bad rtl. */
11413 if (arg0
== error_mark_node
)
11416 if (TREE_CODE (arg0
) != INTEGER_CST
11417 || TREE_INT_CST_LOW (arg0
) & ~0x3)
11419 error ("argument to dss must be a 2-bit unsigned literal");
11423 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11424 op0
= copy_to_mode_reg (mode0
, op0
);
11426 emit_insn (gen_altivec_dss (op0
));
11429 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
11430 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
11431 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
11432 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
11433 case VSX_BUILTIN_VEC_INIT_V2DF
:
11434 case VSX_BUILTIN_VEC_INIT_V2DI
:
11435 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), exp
, target
);
11437 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
11438 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
11439 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
11440 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
11441 case VSX_BUILTIN_VEC_SET_V2DF
:
11442 case VSX_BUILTIN_VEC_SET_V2DI
:
11443 return altivec_expand_vec_set_builtin (exp
);
11445 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
11446 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
11447 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
11448 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
11449 case VSX_BUILTIN_VEC_EXT_V2DF
:
11450 case VSX_BUILTIN_VEC_EXT_V2DI
:
11451 return altivec_expand_vec_ext_builtin (exp
, target
);
11455 /* Fall through. */
11458 /* Expand abs* operations. */
11460 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
11461 if (d
->code
== fcode
)
11462 return altivec_expand_abs_builtin (d
->icode
, exp
, target
);
11464 /* Expand the AltiVec predicates. */
11465 dp
= bdesc_altivec_preds
;
11466 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
11467 if (dp
->code
== fcode
)
11468 return altivec_expand_predicate_builtin (dp
->icode
, exp
, target
);
11470 /* LV* are funky. We initialized them differently. */
11473 case ALTIVEC_BUILTIN_LVSL
:
11474 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
11475 exp
, target
, false);
11476 case ALTIVEC_BUILTIN_LVSR
:
11477 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
11478 exp
, target
, false);
11479 case ALTIVEC_BUILTIN_LVEBX
:
11480 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
11481 exp
, target
, false);
11482 case ALTIVEC_BUILTIN_LVEHX
:
11483 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
11484 exp
, target
, false);
11485 case ALTIVEC_BUILTIN_LVEWX
:
11486 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
11487 exp
, target
, false);
11488 case ALTIVEC_BUILTIN_LVXL
:
11489 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
11490 exp
, target
, false);
11491 case ALTIVEC_BUILTIN_LVX
:
11492 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx
,
11493 exp
, target
, false);
11494 case ALTIVEC_BUILTIN_LVLX
:
11495 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx
,
11496 exp
, target
, true);
11497 case ALTIVEC_BUILTIN_LVLXL
:
11498 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl
,
11499 exp
, target
, true);
11500 case ALTIVEC_BUILTIN_LVRX
:
11501 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx
,
11502 exp
, target
, true);
11503 case ALTIVEC_BUILTIN_LVRXL
:
11504 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl
,
11505 exp
, target
, true);
11508 /* Fall through. */
11511 *expandedp
= false;
11515 /* Expand the builtin in EXP and store the result in TARGET. Store
11516 true in *EXPANDEDP if we found a builtin to expand. */
11518 paired_expand_builtin (tree exp
, rtx target
, bool * expandedp
)
11520 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11521 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11522 const struct builtin_description
*d
;
11529 case PAIRED_BUILTIN_STX
:
11530 return paired_expand_stv_builtin (CODE_FOR_paired_stx
, exp
);
11531 case PAIRED_BUILTIN_LX
:
11532 return paired_expand_lv_builtin (CODE_FOR_paired_lx
, exp
, target
);
11535 /* Fall through. */
11538 /* Expand the paired predicates. */
11539 d
= bdesc_paired_preds
;
11540 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); i
++, d
++)
11541 if (d
->code
== fcode
)
11542 return paired_expand_predicate_builtin (d
->icode
, exp
, target
);
11544 *expandedp
= false;
11548 /* Binops that need to be initialized manually, but can be expanded
11549 automagically by rs6000_expand_binop_builtin. */
11550 static struct builtin_description bdesc_2arg_spe
[] =
11552 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
11553 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
11554 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
11555 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
11556 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
11557 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
11558 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
11559 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
11560 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
11561 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
11562 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
11563 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
11564 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
11565 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
11566 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
11567 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
11568 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
11569 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
11570 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
11571 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
11572 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
11573 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
11576 /* Expand the builtin in EXP and store the result in TARGET. Store
11577 true in *EXPANDEDP if we found a builtin to expand.
11579 This expands the SPE builtins that are not simple unary and binary
11582 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
11584 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11586 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11587 enum insn_code icode
;
11588 enum machine_mode tmode
, mode0
;
11590 struct builtin_description
*d
;
11595 /* Syntax check for a 5-bit unsigned immediate. */
11598 case SPE_BUILTIN_EVSTDD
:
11599 case SPE_BUILTIN_EVSTDH
:
11600 case SPE_BUILTIN_EVSTDW
:
11601 case SPE_BUILTIN_EVSTWHE
:
11602 case SPE_BUILTIN_EVSTWHO
:
11603 case SPE_BUILTIN_EVSTWWE
:
11604 case SPE_BUILTIN_EVSTWWO
:
11605 arg1
= CALL_EXPR_ARG (exp
, 2);
11606 if (TREE_CODE (arg1
) != INTEGER_CST
11607 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
11609 error ("argument 2 must be a 5-bit unsigned literal");
11617 /* The evsplat*i instructions are not quite generic. */
11620 case SPE_BUILTIN_EVSPLATFI
:
11621 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
11623 case SPE_BUILTIN_EVSPLATI
:
11624 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
11630 d
= (struct builtin_description
*) bdesc_2arg_spe
;
11631 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
11632 if (d
->code
== fcode
)
11633 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
11635 d
= (struct builtin_description
*) bdesc_spe_predicates
;
11636 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
11637 if (d
->code
== fcode
)
11638 return spe_expand_predicate_builtin (d
->icode
, exp
, target
);
11640 d
= (struct builtin_description
*) bdesc_spe_evsel
;
11641 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
11642 if (d
->code
== fcode
)
11643 return spe_expand_evsel_builtin (d
->icode
, exp
, target
);
11647 case SPE_BUILTIN_EVSTDDX
:
11648 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, exp
);
11649 case SPE_BUILTIN_EVSTDHX
:
11650 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, exp
);
11651 case SPE_BUILTIN_EVSTDWX
:
11652 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, exp
);
11653 case SPE_BUILTIN_EVSTWHEX
:
11654 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, exp
);
11655 case SPE_BUILTIN_EVSTWHOX
:
11656 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, exp
);
11657 case SPE_BUILTIN_EVSTWWEX
:
11658 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, exp
);
11659 case SPE_BUILTIN_EVSTWWOX
:
11660 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, exp
);
11661 case SPE_BUILTIN_EVSTDD
:
11662 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, exp
);
11663 case SPE_BUILTIN_EVSTDH
:
11664 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, exp
);
11665 case SPE_BUILTIN_EVSTDW
:
11666 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, exp
);
11667 case SPE_BUILTIN_EVSTWHE
:
11668 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, exp
);
11669 case SPE_BUILTIN_EVSTWHO
:
11670 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, exp
);
11671 case SPE_BUILTIN_EVSTWWE
:
11672 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, exp
);
11673 case SPE_BUILTIN_EVSTWWO
:
11674 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, exp
);
11675 case SPE_BUILTIN_MFSPEFSCR
:
11676 icode
= CODE_FOR_spe_mfspefscr
;
11677 tmode
= insn_data
[icode
].operand
[0].mode
;
11680 || GET_MODE (target
) != tmode
11681 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11682 target
= gen_reg_rtx (tmode
);
11684 pat
= GEN_FCN (icode
) (target
);
11689 case SPE_BUILTIN_MTSPEFSCR
:
11690 icode
= CODE_FOR_spe_mtspefscr
;
11691 arg0
= CALL_EXPR_ARG (exp
, 0);
11692 op0
= expand_normal (arg0
);
11693 mode0
= insn_data
[icode
].operand
[0].mode
;
11695 if (arg0
== error_mark_node
)
11698 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
11699 op0
= copy_to_mode_reg (mode0
, op0
);
11701 pat
= GEN_FCN (icode
) (op0
);
11709 *expandedp
= false;
11714 paired_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
11716 rtx pat
, scratch
, tmp
;
11717 tree form
= CALL_EXPR_ARG (exp
, 0);
11718 tree arg0
= CALL_EXPR_ARG (exp
, 1);
11719 tree arg1
= CALL_EXPR_ARG (exp
, 2);
11720 rtx op0
= expand_normal (arg0
);
11721 rtx op1
= expand_normal (arg1
);
11722 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
11723 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
11725 enum rtx_code code
;
11727 if (TREE_CODE (form
) != INTEGER_CST
)
11729 error ("argument 1 of __builtin_paired_predicate must be a constant");
11733 form_int
= TREE_INT_CST_LOW (form
);
11735 gcc_assert (mode0
== mode1
);
11737 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
11741 || GET_MODE (target
) != SImode
11742 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
11743 target
= gen_reg_rtx (SImode
);
11744 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11745 op0
= copy_to_mode_reg (mode0
, op0
);
11746 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
11747 op1
= copy_to_mode_reg (mode1
, op1
);
11749 scratch
= gen_reg_rtx (CCFPmode
);
11751 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
11773 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
11776 error ("argument 1 of __builtin_paired_predicate is out of range");
11780 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
11781 emit_move_insn (target
, tmp
);
11786 spe_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
11788 rtx pat
, scratch
, tmp
;
11789 tree form
= CALL_EXPR_ARG (exp
, 0);
11790 tree arg0
= CALL_EXPR_ARG (exp
, 1);
11791 tree arg1
= CALL_EXPR_ARG (exp
, 2);
11792 rtx op0
= expand_normal (arg0
);
11793 rtx op1
= expand_normal (arg1
);
11794 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
11795 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
11797 enum rtx_code code
;
11799 if (TREE_CODE (form
) != INTEGER_CST
)
11801 error ("argument 1 of __builtin_spe_predicate must be a constant");
11805 form_int
= TREE_INT_CST_LOW (form
);
11807 gcc_assert (mode0
== mode1
);
11809 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
11813 || GET_MODE (target
) != SImode
11814 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
11815 target
= gen_reg_rtx (SImode
);
11817 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11818 op0
= copy_to_mode_reg (mode0
, op0
);
11819 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
11820 op1
= copy_to_mode_reg (mode1
, op1
);
11822 scratch
= gen_reg_rtx (CCmode
);
11824 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
11829 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11830 _lower_. We use one compare, but look in different bits of the
11831 CR for each variant.
11833 There are 2 elements in each SPE simd type (upper/lower). The CR
11834 bits are set as follows:
11836 BIT0 | BIT 1 | BIT 2 | BIT 3
11837 U | L | (U | L) | (U & L)
11839 So, for an "all" relationship, BIT 3 would be set.
11840 For an "any" relationship, BIT 2 would be set. Etc.
11842 Following traditional nomenclature, these bits map to:
11844 BIT0 | BIT 1 | BIT 2 | BIT 3
11847 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11852 /* All variant. OV bit. */
11854 /* We need to get to the OV bit, which is the ORDERED bit. We
11855 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11856 that's ugly and will make validate_condition_mode die.
11857 So let's just use another pattern. */
11858 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
11860 /* Any variant. EQ bit. */
11864 /* Upper variant. LT bit. */
11868 /* Lower variant. GT bit. */
11873 error ("argument 1 of __builtin_spe_predicate is out of range");
11877 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
11878 emit_move_insn (target
, tmp
);
11883 /* The evsel builtins look like this:
11885 e = __builtin_spe_evsel_OP (a, b, c, d);
11887 and work like this:
11889 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11890 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11894 spe_expand_evsel_builtin (enum insn_code icode
, tree exp
, rtx target
)
11897 tree arg0
= CALL_EXPR_ARG (exp
, 0);
11898 tree arg1
= CALL_EXPR_ARG (exp
, 1);
11899 tree arg2
= CALL_EXPR_ARG (exp
, 2);
11900 tree arg3
= CALL_EXPR_ARG (exp
, 3);
11901 rtx op0
= expand_normal (arg0
);
11902 rtx op1
= expand_normal (arg1
);
11903 rtx op2
= expand_normal (arg2
);
11904 rtx op3
= expand_normal (arg3
);
11905 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
11906 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
11908 gcc_assert (mode0
== mode1
);
11910 if (arg0
== error_mark_node
|| arg1
== error_mark_node
11911 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
11915 || GET_MODE (target
) != mode0
11916 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
11917 target
= gen_reg_rtx (mode0
);
11919 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
11920 op0
= copy_to_mode_reg (mode0
, op0
);
11921 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
11922 op1
= copy_to_mode_reg (mode0
, op1
);
11923 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
11924 op2
= copy_to_mode_reg (mode0
, op2
);
11925 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
11926 op3
= copy_to_mode_reg (mode0
, op3
);
11928 /* Generate the compare. */
11929 scratch
= gen_reg_rtx (CCmode
);
11930 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
11935 if (mode0
== V2SImode
)
11936 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
11938 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
11943 /* Expand an expression EXP that calls a built-in function,
11944 with result going to TARGET if that's convenient
11945 (and in mode MODE if that's convenient).
11946 SUBTARGET may be used as the target for computing one of EXP's operands.
11947 IGNORE is nonzero if the value is to be ignored. */
11950 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
11951 enum machine_mode mode ATTRIBUTE_UNUSED
,
11952 int ignore ATTRIBUTE_UNUSED
)
11954 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11955 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11956 const struct builtin_description
*d
;
11963 case RS6000_BUILTIN_RECIP
:
11964 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3
, exp
, target
);
11966 case RS6000_BUILTIN_RECIPF
:
11967 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3
, exp
, target
);
11969 case RS6000_BUILTIN_RSQRTF
:
11970 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2
, exp
, target
);
11972 case RS6000_BUILTIN_RSQRT
:
11973 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2
, exp
, target
);
11975 case RS6000_BUILTIN_BSWAP_HI
:
11976 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2
, exp
, target
);
11978 case POWER7_BUILTIN_BPERMD
:
11979 return rs6000_expand_binop_builtin (((TARGET_64BIT
)
11980 ? CODE_FOR_bpermd_di
11981 : CODE_FOR_bpermd_si
), exp
, target
);
11983 case ALTIVEC_BUILTIN_MASK_FOR_LOAD
:
11984 case ALTIVEC_BUILTIN_MASK_FOR_STORE
:
11986 int icode
= (int) CODE_FOR_altivec_lvsr
;
11987 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11988 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
11992 gcc_assert (TARGET_ALTIVEC
);
11994 arg
= CALL_EXPR_ARG (exp
, 0);
11995 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg
)));
11996 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
11997 addr
= memory_address (mode
, op
);
11998 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
12002 /* For the load case need to negate the address. */
12003 op
= gen_reg_rtx (GET_MODE (addr
));
12004 emit_insn (gen_rtx_SET (VOIDmode
, op
,
12005 gen_rtx_NEG (GET_MODE (addr
), addr
)));
12007 op
= gen_rtx_MEM (mode
, op
);
12010 || GET_MODE (target
) != tmode
12011 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
12012 target
= gen_reg_rtx (tmode
);
12014 /*pat = gen_altivec_lvsr (target, op);*/
12015 pat
= GEN_FCN (icode
) (target
, op
);
12023 case ALTIVEC_BUILTIN_VCFUX
:
12024 case ALTIVEC_BUILTIN_VCFSX
:
12025 case ALTIVEC_BUILTIN_VCTUXS
:
12026 case ALTIVEC_BUILTIN_VCTSXS
:
12027 /* FIXME: There's got to be a nicer way to handle this case than
12028 constructing a new CALL_EXPR. */
12029 if (call_expr_nargs (exp
) == 1)
12031 exp
= build_call_nary (TREE_TYPE (exp
), CALL_EXPR_FN (exp
),
12032 2, CALL_EXPR_ARG (exp
, 0), integer_zero_node
);
12040 if (TARGET_ALTIVEC
)
12042 ret
= altivec_expand_builtin (exp
, target
, &success
);
12049 ret
= spe_expand_builtin (exp
, target
, &success
);
12054 if (TARGET_PAIRED_FLOAT
)
12056 ret
= paired_expand_builtin (exp
, target
, &success
);
12062 gcc_assert (TARGET_ALTIVEC
|| TARGET_VSX
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
);
12064 /* Handle simple unary operations. */
12065 d
= (struct builtin_description
*) bdesc_1arg
;
12066 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
12067 if (d
->code
== fcode
)
12068 return rs6000_expand_unop_builtin (d
->icode
, exp
, target
);
12070 /* Handle simple binary operations. */
12071 d
= (struct builtin_description
*) bdesc_2arg
;
12072 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
12073 if (d
->code
== fcode
)
12074 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
12076 /* Handle simple ternary operations. */
12078 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
12079 if (d
->code
== fcode
)
12080 return rs6000_expand_ternop_builtin (d
->icode
, exp
, target
);
12082 gcc_unreachable ();
12086 rs6000_init_builtins (void)
12091 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
12092 V2SF_type_node
= build_vector_type (float_type_node
, 2);
12093 V2DI_type_node
= build_vector_type (intDI_type_node
, 2);
12094 V2DF_type_node
= build_vector_type (double_type_node
, 2);
12095 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
12096 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
12097 V4SF_type_node
= build_vector_type (float_type_node
, 4);
12098 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
12099 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
12101 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
12102 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
12103 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
12104 unsigned_V2DI_type_node
= build_vector_type (unsigned_intDI_type_node
, 2);
12106 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
12107 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
12108 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
12109 opaque_V4SI_type_node
= build_opaque_vector_type (intSI_type_node
, 4);
12111 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12112 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12113 'vector unsigned short'. */
12115 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
12116 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
12117 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
12118 bool_long_type_node
= build_distinct_type_copy (unsigned_intDI_type_node
);
12119 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
12121 long_integer_type_internal_node
= long_integer_type_node
;
12122 long_unsigned_type_internal_node
= long_unsigned_type_node
;
12123 intQI_type_internal_node
= intQI_type_node
;
12124 uintQI_type_internal_node
= unsigned_intQI_type_node
;
12125 intHI_type_internal_node
= intHI_type_node
;
12126 uintHI_type_internal_node
= unsigned_intHI_type_node
;
12127 intSI_type_internal_node
= intSI_type_node
;
12128 uintSI_type_internal_node
= unsigned_intSI_type_node
;
12129 intDI_type_internal_node
= intDI_type_node
;
12130 uintDI_type_internal_node
= unsigned_intDI_type_node
;
12131 float_type_internal_node
= float_type_node
;
12132 double_type_internal_node
= float_type_node
;
12133 void_type_internal_node
= void_type_node
;
12135 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12137 builtin_mode_to_type
[QImode
][0] = integer_type_node
;
12138 builtin_mode_to_type
[HImode
][0] = integer_type_node
;
12139 builtin_mode_to_type
[SImode
][0] = intSI_type_node
;
12140 builtin_mode_to_type
[SImode
][1] = unsigned_intSI_type_node
;
12141 builtin_mode_to_type
[DImode
][0] = intDI_type_node
;
12142 builtin_mode_to_type
[DImode
][1] = unsigned_intDI_type_node
;
12143 builtin_mode_to_type
[SFmode
][0] = float_type_node
;
12144 builtin_mode_to_type
[DFmode
][0] = double_type_node
;
12145 builtin_mode_to_type
[V2SImode
][0] = V2SI_type_node
;
12146 builtin_mode_to_type
[V2SFmode
][0] = V2SF_type_node
;
12147 builtin_mode_to_type
[V2DImode
][0] = V2DI_type_node
;
12148 builtin_mode_to_type
[V2DImode
][1] = unsigned_V2DI_type_node
;
12149 builtin_mode_to_type
[V2DFmode
][0] = V2DF_type_node
;
12150 builtin_mode_to_type
[V4HImode
][0] = V4HI_type_node
;
12151 builtin_mode_to_type
[V4SImode
][0] = V4SI_type_node
;
12152 builtin_mode_to_type
[V4SImode
][1] = unsigned_V4SI_type_node
;
12153 builtin_mode_to_type
[V4SFmode
][0] = V4SF_type_node
;
12154 builtin_mode_to_type
[V8HImode
][0] = V8HI_type_node
;
12155 builtin_mode_to_type
[V8HImode
][1] = unsigned_V8HI_type_node
;
12156 builtin_mode_to_type
[V16QImode
][0] = V16QI_type_node
;
12157 builtin_mode_to_type
[V16QImode
][1] = unsigned_V16QI_type_node
;
12159 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12160 get_identifier ("__bool char"),
12161 bool_char_type_node
);
12162 TYPE_NAME (bool_char_type_node
) = tdecl
;
12163 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12164 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12165 get_identifier ("__bool short"),
12166 bool_short_type_node
);
12167 TYPE_NAME (bool_short_type_node
) = tdecl
;
12168 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12169 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12170 get_identifier ("__bool int"),
12171 bool_int_type_node
);
12172 TYPE_NAME (bool_int_type_node
) = tdecl
;
12173 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12174 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
, get_identifier ("__pixel"),
12176 TYPE_NAME (pixel_type_node
) = tdecl
;
12177 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12179 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
12180 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
12181 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
12182 bool_V2DI_type_node
= build_vector_type (bool_long_type_node
, 2);
12183 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
12185 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12186 get_identifier ("__vector unsigned char"),
12187 unsigned_V16QI_type_node
);
12188 TYPE_NAME (unsigned_V16QI_type_node
) = tdecl
;
12189 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12190 tdecl
= build_decl (BUILTINS_LOCATION
,
12191 TYPE_DECL
, get_identifier ("__vector signed char"),
12193 TYPE_NAME (V16QI_type_node
) = tdecl
;
12194 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12195 tdecl
= build_decl (BUILTINS_LOCATION
,
12196 TYPE_DECL
, get_identifier ("__vector __bool char"),
12197 bool_V16QI_type_node
);
12198 TYPE_NAME ( bool_V16QI_type_node
) = tdecl
;
12199 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12201 tdecl
= build_decl (BUILTINS_LOCATION
,
12202 TYPE_DECL
, get_identifier ("__vector unsigned short"),
12203 unsigned_V8HI_type_node
);
12204 TYPE_NAME (unsigned_V8HI_type_node
) = tdecl
;
12205 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12206 tdecl
= build_decl (BUILTINS_LOCATION
,
12207 TYPE_DECL
, get_identifier ("__vector signed short"),
12209 TYPE_NAME (V8HI_type_node
) = tdecl
;
12210 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12211 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12212 get_identifier ("__vector __bool short"),
12213 bool_V8HI_type_node
);
12214 TYPE_NAME (bool_V8HI_type_node
) = tdecl
;
12215 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12217 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12218 get_identifier ("__vector unsigned int"),
12219 unsigned_V4SI_type_node
);
12220 TYPE_NAME (unsigned_V4SI_type_node
) = tdecl
;
12221 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12222 tdecl
= build_decl (BUILTINS_LOCATION
,
12223 TYPE_DECL
, get_identifier ("__vector signed int"),
12225 TYPE_NAME (V4SI_type_node
) = tdecl
;
12226 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12227 tdecl
= build_decl (BUILTINS_LOCATION
,
12228 TYPE_DECL
, get_identifier ("__vector __bool int"),
12229 bool_V4SI_type_node
);
12230 TYPE_NAME (bool_V4SI_type_node
) = tdecl
;
12231 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12233 tdecl
= build_decl (BUILTINS_LOCATION
,
12234 TYPE_DECL
, get_identifier ("__vector float"),
12236 TYPE_NAME (V4SF_type_node
) = tdecl
;
12237 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12238 tdecl
= build_decl (BUILTINS_LOCATION
,
12239 TYPE_DECL
, get_identifier ("__vector __pixel"),
12240 pixel_V8HI_type_node
);
12241 TYPE_NAME (pixel_V8HI_type_node
) = tdecl
;
12242 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12246 tdecl
= build_decl (BUILTINS_LOCATION
,
12247 TYPE_DECL
, get_identifier ("__vector double"),
12249 TYPE_NAME (V2DF_type_node
) = tdecl
;
12250 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12252 tdecl
= build_decl (BUILTINS_LOCATION
,
12253 TYPE_DECL
, get_identifier ("__vector long"),
12255 TYPE_NAME (V2DI_type_node
) = tdecl
;
12256 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12258 tdecl
= build_decl (BUILTINS_LOCATION
,
12259 TYPE_DECL
, get_identifier ("__vector unsigned long"),
12260 unsigned_V2DI_type_node
);
12261 TYPE_NAME (unsigned_V2DI_type_node
) = tdecl
;
12262 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12264 tdecl
= build_decl (BUILTINS_LOCATION
,
12265 TYPE_DECL
, get_identifier ("__vector __bool long"),
12266 bool_V2DI_type_node
);
12267 TYPE_NAME (bool_V2DI_type_node
) = tdecl
;
12268 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
12271 if (TARGET_PAIRED_FLOAT
)
12272 paired_init_builtins ();
12274 spe_init_builtins ();
12275 if (TARGET_ALTIVEC
)
12276 altivec_init_builtins ();
12277 if (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
|| TARGET_VSX
)
12278 rs6000_common_init_builtins ();
12281 ftype
= builtin_function_type (DFmode
, DFmode
, DFmode
, VOIDmode
,
12282 RS6000_BUILTIN_RECIP
,
12283 "__builtin_recipdiv");
12284 def_builtin (MASK_POPCNTB
, "__builtin_recipdiv", ftype
,
12285 RS6000_BUILTIN_RECIP
);
12289 ftype
= builtin_function_type (SFmode
, SFmode
, SFmode
, VOIDmode
,
12290 RS6000_BUILTIN_RECIPF
,
12291 "__builtin_recipdivf");
12292 def_builtin (MASK_PPC_GFXOPT
, "__builtin_recipdivf", ftype
,
12293 RS6000_BUILTIN_RECIPF
);
12295 if (TARGET_FRSQRTE
)
12297 ftype
= builtin_function_type (DFmode
, DFmode
, VOIDmode
, VOIDmode
,
12298 RS6000_BUILTIN_RSQRT
,
12299 "__builtin_rsqrt");
12300 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrt", ftype
,
12301 RS6000_BUILTIN_RSQRT
);
12303 if (TARGET_FRSQRTES
)
12305 ftype
= builtin_function_type (SFmode
, SFmode
, VOIDmode
, VOIDmode
,
12306 RS6000_BUILTIN_RSQRTF
,
12307 "__builtin_rsqrtf");
12308 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrtf", ftype
,
12309 RS6000_BUILTIN_RSQRTF
);
12311 if (TARGET_POPCNTD
)
12313 enum machine_mode mode
= (TARGET_64BIT
) ? DImode
: SImode
;
12314 tree ftype
= builtin_function_type (mode
, mode
, mode
, VOIDmode
,
12315 POWER7_BUILTIN_BPERMD
,
12316 "__builtin_bpermd");
12317 def_builtin (MASK_POPCNTD
, "__builtin_bpermd", ftype
,
12318 POWER7_BUILTIN_BPERMD
);
12320 if (TARGET_POWERPC
)
12322 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12323 tree ftype
= build_function_type_list (unsigned_intHI_type_node
,
12324 unsigned_intHI_type_node
,
12326 def_builtin (MASK_POWERPC
, "__builtin_bswap16", ftype
,
12327 RS6000_BUILTIN_BSWAP_HI
);
12331 /* AIX libm provides clog as __clog. */
12332 if (built_in_decls
[BUILT_IN_CLOG
])
12333 set_user_assembler_name (built_in_decls
[BUILT_IN_CLOG
], "__clog");
12336 #ifdef SUBTARGET_INIT_BUILTINS
12337 SUBTARGET_INIT_BUILTINS
;
12341 /* Returns the rs6000 builtin decl for CODE. */
12344 rs6000_builtin_decl (unsigned code
, bool initialize_p ATTRIBUTE_UNUSED
)
12346 if (code
>= RS6000_BUILTIN_COUNT
)
12347 return error_mark_node
;
12349 return rs6000_builtin_decls
[code
];
12352 /* Search through a set of builtins and enable the mask bits.
12353 DESC is an array of builtins.
12354 SIZE is the total number of builtins.
12355 START is the builtin enum at which to start.
12356 END is the builtin enum at which to end. */
12358 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
12359 enum rs6000_builtins start
,
12360 enum rs6000_builtins end
)
12364 for (i
= 0; i
< size
; ++i
)
12365 if (desc
[i
].code
== start
)
12371 for (; i
< size
; ++i
)
12373 /* Flip all the bits on. */
12374 desc
[i
].mask
= target_flags
;
12375 if (desc
[i
].code
== end
)
12381 spe_init_builtins (void)
12383 tree endlink
= void_list_node
;
12384 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
12385 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
12386 struct builtin_description
*d
;
12389 tree v2si_ftype_4_v2si
12390 = build_function_type
12391 (opaque_V2SI_type_node
,
12392 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12393 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12394 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12395 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12398 tree v2sf_ftype_4_v2sf
12399 = build_function_type
12400 (opaque_V2SF_type_node
,
12401 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12402 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12403 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12404 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12407 tree int_ftype_int_v2si_v2si
12408 = build_function_type
12409 (integer_type_node
,
12410 tree_cons (NULL_TREE
, integer_type_node
,
12411 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12412 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12415 tree int_ftype_int_v2sf_v2sf
12416 = build_function_type
12417 (integer_type_node
,
12418 tree_cons (NULL_TREE
, integer_type_node
,
12419 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12420 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
12423 tree void_ftype_v2si_puint_int
12424 = build_function_type (void_type_node
,
12425 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12426 tree_cons (NULL_TREE
, puint_type_node
,
12427 tree_cons (NULL_TREE
,
12431 tree void_ftype_v2si_puint_char
12432 = build_function_type (void_type_node
,
12433 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12434 tree_cons (NULL_TREE
, puint_type_node
,
12435 tree_cons (NULL_TREE
,
12439 tree void_ftype_v2si_pv2si_int
12440 = build_function_type (void_type_node
,
12441 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12442 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
12443 tree_cons (NULL_TREE
,
12447 tree void_ftype_v2si_pv2si_char
12448 = build_function_type (void_type_node
,
12449 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
12450 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
12451 tree_cons (NULL_TREE
,
12455 tree void_ftype_int
12456 = build_function_type (void_type_node
,
12457 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
12459 tree int_ftype_void
12460 = build_function_type (integer_type_node
, endlink
);
12462 tree v2si_ftype_pv2si_int
12463 = build_function_type (opaque_V2SI_type_node
,
12464 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
12465 tree_cons (NULL_TREE
, integer_type_node
,
12468 tree v2si_ftype_puint_int
12469 = build_function_type (opaque_V2SI_type_node
,
12470 tree_cons (NULL_TREE
, puint_type_node
,
12471 tree_cons (NULL_TREE
, integer_type_node
,
12474 tree v2si_ftype_pushort_int
12475 = build_function_type (opaque_V2SI_type_node
,
12476 tree_cons (NULL_TREE
, pushort_type_node
,
12477 tree_cons (NULL_TREE
, integer_type_node
,
12480 tree v2si_ftype_signed_char
12481 = build_function_type (opaque_V2SI_type_node
,
12482 tree_cons (NULL_TREE
, signed_char_type_node
,
12485 /* The initialization of the simple binary and unary builtins is
12486 done in rs6000_common_init_builtins, but we have to enable the
12487 mask bits here manually because we have run out of `target_flags'
12488 bits. We really need to redesign this mask business. */
12490 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
12491 ARRAY_SIZE (bdesc_2arg
),
12492 SPE_BUILTIN_EVADDW
,
12493 SPE_BUILTIN_EVXOR
);
12494 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
12495 ARRAY_SIZE (bdesc_1arg
),
12497 SPE_BUILTIN_EVSUBFUSIAAW
);
12498 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
12499 ARRAY_SIZE (bdesc_spe_predicates
),
12500 SPE_BUILTIN_EVCMPEQ
,
12501 SPE_BUILTIN_EVFSTSTLT
);
12502 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
12503 ARRAY_SIZE (bdesc_spe_evsel
),
12504 SPE_BUILTIN_EVSEL_CMPGTS
,
12505 SPE_BUILTIN_EVSEL_FSTSTEQ
);
12507 (*lang_hooks
.decls
.pushdecl
)
12508 (build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
12509 get_identifier ("__ev64_opaque__"),
12510 opaque_V2SI_type_node
));
12512 /* Initialize irregular SPE builtins. */
12514 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
12515 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
12516 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
12517 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
12518 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
12519 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
12520 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
12521 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
12522 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
12523 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
12524 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
12525 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
12526 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
12527 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
12528 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
12529 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
12530 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
12531 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
12534 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
12535 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
12536 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
12537 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
12538 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
12539 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
12540 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
12541 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
12542 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
12543 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
12544 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
12545 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
12546 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
12547 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
12548 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
12549 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
12550 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
12551 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
12552 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
12553 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
12554 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
12555 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
12558 d
= (struct builtin_description
*) bdesc_spe_predicates
;
12559 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
12563 switch (insn_data
[d
->icode
].operand
[1].mode
)
12566 type
= int_ftype_int_v2si_v2si
;
12569 type
= int_ftype_int_v2sf_v2sf
;
12572 gcc_unreachable ();
12575 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12578 /* Evsel predicates. */
12579 d
= (struct builtin_description
*) bdesc_spe_evsel
;
12580 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
12584 switch (insn_data
[d
->icode
].operand
[1].mode
)
12587 type
= v2si_ftype_4_v2si
;
12590 type
= v2sf_ftype_4_v2sf
;
12593 gcc_unreachable ();
12596 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12601 paired_init_builtins (void)
12603 const struct builtin_description
*d
;
12605 tree endlink
= void_list_node
;
12607 tree int_ftype_int_v2sf_v2sf
12608 = build_function_type
12609 (integer_type_node
,
12610 tree_cons (NULL_TREE
, integer_type_node
,
12611 tree_cons (NULL_TREE
, V2SF_type_node
,
12612 tree_cons (NULL_TREE
, V2SF_type_node
,
12614 tree pcfloat_type_node
=
12615 build_pointer_type (build_qualified_type
12616 (float_type_node
, TYPE_QUAL_CONST
));
12618 tree v2sf_ftype_long_pcfloat
= build_function_type_list (V2SF_type_node
,
12619 long_integer_type_node
,
12622 tree void_ftype_v2sf_long_pcfloat
=
12623 build_function_type_list (void_type_node
,
12625 long_integer_type_node
,
12630 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat
,
12631 PAIRED_BUILTIN_LX
);
12634 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat
,
12635 PAIRED_BUILTIN_STX
);
12638 d
= bdesc_paired_preds
;
12639 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); ++i
, d
++)
12643 switch (insn_data
[d
->icode
].operand
[1].mode
)
12646 type
= int_ftype_int_v2sf_v2sf
;
12649 gcc_unreachable ();
12652 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12657 altivec_init_builtins (void)
12659 const struct builtin_description
*d
;
12660 const struct builtin_description_predicates
*dp
;
12664 tree pfloat_type_node
= build_pointer_type (float_type_node
);
12665 tree pint_type_node
= build_pointer_type (integer_type_node
);
12666 tree pshort_type_node
= build_pointer_type (short_integer_type_node
);
12667 tree pchar_type_node
= build_pointer_type (char_type_node
);
12669 tree pvoid_type_node
= build_pointer_type (void_type_node
);
12671 tree pcfloat_type_node
= build_pointer_type (build_qualified_type (float_type_node
, TYPE_QUAL_CONST
));
12672 tree pcint_type_node
= build_pointer_type (build_qualified_type (integer_type_node
, TYPE_QUAL_CONST
));
12673 tree pcshort_type_node
= build_pointer_type (build_qualified_type (short_integer_type_node
, TYPE_QUAL_CONST
));
12674 tree pcchar_type_node
= build_pointer_type (build_qualified_type (char_type_node
, TYPE_QUAL_CONST
));
12676 tree pcvoid_type_node
= build_pointer_type (build_qualified_type (void_type_node
, TYPE_QUAL_CONST
));
12678 tree int_ftype_opaque
12679 = build_function_type_list (integer_type_node
,
12680 opaque_V4SI_type_node
, NULL_TREE
);
12681 tree opaque_ftype_opaque
12682 = build_function_type (integer_type_node
,
12684 tree opaque_ftype_opaque_int
12685 = build_function_type_list (opaque_V4SI_type_node
,
12686 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
12687 tree opaque_ftype_opaque_opaque_int
12688 = build_function_type_list (opaque_V4SI_type_node
,
12689 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
12690 integer_type_node
, NULL_TREE
);
12691 tree int_ftype_int_opaque_opaque
12692 = build_function_type_list (integer_type_node
,
12693 integer_type_node
, opaque_V4SI_type_node
,
12694 opaque_V4SI_type_node
, NULL_TREE
);
12695 tree int_ftype_int_v4si_v4si
12696 = build_function_type_list (integer_type_node
,
12697 integer_type_node
, V4SI_type_node
,
12698 V4SI_type_node
, NULL_TREE
);
12699 tree v4sf_ftype_pcfloat
12700 = build_function_type_list (V4SF_type_node
, pcfloat_type_node
, NULL_TREE
);
12701 tree void_ftype_pfloat_v4sf
12702 = build_function_type_list (void_type_node
,
12703 pfloat_type_node
, V4SF_type_node
, NULL_TREE
);
12704 tree v4si_ftype_pcint
12705 = build_function_type_list (V4SI_type_node
, pcint_type_node
, NULL_TREE
);
12706 tree void_ftype_pint_v4si
12707 = build_function_type_list (void_type_node
,
12708 pint_type_node
, V4SI_type_node
, NULL_TREE
);
12709 tree v8hi_ftype_pcshort
12710 = build_function_type_list (V8HI_type_node
, pcshort_type_node
, NULL_TREE
);
12711 tree void_ftype_pshort_v8hi
12712 = build_function_type_list (void_type_node
,
12713 pshort_type_node
, V8HI_type_node
, NULL_TREE
);
12714 tree v16qi_ftype_pcchar
12715 = build_function_type_list (V16QI_type_node
, pcchar_type_node
, NULL_TREE
);
12716 tree void_ftype_pchar_v16qi
12717 = build_function_type_list (void_type_node
,
12718 pchar_type_node
, V16QI_type_node
, NULL_TREE
);
12719 tree void_ftype_v4si
12720 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
12721 tree v8hi_ftype_void
12722 = build_function_type (V8HI_type_node
, void_list_node
);
12723 tree void_ftype_void
12724 = build_function_type (void_type_node
, void_list_node
);
12725 tree void_ftype_int
12726 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
12728 tree opaque_ftype_long_pcvoid
12729 = build_function_type_list (opaque_V4SI_type_node
,
12730 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
12731 tree v16qi_ftype_long_pcvoid
12732 = build_function_type_list (V16QI_type_node
,
12733 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
12734 tree v8hi_ftype_long_pcvoid
12735 = build_function_type_list (V8HI_type_node
,
12736 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
12737 tree v4si_ftype_long_pcvoid
12738 = build_function_type_list (V4SI_type_node
,
12739 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
12741 tree void_ftype_opaque_long_pvoid
12742 = build_function_type_list (void_type_node
,
12743 opaque_V4SI_type_node
, long_integer_type_node
,
12744 pvoid_type_node
, NULL_TREE
);
12745 tree void_ftype_v4si_long_pvoid
12746 = build_function_type_list (void_type_node
,
12747 V4SI_type_node
, long_integer_type_node
,
12748 pvoid_type_node
, NULL_TREE
);
12749 tree void_ftype_v16qi_long_pvoid
12750 = build_function_type_list (void_type_node
,
12751 V16QI_type_node
, long_integer_type_node
,
12752 pvoid_type_node
, NULL_TREE
);
12753 tree void_ftype_v8hi_long_pvoid
12754 = build_function_type_list (void_type_node
,
12755 V8HI_type_node
, long_integer_type_node
,
12756 pvoid_type_node
, NULL_TREE
);
12757 tree int_ftype_int_v8hi_v8hi
12758 = build_function_type_list (integer_type_node
,
12759 integer_type_node
, V8HI_type_node
,
12760 V8HI_type_node
, NULL_TREE
);
12761 tree int_ftype_int_v16qi_v16qi
12762 = build_function_type_list (integer_type_node
,
12763 integer_type_node
, V16QI_type_node
,
12764 V16QI_type_node
, NULL_TREE
);
12765 tree int_ftype_int_v4sf_v4sf
12766 = build_function_type_list (integer_type_node
,
12767 integer_type_node
, V4SF_type_node
,
12768 V4SF_type_node
, NULL_TREE
);
12769 tree int_ftype_int_v2df_v2df
12770 = build_function_type_list (integer_type_node
,
12771 integer_type_node
, V2DF_type_node
,
12772 V2DF_type_node
, NULL_TREE
);
12773 tree v4si_ftype_v4si
12774 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
12775 tree v8hi_ftype_v8hi
12776 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
12777 tree v16qi_ftype_v16qi
12778 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
12779 tree v4sf_ftype_v4sf
12780 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
12781 tree v2df_ftype_v2df
12782 = build_function_type_list (V2DF_type_node
, V2DF_type_node
, NULL_TREE
);
12783 tree void_ftype_pcvoid_int_int
12784 = build_function_type_list (void_type_node
,
12785 pcvoid_type_node
, integer_type_node
,
12786 integer_type_node
, NULL_TREE
);
12788 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat
,
12789 ALTIVEC_BUILTIN_LD_INTERNAL_4sf
);
12790 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf
,
12791 ALTIVEC_BUILTIN_ST_INTERNAL_4sf
);
12792 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint
,
12793 ALTIVEC_BUILTIN_LD_INTERNAL_4si
);
12794 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si
,
12795 ALTIVEC_BUILTIN_ST_INTERNAL_4si
);
12796 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort
,
12797 ALTIVEC_BUILTIN_LD_INTERNAL_8hi
);
12798 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi
,
12799 ALTIVEC_BUILTIN_ST_INTERNAL_8hi
);
12800 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar
,
12801 ALTIVEC_BUILTIN_LD_INTERNAL_16qi
);
12802 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi
,
12803 ALTIVEC_BUILTIN_ST_INTERNAL_16qi
);
12804 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
12805 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
12806 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
12807 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
12808 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
12809 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
12810 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
12811 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
12812 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
12813 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
12814 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
12815 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
12816 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
12817 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
12818 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
12819 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
12820 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
12821 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
12822 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
12823 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
12824 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
12825 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
12826 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
12827 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
12828 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
12829 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
12830 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
12831 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
12832 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
12833 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
12835 if (rs6000_cpu
== PROCESSOR_CELL
)
12837 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLX
);
12838 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLXL
);
12839 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRX
);
12840 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRXL
);
12842 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLX
);
12843 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLXL
);
12844 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRX
);
12845 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRXL
);
12847 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLX
);
12848 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLXL
);
12849 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRX
);
12850 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRXL
);
12852 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLX
);
12853 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLXL
);
12854 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRX
);
12855 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRXL
);
12857 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
12858 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splats", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_SPLATS
);
12859 def_builtin (MASK_ALTIVEC
, "__builtin_vec_promote", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_PROMOTE
);
12861 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
12862 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
12863 def_builtin (MASK_ALTIVEC
, "__builtin_vec_extract", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_EXTRACT
);
12864 def_builtin (MASK_ALTIVEC
, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_INSERT
);
12865 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
12866 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
12867 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
12868 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
12869 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
12870 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
12871 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
12872 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
12874 /* Add the DST variants. */
12876 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
12877 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
12879 /* Initialize the predicates. */
12880 dp
= bdesc_altivec_preds
;
12881 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
12883 enum machine_mode mode1
;
12885 bool is_overloaded
= ((dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12886 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
12887 || (dp
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
12888 && dp
->code
<= VSX_BUILTIN_OVERLOADED_LAST
));
12893 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
12898 type
= int_ftype_int_opaque_opaque
;
12901 type
= int_ftype_int_v4si_v4si
;
12904 type
= int_ftype_int_v8hi_v8hi
;
12907 type
= int_ftype_int_v16qi_v16qi
;
12910 type
= int_ftype_int_v4sf_v4sf
;
12913 type
= int_ftype_int_v2df_v2df
;
12916 gcc_unreachable ();
12919 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
12922 /* Initialize the abs* operators. */
12924 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
12926 enum machine_mode mode0
;
12929 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
12934 type
= v4si_ftype_v4si
;
12937 type
= v8hi_ftype_v8hi
;
12940 type
= v16qi_ftype_v16qi
;
12943 type
= v4sf_ftype_v4sf
;
12946 type
= v2df_ftype_v2df
;
12949 gcc_unreachable ();
12952 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12955 if (TARGET_ALTIVEC
)
12959 /* Initialize target builtin that implements
12960 targetm.vectorize.builtin_mask_for_load. */
12962 decl
= add_builtin_function ("__builtin_altivec_mask_for_load",
12963 v16qi_ftype_long_pcvoid
,
12964 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
12965 BUILT_IN_MD
, NULL
, NULL_TREE
);
12966 TREE_READONLY (decl
) = 1;
12967 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12968 altivec_builtin_mask_for_load
= decl
;
12971 /* Access to the vec_init patterns. */
12972 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
12973 integer_type_node
, integer_type_node
,
12974 integer_type_node
, NULL_TREE
);
12975 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4si", ftype
,
12976 ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
12978 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
12979 short_integer_type_node
,
12980 short_integer_type_node
,
12981 short_integer_type_node
,
12982 short_integer_type_node
,
12983 short_integer_type_node
,
12984 short_integer_type_node
,
12985 short_integer_type_node
, NULL_TREE
);
12986 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v8hi", ftype
,
12987 ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
12989 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
12990 char_type_node
, char_type_node
,
12991 char_type_node
, char_type_node
,
12992 char_type_node
, char_type_node
,
12993 char_type_node
, char_type_node
,
12994 char_type_node
, char_type_node
,
12995 char_type_node
, char_type_node
,
12996 char_type_node
, char_type_node
,
12997 char_type_node
, NULL_TREE
);
12998 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v16qi", ftype
,
12999 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
13001 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
13002 float_type_node
, float_type_node
,
13003 float_type_node
, NULL_TREE
);
13004 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4sf", ftype
,
13005 ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
13009 ftype
= build_function_type_list (V2DF_type_node
, double_type_node
,
13010 double_type_node
, NULL_TREE
);
13011 def_builtin (MASK_VSX
, "__builtin_vec_init_v2df", ftype
,
13012 VSX_BUILTIN_VEC_INIT_V2DF
);
13014 ftype
= build_function_type_list (V2DI_type_node
, intDI_type_node
,
13015 intDI_type_node
, NULL_TREE
);
13016 def_builtin (MASK_VSX
, "__builtin_vec_init_v2di", ftype
,
13017 VSX_BUILTIN_VEC_INIT_V2DI
);
13020 /* Access to the vec_set patterns. */
13021 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
13023 integer_type_node
, NULL_TREE
);
13024 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4si", ftype
,
13025 ALTIVEC_BUILTIN_VEC_SET_V4SI
);
13027 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
13029 integer_type_node
, NULL_TREE
);
13030 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v8hi", ftype
,
13031 ALTIVEC_BUILTIN_VEC_SET_V8HI
);
13033 ftype
= build_function_type_list (V16QI_type_node
, V16QI_type_node
,
13035 integer_type_node
, NULL_TREE
);
13036 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v16qi", ftype
,
13037 ALTIVEC_BUILTIN_VEC_SET_V16QI
);
13039 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
13041 integer_type_node
, NULL_TREE
);
13042 def_builtin (MASK_ALTIVEC
|MASK_VSX
, "__builtin_vec_set_v4sf", ftype
,
13043 ALTIVEC_BUILTIN_VEC_SET_V4SF
);
13047 ftype
= build_function_type_list (V2DF_type_node
, V2DF_type_node
,
13049 integer_type_node
, NULL_TREE
);
13050 def_builtin (MASK_VSX
, "__builtin_vec_set_v2df", ftype
,
13051 VSX_BUILTIN_VEC_SET_V2DF
);
13053 ftype
= build_function_type_list (V2DI_type_node
, V2DI_type_node
,
13055 integer_type_node
, NULL_TREE
);
13056 def_builtin (MASK_VSX
, "__builtin_vec_set_v2di", ftype
,
13057 VSX_BUILTIN_VEC_SET_V2DI
);
13060 /* Access to the vec_extract patterns. */
13061 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
13062 integer_type_node
, NULL_TREE
);
13063 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4si", ftype
,
13064 ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
13066 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
13067 integer_type_node
, NULL_TREE
);
13068 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v8hi", ftype
,
13069 ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
13071 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
13072 integer_type_node
, NULL_TREE
);
13073 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v16qi", ftype
,
13074 ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
13076 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
13077 integer_type_node
, NULL_TREE
);
13078 def_builtin (MASK_ALTIVEC
|MASK_VSX
, "__builtin_vec_ext_v4sf", ftype
,
13079 ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
13083 ftype
= build_function_type_list (double_type_node
, V2DF_type_node
,
13084 integer_type_node
, NULL_TREE
);
13085 def_builtin (MASK_VSX
, "__builtin_vec_ext_v2df", ftype
,
13086 VSX_BUILTIN_VEC_EXT_V2DF
);
13088 ftype
= build_function_type_list (intDI_type_node
, V2DI_type_node
,
13089 integer_type_node
, NULL_TREE
);
13090 def_builtin (MASK_VSX
, "__builtin_vec_ext_v2di", ftype
,
13091 VSX_BUILTIN_VEC_EXT_V2DI
);
13095 /* Hash function for builtin functions with up to 3 arguments and a return
13098 builtin_hash_function (const void *hash_entry
)
13102 const struct builtin_hash_struct
*bh
=
13103 (const struct builtin_hash_struct
*) hash_entry
;
13105 for (i
= 0; i
< 4; i
++)
13107 ret
= (ret
* (unsigned)MAX_MACHINE_MODE
) + ((unsigned)bh
->mode
[i
]);
13108 ret
= (ret
* 2) + bh
->uns_p
[i
];
13114 /* Compare builtin hash entries H1 and H2 for equivalence. */
13116 builtin_hash_eq (const void *h1
, const void *h2
)
13118 const struct builtin_hash_struct
*p1
= (const struct builtin_hash_struct
*) h1
;
13119 const struct builtin_hash_struct
*p2
= (const struct builtin_hash_struct
*) h2
;
13121 return ((p1
->mode
[0] == p2
->mode
[0])
13122 && (p1
->mode
[1] == p2
->mode
[1])
13123 && (p1
->mode
[2] == p2
->mode
[2])
13124 && (p1
->mode
[3] == p2
->mode
[3])
13125 && (p1
->uns_p
[0] == p2
->uns_p
[0])
13126 && (p1
->uns_p
[1] == p2
->uns_p
[1])
13127 && (p1
->uns_p
[2] == p2
->uns_p
[2])
13128 && (p1
->uns_p
[3] == p2
->uns_p
[3]));
13131 /* Map types for builtin functions with an explicit return type and up to 3
13132 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13133 of the argument. */
13135 builtin_function_type (enum machine_mode mode_ret
, enum machine_mode mode_arg0
,
13136 enum machine_mode mode_arg1
, enum machine_mode mode_arg2
,
13137 enum rs6000_builtins builtin
, const char *name
)
13139 struct builtin_hash_struct h
;
13140 struct builtin_hash_struct
*h2
;
13144 tree ret_type
= NULL_TREE
;
13145 tree arg_type
[3] = { NULL_TREE
, NULL_TREE
, NULL_TREE
};
13148 /* Create builtin_hash_table. */
13149 if (builtin_hash_table
== NULL
)
13150 builtin_hash_table
= htab_create_ggc (1500, builtin_hash_function
,
13151 builtin_hash_eq
, NULL
);
13153 h
.type
= NULL_TREE
;
13154 h
.mode
[0] = mode_ret
;
13155 h
.mode
[1] = mode_arg0
;
13156 h
.mode
[2] = mode_arg1
;
13157 h
.mode
[3] = mode_arg2
;
13163 /* If the builtin is a type that produces unsigned results or takes unsigned
13164 arguments, and it is returned as a decl for the vectorizer (such as
13165 widening multiplies, permute), make sure the arguments and return value
13166 are type correct. */
13169 /* unsigned 2 argument functions. */
13170 case ALTIVEC_BUILTIN_VMULEUB_UNS
:
13171 case ALTIVEC_BUILTIN_VMULEUH_UNS
:
13172 case ALTIVEC_BUILTIN_VMULOUB_UNS
:
13173 case ALTIVEC_BUILTIN_VMULOUH_UNS
:
13179 /* unsigned 3 argument functions. */
13180 case ALTIVEC_BUILTIN_VPERM_16QI_UNS
:
13181 case ALTIVEC_BUILTIN_VPERM_8HI_UNS
:
13182 case ALTIVEC_BUILTIN_VPERM_4SI_UNS
:
13183 case ALTIVEC_BUILTIN_VPERM_2DI_UNS
:
13184 case ALTIVEC_BUILTIN_VSEL_16QI_UNS
:
13185 case ALTIVEC_BUILTIN_VSEL_8HI_UNS
:
13186 case ALTIVEC_BUILTIN_VSEL_4SI_UNS
:
13187 case ALTIVEC_BUILTIN_VSEL_2DI_UNS
:
13188 case VSX_BUILTIN_VPERM_16QI_UNS
:
13189 case VSX_BUILTIN_VPERM_8HI_UNS
:
13190 case VSX_BUILTIN_VPERM_4SI_UNS
:
13191 case VSX_BUILTIN_VPERM_2DI_UNS
:
13192 case VSX_BUILTIN_XXSEL_16QI_UNS
:
13193 case VSX_BUILTIN_XXSEL_8HI_UNS
:
13194 case VSX_BUILTIN_XXSEL_4SI_UNS
:
13195 case VSX_BUILTIN_XXSEL_2DI_UNS
:
13202 /* signed permute functions with unsigned char mask. */
13203 case ALTIVEC_BUILTIN_VPERM_16QI
:
13204 case ALTIVEC_BUILTIN_VPERM_8HI
:
13205 case ALTIVEC_BUILTIN_VPERM_4SI
:
13206 case ALTIVEC_BUILTIN_VPERM_4SF
:
13207 case ALTIVEC_BUILTIN_VPERM_2DI
:
13208 case ALTIVEC_BUILTIN_VPERM_2DF
:
13209 case VSX_BUILTIN_VPERM_16QI
:
13210 case VSX_BUILTIN_VPERM_8HI
:
13211 case VSX_BUILTIN_VPERM_4SI
:
13212 case VSX_BUILTIN_VPERM_4SF
:
13213 case VSX_BUILTIN_VPERM_2DI
:
13214 case VSX_BUILTIN_VPERM_2DF
:
13218 /* unsigned args, signed return. */
13219 case VSX_BUILTIN_XVCVUXDDP_UNS
:
13220 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
:
13224 /* signed args, unsigned return. */
13225 case VSX_BUILTIN_XVCVDPUXDS_UNS
:
13226 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
:
13234 /* Figure out how many args are present. */
13235 while (num_args
> 0 && h
.mode
[num_args
] == VOIDmode
)
13239 fatal_error ("internal error: builtin function %s had no type", name
);
13241 ret_type
= builtin_mode_to_type
[h
.mode
[0]][h
.uns_p
[0]];
13242 if (!ret_type
&& h
.uns_p
[0])
13243 ret_type
= builtin_mode_to_type
[h
.mode
[0]][0];
13246 fatal_error ("internal error: builtin function %s had an unexpected "
13247 "return type %s", name
, GET_MODE_NAME (h
.mode
[0]));
13249 for (i
= 0; i
< num_args
; i
++)
13251 int m
= (int) h
.mode
[i
+1];
13252 int uns_p
= h
.uns_p
[i
+1];
13254 arg_type
[i
] = builtin_mode_to_type
[m
][uns_p
];
13255 if (!arg_type
[i
] && uns_p
)
13256 arg_type
[i
] = builtin_mode_to_type
[m
][0];
13259 fatal_error ("internal error: builtin function %s, argument %d "
13260 "had unexpected argument type %s", name
, i
,
13261 GET_MODE_NAME (m
));
13264 found
= htab_find_slot (builtin_hash_table
, &h
, INSERT
);
13265 if (*found
== NULL
)
13267 h2
= ggc_alloc_builtin_hash_struct ();
13269 *found
= (void *)h2
;
13270 args
= void_list_node
;
13272 for (i
= num_args
- 1; i
>= 0; i
--)
13273 args
= tree_cons (NULL_TREE
, arg_type
[i
], args
);
13275 h2
->type
= build_function_type (ret_type
, args
);
13278 return ((struct builtin_hash_struct
*)(*found
))->type
;
13282 rs6000_common_init_builtins (void)
13284 const struct builtin_description
*d
;
13287 tree opaque_ftype_opaque
= NULL_TREE
;
13288 tree opaque_ftype_opaque_opaque
= NULL_TREE
;
13289 tree opaque_ftype_opaque_opaque_opaque
= NULL_TREE
;
13290 tree v2si_ftype_qi
= NULL_TREE
;
13291 tree v2si_ftype_v2si_qi
= NULL_TREE
;
13292 tree v2si_ftype_int_qi
= NULL_TREE
;
13294 if (!TARGET_PAIRED_FLOAT
)
13296 builtin_mode_to_type
[V2SImode
][0] = opaque_V2SI_type_node
;
13297 builtin_mode_to_type
[V2SFmode
][0] = opaque_V2SF_type_node
;
13300 /* Add the ternary operators. */
13302 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
13305 int mask
= d
->mask
;
13307 if ((mask
!= 0 && (mask
& target_flags
) == 0)
13308 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
13311 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13312 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13313 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13314 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
13316 if (! (type
= opaque_ftype_opaque_opaque_opaque
))
13317 type
= opaque_ftype_opaque_opaque_opaque
13318 = build_function_type_list (opaque_V4SI_type_node
,
13319 opaque_V4SI_type_node
,
13320 opaque_V4SI_type_node
,
13321 opaque_V4SI_type_node
,
13326 enum insn_code icode
= d
->icode
;
13327 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
13330 type
= builtin_function_type (insn_data
[icode
].operand
[0].mode
,
13331 insn_data
[icode
].operand
[1].mode
,
13332 insn_data
[icode
].operand
[2].mode
,
13333 insn_data
[icode
].operand
[3].mode
,
13337 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13340 /* Add the binary operators. */
13342 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
13344 enum machine_mode mode0
, mode1
, mode2
;
13346 int mask
= d
->mask
;
13348 if ((mask
!= 0 && (mask
& target_flags
) == 0)
13349 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
13352 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13353 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13354 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13355 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
13357 if (! (type
= opaque_ftype_opaque_opaque
))
13358 type
= opaque_ftype_opaque_opaque
13359 = build_function_type_list (opaque_V4SI_type_node
,
13360 opaque_V4SI_type_node
,
13361 opaque_V4SI_type_node
,
13366 enum insn_code icode
= d
->icode
;
13367 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
13370 mode0
= insn_data
[icode
].operand
[0].mode
;
13371 mode1
= insn_data
[icode
].operand
[1].mode
;
13372 mode2
= insn_data
[icode
].operand
[2].mode
;
13374 if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
13376 if (! (type
= v2si_ftype_v2si_qi
))
13377 type
= v2si_ftype_v2si_qi
13378 = build_function_type_list (opaque_V2SI_type_node
,
13379 opaque_V2SI_type_node
,
13384 else if (mode0
== V2SImode
&& GET_MODE_CLASS (mode1
) == MODE_INT
13385 && mode2
== QImode
)
13387 if (! (type
= v2si_ftype_int_qi
))
13388 type
= v2si_ftype_int_qi
13389 = build_function_type_list (opaque_V2SI_type_node
,
13396 type
= builtin_function_type (mode0
, mode1
, mode2
, VOIDmode
,
13400 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13403 /* Add the simple unary operators. */
13404 d
= (struct builtin_description
*) bdesc_1arg
;
13405 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
13407 enum machine_mode mode0
, mode1
;
13409 int mask
= d
->mask
;
13411 if ((mask
!= 0 && (mask
& target_flags
) == 0)
13412 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
13415 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13416 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
13417 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
13418 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
13420 if (! (type
= opaque_ftype_opaque
))
13421 type
= opaque_ftype_opaque
13422 = build_function_type_list (opaque_V4SI_type_node
,
13423 opaque_V4SI_type_node
,
13428 enum insn_code icode
= d
->icode
;
13429 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
13432 mode0
= insn_data
[icode
].operand
[0].mode
;
13433 mode1
= insn_data
[icode
].operand
[1].mode
;
13435 if (mode0
== V2SImode
&& mode1
== QImode
)
13437 if (! (type
= v2si_ftype_qi
))
13438 type
= v2si_ftype_qi
13439 = build_function_type_list (opaque_V2SI_type_node
,
13445 type
= builtin_function_type (mode0
, mode1
, VOIDmode
, VOIDmode
,
13449 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
13454 rs6000_init_libfuncs (void)
13456 if (DEFAULT_ABI
!= ABI_V4
&& TARGET_XCOFF
13457 && !TARGET_POWER2
&& !TARGET_POWERPC
)
13459 /* AIX library routines for float->int conversion. */
13460 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
13461 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
13462 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
13463 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
13466 if (!TARGET_IEEEQUAD
)
13467 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13468 if (!TARGET_XL_COMPAT
)
13470 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
13471 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
13472 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
13473 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
13475 if (!(TARGET_HARD_FLOAT
&& (TARGET_FPRS
|| TARGET_E500_DOUBLE
)))
13477 set_optab_libfunc (neg_optab
, TFmode
, "__gcc_qneg");
13478 set_optab_libfunc (eq_optab
, TFmode
, "__gcc_qeq");
13479 set_optab_libfunc (ne_optab
, TFmode
, "__gcc_qne");
13480 set_optab_libfunc (gt_optab
, TFmode
, "__gcc_qgt");
13481 set_optab_libfunc (ge_optab
, TFmode
, "__gcc_qge");
13482 set_optab_libfunc (lt_optab
, TFmode
, "__gcc_qlt");
13483 set_optab_libfunc (le_optab
, TFmode
, "__gcc_qle");
13485 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "__gcc_stoq");
13486 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "__gcc_dtoq");
13487 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "__gcc_qtos");
13488 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "__gcc_qtod");
13489 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "__gcc_qtoi");
13490 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "__gcc_qtou");
13491 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "__gcc_itoq");
13492 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "__gcc_utoq");
13495 if (!(TARGET_HARD_FLOAT
&& TARGET_FPRS
))
13496 set_optab_libfunc (unord_optab
, TFmode
, "__gcc_qunord");
13500 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
13501 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
13502 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
13503 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
13507 /* 32-bit SVR4 quad floating point routines. */
13509 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
13510 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
13511 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
13512 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
13513 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
13514 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
13515 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
13517 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
13518 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
13519 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
13520 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
13521 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
13522 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
13524 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
13525 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
13526 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
13527 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
13528 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
13529 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
13530 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
13531 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "_q_utoq");
13536 /* Expand a block clear operation, and return 1 if successful. Return 0
13537 if we should let the compiler generate normal code.
13539 operands[0] is the destination
13540 operands[1] is the length
13541 operands[3] is the alignment */
13544 expand_block_clear (rtx operands
[])
13546 rtx orig_dest
= operands
[0];
13547 rtx bytes_rtx
= operands
[1];
13548 rtx align_rtx
= operands
[3];
13549 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
13550 HOST_WIDE_INT align
;
13551 HOST_WIDE_INT bytes
;
13556 /* If this is not a fixed size move, just call memcpy */
13560 /* This must be a fixed size alignment */
13561 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
13562 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
13564 /* Anything to clear? */
13565 bytes
= INTVAL (bytes_rtx
);
13569 /* Use the builtin memset after a point, to avoid huge code bloat.
13570 When optimize_size, avoid any significant code bloat; calling
13571 memset is about 4 instructions, so allow for one instruction to
13572 load zero and three to do clearing. */
13573 if (TARGET_ALTIVEC
&& align
>= 128)
13575 else if (TARGET_POWERPC64
&& align
>= 32)
13577 else if (TARGET_SPE
&& align
>= 64)
13582 if (optimize_size
&& bytes
> 3 * clear_step
)
13584 if (! optimize_size
&& bytes
> 8 * clear_step
)
13587 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
13589 enum machine_mode mode
= BLKmode
;
13592 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
13597 else if (bytes
>= 8 && TARGET_SPE
&& align
>= 64)
13602 else if (bytes
>= 8 && TARGET_POWERPC64
13603 /* 64-bit loads and stores require word-aligned
13605 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
13610 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
13611 { /* move 4 bytes */
13615 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
13616 { /* move 2 bytes */
13620 else /* move 1 byte at a time */
13626 dest
= adjust_address (orig_dest
, mode
, offset
);
13628 emit_move_insn (dest
, CONST0_RTX (mode
));
13635 /* Expand a block move operation, and return 1 if successful. Return 0
13636 if we should let the compiler generate normal code.
13638 operands[0] is the destination
13639 operands[1] is the source
13640 operands[2] is the length
13641 operands[3] is the alignment */
13643 #define MAX_MOVE_REG 4
13646 expand_block_move (rtx operands
[])
13648 rtx orig_dest
= operands
[0];
13649 rtx orig_src
= operands
[1];
13650 rtx bytes_rtx
= operands
[2];
13651 rtx align_rtx
= operands
[3];
13652 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
13657 rtx stores
[MAX_MOVE_REG
];
13660 /* If this is not a fixed size move, just call memcpy */
13664 /* This must be a fixed size alignment */
13665 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
13666 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
13668 /* Anything to move? */
13669 bytes
= INTVAL (bytes_rtx
);
13673 if (bytes
> rs6000_block_move_inline_limit
)
13676 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
13679 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
13680 rtx (*mov
) (rtx
, rtx
);
13682 enum machine_mode mode
= BLKmode
;
13685 /* Altivec first, since it will be faster than a string move
13686 when it applies, and usually not significantly larger. */
13687 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
13691 gen_func
.mov
= gen_movv4si
;
13693 else if (TARGET_SPE
&& bytes
>= 8 && align
>= 64)
13697 gen_func
.mov
= gen_movv2si
;
13699 else if (TARGET_STRING
13700 && bytes
> 24 /* move up to 32 bytes at a time */
13706 && ! fixed_regs
[10]
13707 && ! fixed_regs
[11]
13708 && ! fixed_regs
[12])
13710 move_bytes
= (bytes
> 32) ? 32 : bytes
;
13711 gen_func
.movmemsi
= gen_movmemsi_8reg
;
13713 else if (TARGET_STRING
13714 && bytes
> 16 /* move up to 24 bytes at a time */
13720 && ! fixed_regs
[10])
13722 move_bytes
= (bytes
> 24) ? 24 : bytes
;
13723 gen_func
.movmemsi
= gen_movmemsi_6reg
;
13725 else if (TARGET_STRING
13726 && bytes
> 8 /* move up to 16 bytes at a time */
13730 && ! fixed_regs
[8])
13732 move_bytes
= (bytes
> 16) ? 16 : bytes
;
13733 gen_func
.movmemsi
= gen_movmemsi_4reg
;
13735 else if (bytes
>= 8 && TARGET_POWERPC64
13736 /* 64-bit loads and stores require word-aligned
13738 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
13742 gen_func
.mov
= gen_movdi
;
13744 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
13745 { /* move up to 8 bytes at a time */
13746 move_bytes
= (bytes
> 8) ? 8 : bytes
;
13747 gen_func
.movmemsi
= gen_movmemsi_2reg
;
13749 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
13750 { /* move 4 bytes */
13753 gen_func
.mov
= gen_movsi
;
13755 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
13756 { /* move 2 bytes */
13759 gen_func
.mov
= gen_movhi
;
13761 else if (TARGET_STRING
&& bytes
> 1)
13762 { /* move up to 4 bytes at a time */
13763 move_bytes
= (bytes
> 4) ? 4 : bytes
;
13764 gen_func
.movmemsi
= gen_movmemsi_1reg
;
13766 else /* move 1 byte at a time */
13770 gen_func
.mov
= gen_movqi
;
13773 src
= adjust_address (orig_src
, mode
, offset
);
13774 dest
= adjust_address (orig_dest
, mode
, offset
);
13776 if (mode
!= BLKmode
)
13778 rtx tmp_reg
= gen_reg_rtx (mode
);
13780 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
13781 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
13784 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
13787 for (i
= 0; i
< num_reg
; i
++)
13788 emit_insn (stores
[i
]);
13792 if (mode
== BLKmode
)
13794 /* Move the address into scratch registers. The movmemsi
13795 patterns require zero offset. */
13796 if (!REG_P (XEXP (src
, 0)))
13798 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
13799 src
= replace_equiv_address (src
, src_reg
);
13801 set_mem_size (src
, GEN_INT (move_bytes
));
13803 if (!REG_P (XEXP (dest
, 0)))
13805 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
13806 dest
= replace_equiv_address (dest
, dest_reg
);
13808 set_mem_size (dest
, GEN_INT (move_bytes
));
13810 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
13811 GEN_INT (move_bytes
& 31),
13820 /* Return a string to perform a load_multiple operation.
13821 operands[0] is the vector.
13822 operands[1] is the source address.
13823 operands[2] is the first destination register. */
13826 rs6000_output_load_multiple (rtx operands
[3])
13828 /* We have to handle the case where the pseudo used to contain the address
13829 is assigned to one of the output registers. */
13831 int words
= XVECLEN (operands
[0], 0);
13834 if (XVECLEN (operands
[0], 0) == 1)
13835 return "{l|lwz} %2,0(%1)";
13837 for (i
= 0; i
< words
; i
++)
13838 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
13839 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
13843 xop
[0] = GEN_INT (4 * (words
-1));
13844 xop
[1] = operands
[1];
13845 xop
[2] = operands
[2];
13846 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
13851 xop
[0] = GEN_INT (4 * (words
-1));
13852 xop
[1] = operands
[1];
13853 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
13854 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
);
13859 for (j
= 0; j
< words
; j
++)
13862 xop
[0] = GEN_INT (j
* 4);
13863 xop
[1] = operands
[1];
13864 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
13865 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
13867 xop
[0] = GEN_INT (i
* 4);
13868 xop
[1] = operands
[1];
13869 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
13874 return "{lsi|lswi} %2,%1,%N0";
13878 /* A validation routine: say whether CODE, a condition code, and MODE
13879 match. The other alternatives either don't make sense or should
13880 never be generated. */
13883 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
13885 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
13886 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
13887 && GET_MODE_CLASS (mode
) == MODE_CC
);
13889 /* These don't make sense. */
13890 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
13891 || mode
!= CCUNSmode
);
13893 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
13894 || mode
== CCUNSmode
);
13896 gcc_assert (mode
== CCFPmode
13897 || (code
!= ORDERED
&& code
!= UNORDERED
13898 && code
!= UNEQ
&& code
!= LTGT
13899 && code
!= UNGT
&& code
!= UNLT
13900 && code
!= UNGE
&& code
!= UNLE
));
13902 /* These should never be generated except for
13903 flag_finite_math_only. */
13904 gcc_assert (mode
!= CCFPmode
13905 || flag_finite_math_only
13906 || (code
!= LE
&& code
!= GE
13907 && code
!= UNEQ
&& code
!= LTGT
13908 && code
!= UNGT
&& code
!= UNLT
));
13910 /* These are invalid; the information is not there. */
13911 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
13915 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13916 mask required to convert the result of a rotate insn into a shift
13917 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13920 includes_lshift_p (rtx shiftop
, rtx andop
)
13922 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
13924 shift_mask
<<= INTVAL (shiftop
);
13926 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
13929 /* Similar, but for right shift. */
13932 includes_rshift_p (rtx shiftop
, rtx andop
)
13934 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
13936 shift_mask
>>= INTVAL (shiftop
);
13938 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
13941 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13942 to perform a left shift. It must have exactly SHIFTOP least
13943 significant 0's, then one or more 1's, then zero or more 0's. */
13946 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
13948 if (GET_CODE (andop
) == CONST_INT
)
13950 HOST_WIDE_INT c
, lsb
, shift_mask
;
13952 c
= INTVAL (andop
);
13953 if (c
== 0 || c
== ~0)
13957 shift_mask
<<= INTVAL (shiftop
);
13959 /* Find the least significant one bit. */
13962 /* It must coincide with the LSB of the shift mask. */
13963 if (-lsb
!= shift_mask
)
13966 /* Invert to look for the next transition (if any). */
13969 /* Remove the low group of ones (originally low group of zeros). */
13972 /* Again find the lsb, and check we have all 1's above. */
13976 else if (GET_CODE (andop
) == CONST_DOUBLE
13977 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
13979 HOST_WIDE_INT low
, high
, lsb
;
13980 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
13982 low
= CONST_DOUBLE_LOW (andop
);
13983 if (HOST_BITS_PER_WIDE_INT
< 64)
13984 high
= CONST_DOUBLE_HIGH (andop
);
13986 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
13987 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
13990 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
13992 shift_mask_high
= ~0;
13993 if (INTVAL (shiftop
) > 32)
13994 shift_mask_high
<<= INTVAL (shiftop
) - 32;
13996 lsb
= high
& -high
;
13998 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
14004 lsb
= high
& -high
;
14005 return high
== -lsb
;
14008 shift_mask_low
= ~0;
14009 shift_mask_low
<<= INTVAL (shiftop
);
14013 if (-lsb
!= shift_mask_low
)
14016 if (HOST_BITS_PER_WIDE_INT
< 64)
14021 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
14023 lsb
= high
& -high
;
14024 return high
== -lsb
;
14028 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
14034 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14035 to perform a left shift. It must have SHIFTOP or more least
14036 significant 0's, with the remainder of the word 1's. */
14039 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
14041 if (GET_CODE (andop
) == CONST_INT
)
14043 HOST_WIDE_INT c
, lsb
, shift_mask
;
14046 shift_mask
<<= INTVAL (shiftop
);
14047 c
= INTVAL (andop
);
14049 /* Find the least significant one bit. */
14052 /* It must be covered by the shift mask.
14053 This test also rejects c == 0. */
14054 if ((lsb
& shift_mask
) == 0)
14057 /* Check we have all 1's above the transition, and reject all 1's. */
14058 return c
== -lsb
&& lsb
!= 1;
14060 else if (GET_CODE (andop
) == CONST_DOUBLE
14061 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
14063 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
14065 low
= CONST_DOUBLE_LOW (andop
);
14067 if (HOST_BITS_PER_WIDE_INT
< 64)
14069 HOST_WIDE_INT high
, shift_mask_high
;
14071 high
= CONST_DOUBLE_HIGH (andop
);
14075 shift_mask_high
= ~0;
14076 if (INTVAL (shiftop
) > 32)
14077 shift_mask_high
<<= INTVAL (shiftop
) - 32;
14079 lsb
= high
& -high
;
14081 if ((lsb
& shift_mask_high
) == 0)
14084 return high
== -lsb
;
14090 shift_mask_low
= ~0;
14091 shift_mask_low
<<= INTVAL (shiftop
);
14095 if ((lsb
& shift_mask_low
) == 0)
14098 return low
== -lsb
&& lsb
!= 1;
14104 /* Return 1 if operands will generate a valid arguments to rlwimi
14105 instruction for insert with right shift in 64-bit mode. The mask may
14106 not start on the first bit or stop on the last bit because wrap-around
14107 effects of instruction do not correspond to semantics of RTL insn. */
14110 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
14112 if (INTVAL (startop
) > 32
14113 && INTVAL (startop
) < 64
14114 && INTVAL (sizeop
) > 1
14115 && INTVAL (sizeop
) + INTVAL (startop
) < 64
14116 && INTVAL (shiftop
) > 0
14117 && INTVAL (sizeop
) + INTVAL (shiftop
) < 32
14118 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
14124 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14125 for lfq and stfq insns iff the registers are hard registers. */
14128 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
14130 /* We might have been passed a SUBREG. */
14131 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
14134 /* We might have been passed non floating point registers. */
14135 if (!FP_REGNO_P (REGNO (reg1
))
14136 || !FP_REGNO_P (REGNO (reg2
)))
14139 return (REGNO (reg1
) == REGNO (reg2
) - 1);
14142 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14143 addr1 and addr2 must be in consecutive memory locations
14144 (addr2 == addr1 + 8). */
14147 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
14150 unsigned int reg1
, reg2
;
14151 int offset1
, offset2
;
14153 /* The mems cannot be volatile. */
14154 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
14157 addr1
= XEXP (mem1
, 0);
14158 addr2
= XEXP (mem2
, 0);
14160 /* Extract an offset (if used) from the first addr. */
14161 if (GET_CODE (addr1
) == PLUS
)
14163 /* If not a REG, return zero. */
14164 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
14168 reg1
= REGNO (XEXP (addr1
, 0));
14169 /* The offset must be constant! */
14170 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
14172 offset1
= INTVAL (XEXP (addr1
, 1));
14175 else if (GET_CODE (addr1
) != REG
)
14179 reg1
= REGNO (addr1
);
14180 /* This was a simple (mem (reg)) expression. Offset is 0. */
14184 /* And now for the second addr. */
14185 if (GET_CODE (addr2
) == PLUS
)
14187 /* If not a REG, return zero. */
14188 if (GET_CODE (XEXP (addr2
, 0)) != REG
)
14192 reg2
= REGNO (XEXP (addr2
, 0));
14193 /* The offset must be constant. */
14194 if (GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
14196 offset2
= INTVAL (XEXP (addr2
, 1));
14199 else if (GET_CODE (addr2
) != REG
)
14203 reg2
= REGNO (addr2
);
14204 /* This was a simple (mem (reg)) expression. Offset is 0. */
14208 /* Both of these must have the same base register. */
14212 /* The offset for the second addr must be 8 more than the first addr. */
14213 if (offset2
!= offset1
+ 8)
14216 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14223 rs6000_secondary_memory_needed_rtx (enum machine_mode mode
)
14225 static bool eliminated
= false;
14228 if (mode
!= SDmode
)
14229 ret
= assign_stack_local (mode
, GET_MODE_SIZE (mode
), 0);
14232 rtx mem
= cfun
->machine
->sdmode_stack_slot
;
14233 gcc_assert (mem
!= NULL_RTX
);
14237 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
14238 cfun
->machine
->sdmode_stack_slot
= mem
;
14244 if (TARGET_DEBUG_ADDR
)
14246 fprintf (stderr
, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14247 GET_MODE_NAME (mode
));
14249 fprintf (stderr
, "\tNULL_RTX\n");
14258 rs6000_check_sdmode (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
14260 /* Don't walk into types. */
14261 if (*tp
== NULL_TREE
|| *tp
== error_mark_node
|| TYPE_P (*tp
))
14263 *walk_subtrees
= 0;
14267 switch (TREE_CODE (*tp
))
14276 case VIEW_CONVERT_EXPR
:
14277 if (TYPE_MODE (TREE_TYPE (*tp
)) == SDmode
)
14287 enum reload_reg_type
{
14289 VECTOR_REGISTER_TYPE
,
14290 OTHER_REGISTER_TYPE
14293 static enum reload_reg_type
14294 rs6000_reload_register_type (enum reg_class rclass
)
14300 return GPR_REGISTER_TYPE
;
14305 return VECTOR_REGISTER_TYPE
;
14308 return OTHER_REGISTER_TYPE
;
14312 /* Inform reload about cases where moving X with a mode MODE to a register in
14313 RCLASS requires an extra scratch or immediate register. Return the class
14314 needed for the immediate register.
14316 For VSX and Altivec, we may need a register to convert sp+offset into
14320 rs6000_secondary_reload (bool in_p
,
14322 reg_class_t rclass_i
,
14323 enum machine_mode mode
,
14324 secondary_reload_info
*sri
)
14326 enum reg_class rclass
= (enum reg_class
) rclass_i
;
14327 reg_class_t ret
= ALL_REGS
;
14328 enum insn_code icode
;
14329 bool default_p
= false;
14331 sri
->icode
= CODE_FOR_nothing
;
14333 /* Convert vector loads and stores into gprs to use an additional base
14335 icode
= rs6000_vector_reload
[mode
][in_p
!= false];
14336 if (icode
!= CODE_FOR_nothing
)
14339 sri
->icode
= CODE_FOR_nothing
;
14340 sri
->extra_cost
= 0;
14342 if (GET_CODE (x
) == MEM
)
14344 rtx addr
= XEXP (x
, 0);
14346 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14347 an extra register in that case, but it would need an extra
14348 register if the addressing is reg+reg or (reg+reg)&(-16). */
14349 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
)
14351 if (!legitimate_indirect_address_p (addr
, false)
14352 && !rs6000_legitimate_offset_address_p (TImode
, addr
, false))
14354 sri
->icode
= icode
;
14355 /* account for splitting the loads, and converting the
14356 address from reg+reg to reg. */
14357 sri
->extra_cost
= (((TARGET_64BIT
) ? 3 : 5)
14358 + ((GET_CODE (addr
) == AND
) ? 1 : 0));
14361 /* Loads to and stores from vector registers can only do reg+reg
14362 addressing. Altivec registers can also do (reg+reg)&(-16). */
14363 else if (rclass
== VSX_REGS
|| rclass
== ALTIVEC_REGS
14364 || rclass
== FLOAT_REGS
|| rclass
== NO_REGS
)
14366 if (!VECTOR_MEM_ALTIVEC_P (mode
)
14367 && GET_CODE (addr
) == AND
14368 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
14369 && INTVAL (XEXP (addr
, 1)) == -16
14370 && (legitimate_indirect_address_p (XEXP (addr
, 0), false)
14371 || legitimate_indexed_address_p (XEXP (addr
, 0), false)))
14373 sri
->icode
= icode
;
14374 sri
->extra_cost
= ((GET_CODE (XEXP (addr
, 0)) == PLUS
)
14377 else if (!legitimate_indirect_address_p (addr
, false)
14378 && (rclass
== NO_REGS
14379 || !legitimate_indexed_address_p (addr
, false)))
14381 sri
->icode
= icode
;
14382 sri
->extra_cost
= 1;
14385 icode
= CODE_FOR_nothing
;
14387 /* Any other loads, including to pseudo registers which haven't been
14388 assigned to a register yet, default to require a scratch
14392 sri
->icode
= icode
;
14393 sri
->extra_cost
= 2;
14396 else if (REG_P (x
))
14398 int regno
= true_regnum (x
);
14400 icode
= CODE_FOR_nothing
;
14401 if (regno
< 0 || regno
>= FIRST_PSEUDO_REGISTER
)
14405 enum reg_class xclass
= REGNO_REG_CLASS (regno
);
14406 enum reload_reg_type rtype1
= rs6000_reload_register_type (rclass
);
14407 enum reload_reg_type rtype2
= rs6000_reload_register_type (xclass
);
14409 /* If memory is needed, use default_secondary_reload to create the
14411 if (rtype1
!= rtype2
|| rtype1
== OTHER_REGISTER_TYPE
)
14424 ret
= default_secondary_reload (in_p
, x
, rclass
, mode
, sri
);
14426 gcc_assert (ret
!= ALL_REGS
);
14428 if (TARGET_DEBUG_ADDR
)
14431 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14433 reg_class_names
[ret
],
14434 in_p
? "true" : "false",
14435 reg_class_names
[rclass
],
14436 GET_MODE_NAME (mode
));
14439 fprintf (stderr
, ", default secondary reload");
14441 if (sri
->icode
!= CODE_FOR_nothing
)
14442 fprintf (stderr
, ", reload func = %s, extra cost = %d\n",
14443 insn_data
[sri
->icode
].name
, sri
->extra_cost
);
14445 fprintf (stderr
, "\n");
14453 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14454 to SP+reg addressing. */
14457 rs6000_secondary_reload_inner (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
14459 int regno
= true_regnum (reg
);
14460 enum machine_mode mode
= GET_MODE (reg
);
14461 enum reg_class rclass
;
14463 rtx and_op2
= NULL_RTX
;
14466 rtx scratch_or_premodify
= scratch
;
14470 if (TARGET_DEBUG_ADDR
)
14472 fprintf (stderr
, "\nrs6000_secondary_reload_inner, type = %s\n",
14473 store_p
? "store" : "load");
14474 fprintf (stderr
, "reg:\n");
14476 fprintf (stderr
, "mem:\n");
14478 fprintf (stderr
, "scratch:\n");
14479 debug_rtx (scratch
);
14482 gcc_assert (regno
>= 0 && regno
< FIRST_PSEUDO_REGISTER
);
14483 gcc_assert (GET_CODE (mem
) == MEM
);
14484 rclass
= REGNO_REG_CLASS (regno
);
14485 addr
= XEXP (mem
, 0);
14489 /* GPRs can handle reg + small constant, all other addresses need to use
14490 the scratch register. */
14493 if (GET_CODE (addr
) == AND
)
14495 and_op2
= XEXP (addr
, 1);
14496 addr
= XEXP (addr
, 0);
14499 if (GET_CODE (addr
) == PRE_MODIFY
)
14501 scratch_or_premodify
= XEXP (addr
, 0);
14502 gcc_assert (REG_P (scratch_or_premodify
));
14503 gcc_assert (GET_CODE (XEXP (addr
, 1)) == PLUS
);
14504 addr
= XEXP (addr
, 1);
14507 if (GET_CODE (addr
) == PLUS
14508 && (!rs6000_legitimate_offset_address_p (TImode
, addr
, false)
14509 || and_op2
!= NULL_RTX
))
14511 addr_op1
= XEXP (addr
, 0);
14512 addr_op2
= XEXP (addr
, 1);
14513 gcc_assert (legitimate_indirect_address_p (addr_op1
, false));
14515 if (!REG_P (addr_op2
)
14516 && (GET_CODE (addr_op2
) != CONST_INT
14517 || !satisfies_constraint_I (addr_op2
)))
14519 if (TARGET_DEBUG_ADDR
)
14522 "\nMove plus addr to register %s, mode = %s: ",
14523 rs6000_reg_names
[REGNO (scratch
)],
14524 GET_MODE_NAME (mode
));
14525 debug_rtx (addr_op2
);
14527 rs6000_emit_move (scratch
, addr_op2
, Pmode
);
14528 addr_op2
= scratch
;
14531 emit_insn (gen_rtx_SET (VOIDmode
,
14532 scratch_or_premodify
,
14533 gen_rtx_PLUS (Pmode
,
14537 addr
= scratch_or_premodify
;
14538 scratch_or_premodify
= scratch
;
14540 else if (!legitimate_indirect_address_p (addr
, false)
14541 && !rs6000_legitimate_offset_address_p (TImode
, addr
, false))
14543 if (TARGET_DEBUG_ADDR
)
14545 fprintf (stderr
, "\nMove addr to register %s, mode = %s: ",
14546 rs6000_reg_names
[REGNO (scratch_or_premodify
)],
14547 GET_MODE_NAME (mode
));
14550 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
14551 addr
= scratch_or_premodify
;
14552 scratch_or_premodify
= scratch
;
14556 /* Float/Altivec registers can only handle reg+reg addressing. Move
14557 other addresses into a scratch register. */
14562 /* With float regs, we need to handle the AND ourselves, since we can't
14563 use the Altivec instruction with an implicit AND -16. Allow scalar
14564 loads to float registers to use reg+offset even if VSX. */
14565 if (GET_CODE (addr
) == AND
14566 && (rclass
!= ALTIVEC_REGS
|| GET_MODE_SIZE (mode
) != 16
14567 || GET_CODE (XEXP (addr
, 1)) != CONST_INT
14568 || INTVAL (XEXP (addr
, 1)) != -16
14569 || !VECTOR_MEM_ALTIVEC_P (mode
)))
14571 and_op2
= XEXP (addr
, 1);
14572 addr
= XEXP (addr
, 0);
14575 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14576 as the address later. */
14577 if (GET_CODE (addr
) == PRE_MODIFY
14578 && (!VECTOR_MEM_VSX_P (mode
)
14579 || and_op2
!= NULL_RTX
14580 || !legitimate_indexed_address_p (XEXP (addr
, 1), false)))
14582 scratch_or_premodify
= XEXP (addr
, 0);
14583 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify
,
14585 gcc_assert (GET_CODE (XEXP (addr
, 1)) == PLUS
);
14586 addr
= XEXP (addr
, 1);
14589 if (legitimate_indirect_address_p (addr
, false) /* reg */
14590 || legitimate_indexed_address_p (addr
, false) /* reg+reg */
14591 || GET_CODE (addr
) == PRE_MODIFY
/* VSX pre-modify */
14592 || (GET_CODE (addr
) == AND
/* Altivec memory */
14593 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
14594 && INTVAL (XEXP (addr
, 1)) == -16
14595 && VECTOR_MEM_ALTIVEC_P (mode
))
14596 || (rclass
== FLOAT_REGS
/* legacy float mem */
14597 && GET_MODE_SIZE (mode
) == 8
14598 && and_op2
== NULL_RTX
14599 && scratch_or_premodify
== scratch
14600 && rs6000_legitimate_offset_address_p (mode
, addr
, false)))
14603 else if (GET_CODE (addr
) == PLUS
)
14605 addr_op1
= XEXP (addr
, 0);
14606 addr_op2
= XEXP (addr
, 1);
14607 gcc_assert (REG_P (addr_op1
));
14609 if (TARGET_DEBUG_ADDR
)
14611 fprintf (stderr
, "\nMove plus addr to register %s, mode = %s: ",
14612 rs6000_reg_names
[REGNO (scratch
)], GET_MODE_NAME (mode
));
14613 debug_rtx (addr_op2
);
14615 rs6000_emit_move (scratch
, addr_op2
, Pmode
);
14616 emit_insn (gen_rtx_SET (VOIDmode
,
14617 scratch_or_premodify
,
14618 gen_rtx_PLUS (Pmode
,
14621 addr
= scratch_or_premodify
;
14622 scratch_or_premodify
= scratch
;
14625 else if (GET_CODE (addr
) == SYMBOL_REF
|| GET_CODE (addr
) == CONST
14626 || GET_CODE (addr
) == CONST_INT
|| REG_P (addr
))
14628 if (TARGET_DEBUG_ADDR
)
14630 fprintf (stderr
, "\nMove addr to register %s, mode = %s: ",
14631 rs6000_reg_names
[REGNO (scratch_or_premodify
)],
14632 GET_MODE_NAME (mode
));
14636 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
14637 addr
= scratch_or_premodify
;
14638 scratch_or_premodify
= scratch
;
14642 gcc_unreachable ();
14647 gcc_unreachable ();
14650 /* If the original address involved a pre-modify that we couldn't use the VSX
14651 memory instruction with update, and we haven't taken care of already,
14652 store the address in the pre-modify register and use that as the
14654 if (scratch_or_premodify
!= scratch
&& scratch_or_premodify
!= addr
)
14656 emit_insn (gen_rtx_SET (VOIDmode
, scratch_or_premodify
, addr
));
14657 addr
= scratch_or_premodify
;
14660 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14661 memory instruction, recreate the AND now, including the clobber which is
14662 generated by the general ANDSI3/ANDDI3 patterns for the
14663 andi. instruction. */
14664 if (and_op2
!= NULL_RTX
)
14666 if (! legitimate_indirect_address_p (addr
, false))
14668 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, addr
));
14672 if (TARGET_DEBUG_ADDR
)
14674 fprintf (stderr
, "\nAnd addr to register %s, mode = %s: ",
14675 rs6000_reg_names
[REGNO (scratch
)], GET_MODE_NAME (mode
));
14676 debug_rtx (and_op2
);
14679 and_rtx
= gen_rtx_SET (VOIDmode
,
14681 gen_rtx_AND (Pmode
,
14685 cc_clobber
= gen_rtx_CLOBBER (CCmode
, gen_rtx_SCRATCH (CCmode
));
14686 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
14687 gen_rtvec (2, and_rtx
, cc_clobber
)));
14691 /* Adjust the address if it changed. */
14692 if (addr
!= XEXP (mem
, 0))
14694 mem
= change_address (mem
, mode
, addr
);
14695 if (TARGET_DEBUG_ADDR
)
14696 fprintf (stderr
, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14699 /* Now create the move. */
14701 emit_insn (gen_rtx_SET (VOIDmode
, mem
, reg
));
14703 emit_insn (gen_rtx_SET (VOIDmode
, reg
, mem
));
14708 /* Target hook to return the cover classes for Integrated Register Allocator.
14709 Cover classes is a set of non-intersected register classes covering all hard
14710 registers used for register allocation purpose. Any move between two
14711 registers of a cover class should be cheaper than load or store of the
14712 registers. The value is array of register classes with LIM_REG_CLASSES used
14715 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14716 account for the Altivec and Floating registers being subsets of the VSX
14717 register set under VSX, but distinct register sets on pre-VSX machines. */
14719 static const reg_class_t
*
14720 rs6000_ira_cover_classes (void)
14722 static const reg_class_t cover_pre_vsx
[] = IRA_COVER_CLASSES_PRE_VSX
;
14723 static const reg_class_t cover_vsx
[] = IRA_COVER_CLASSES_VSX
;
14725 return (TARGET_VSX
) ? cover_vsx
: cover_pre_vsx
;
14728 /* Allocate a 64-bit stack slot to be used for copying SDmode
14729 values through if this function has any SDmode references. */
14732 rs6000_alloc_sdmode_stack_slot (void)
14736 gimple_stmt_iterator gsi
;
14738 gcc_assert (cfun
->machine
->sdmode_stack_slot
== NULL_RTX
);
14741 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
14743 tree ret
= walk_gimple_op (gsi_stmt (gsi
), rs6000_check_sdmode
, NULL
);
14746 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
14747 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
14753 /* Check for any SDmode parameters of the function. */
14754 for (t
= DECL_ARGUMENTS (cfun
->decl
); t
; t
= DECL_CHAIN (t
))
14756 if (TREE_TYPE (t
) == error_mark_node
)
14759 if (TYPE_MODE (TREE_TYPE (t
)) == SDmode
14760 || TYPE_MODE (DECL_ARG_TYPE (t
)) == SDmode
)
14762 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
14763 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
14771 rs6000_instantiate_decls (void)
14773 if (cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
14774 instantiate_decl_rtl (cfun
->machine
->sdmode_stack_slot
);
14777 /* Given an rtx X being reloaded into a reg required to be
14778 in class CLASS, return the class of reg to actually use.
14779 In general this is just CLASS; but on some machines
14780 in some cases it is preferable to use a more restrictive class.
14782 On the RS/6000, we have to return NO_REGS when we want to reload a
14783 floating-point CONST_DOUBLE to force it to be copied to memory.
14785 We also don't want to reload integer values into floating-point
14786 registers if we can at all help it. In fact, this can
14787 cause reload to die, if it tries to generate a reload of CTR
14788 into a FP register and discovers it doesn't have the memory location
14791 ??? Would it be a good idea to have reload do the converse, that is
14792 try to reload floating modes into FP registers if possible?
14795 static enum reg_class
14796 rs6000_preferred_reload_class (rtx x
, enum reg_class rclass
)
14798 enum machine_mode mode
= GET_MODE (x
);
14800 if (VECTOR_UNIT_VSX_P (mode
)
14801 && x
== CONST0_RTX (mode
) && VSX_REG_CLASS_P (rclass
))
14804 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode
)
14805 && (rclass
== ALTIVEC_REGS
|| rclass
== VSX_REGS
)
14806 && easy_vector_constant (x
, mode
))
14807 return ALTIVEC_REGS
;
14809 if (CONSTANT_P (x
) && reg_classes_intersect_p (rclass
, FLOAT_REGS
))
14812 if (GET_MODE_CLASS (mode
) == MODE_INT
&& rclass
== NON_SPECIAL_REGS
)
14813 return GENERAL_REGS
;
14815 /* For VSX, prefer the traditional registers for 64-bit values because we can
14816 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14817 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14818 prefer Altivec loads.. */
14819 if (rclass
== VSX_REGS
)
14821 if (GET_MODE_SIZE (mode
) <= 8)
14824 if (VECTOR_UNIT_ALTIVEC_P (mode
) || VECTOR_MEM_ALTIVEC_P (mode
))
14825 return ALTIVEC_REGS
;
14833 /* Debug version of rs6000_preferred_reload_class. */
14834 static enum reg_class
14835 rs6000_debug_preferred_reload_class (rtx x
, enum reg_class rclass
)
14837 enum reg_class ret
= rs6000_preferred_reload_class (x
, rclass
);
14840 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14842 reg_class_names
[ret
], reg_class_names
[rclass
],
14843 GET_MODE_NAME (GET_MODE (x
)));
14849 /* If we are copying between FP or AltiVec registers and anything else, we need
14850 a memory location. The exception is when we are targeting ppc64 and the
14851 move to/from fpr to gpr instructions are available. Also, under VSX, you
14852 can copy vector registers from the FP register set to the Altivec register
14853 set and vice versa. */
14856 rs6000_secondary_memory_needed (enum reg_class class1
,
14857 enum reg_class class2
,
14858 enum machine_mode mode
)
14860 if (class1
== class2
)
14863 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14864 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14865 between these classes. But we need memory for other things that can go in
14866 FLOAT_REGS like SFmode. */
14868 && (VECTOR_MEM_VSX_P (mode
) || VECTOR_UNIT_VSX_P (mode
))
14869 && (class1
== VSX_REGS
|| class1
== ALTIVEC_REGS
14870 || class1
== FLOAT_REGS
))
14871 return (class2
!= VSX_REGS
&& class2
!= ALTIVEC_REGS
14872 && class2
!= FLOAT_REGS
);
14874 if (class1
== VSX_REGS
|| class2
== VSX_REGS
)
14877 if (class1
== FLOAT_REGS
14878 && (!TARGET_MFPGPR
|| !TARGET_POWERPC64
14879 || ((mode
!= DFmode
)
14880 && (mode
!= DDmode
)
14881 && (mode
!= DImode
))))
14884 if (class2
== FLOAT_REGS
14885 && (!TARGET_MFPGPR
|| !TARGET_POWERPC64
14886 || ((mode
!= DFmode
)
14887 && (mode
!= DDmode
)
14888 && (mode
!= DImode
))))
14891 if (class1
== ALTIVEC_REGS
|| class2
== ALTIVEC_REGS
)
14897 /* Debug version of rs6000_secondary_memory_needed. */
14899 rs6000_debug_secondary_memory_needed (enum reg_class class1
,
14900 enum reg_class class2
,
14901 enum machine_mode mode
)
14903 bool ret
= rs6000_secondary_memory_needed (class1
, class2
, mode
);
14906 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14907 "class2 = %s, mode = %s\n",
14908 ret
? "true" : "false", reg_class_names
[class1
],
14909 reg_class_names
[class2
], GET_MODE_NAME (mode
));
14914 /* Return the register class of a scratch register needed to copy IN into
14915 or out of a register in RCLASS in MODE. If it can be done directly,
14916 NO_REGS is returned. */
14918 static enum reg_class
14919 rs6000_secondary_reload_class (enum reg_class rclass
, enum machine_mode mode
,
14924 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
14926 && MACHOPIC_INDIRECT
14930 /* We cannot copy a symbolic operand directly into anything
14931 other than BASE_REGS for TARGET_ELF. So indicate that a
14932 register from BASE_REGS is needed as an intermediate
14935 On Darwin, pic addresses require a load from memory, which
14936 needs a base register. */
14937 if (rclass
!= BASE_REGS
14938 && (GET_CODE (in
) == SYMBOL_REF
14939 || GET_CODE (in
) == HIGH
14940 || GET_CODE (in
) == LABEL_REF
14941 || GET_CODE (in
) == CONST
))
14945 if (GET_CODE (in
) == REG
)
14947 regno
= REGNO (in
);
14948 if (regno
>= FIRST_PSEUDO_REGISTER
)
14950 regno
= true_regnum (in
);
14951 if (regno
>= FIRST_PSEUDO_REGISTER
)
14955 else if (GET_CODE (in
) == SUBREG
)
14957 regno
= true_regnum (in
);
14958 if (regno
>= FIRST_PSEUDO_REGISTER
)
14964 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14966 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
14967 || (regno
>= 0 && INT_REGNO_P (regno
)))
14970 /* Constants, memory, and FP registers can go into FP registers. */
14971 if ((regno
== -1 || FP_REGNO_P (regno
))
14972 && (rclass
== FLOAT_REGS
|| rclass
== NON_SPECIAL_REGS
))
14973 return (mode
!= SDmode
) ? NO_REGS
: GENERAL_REGS
;
14975 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14978 && (regno
== -1 || VSX_REGNO_P (regno
))
14979 && VSX_REG_CLASS_P (rclass
))
14982 /* Memory, and AltiVec registers can go into AltiVec registers. */
14983 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
14984 && rclass
== ALTIVEC_REGS
)
14987 /* We can copy among the CR registers. */
14988 if ((rclass
== CR_REGS
|| rclass
== CR0_REGS
)
14989 && regno
>= 0 && CR_REGNO_P (regno
))
14992 /* Otherwise, we need GENERAL_REGS. */
14993 return GENERAL_REGS
;
14996 /* Debug version of rs6000_secondary_reload_class. */
14997 static enum reg_class
14998 rs6000_debug_secondary_reload_class (enum reg_class rclass
,
14999 enum machine_mode mode
, rtx in
)
15001 enum reg_class ret
= rs6000_secondary_reload_class (rclass
, mode
, in
);
15003 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15004 "mode = %s, input rtx:\n",
15005 reg_class_names
[ret
], reg_class_names
[rclass
],
15006 GET_MODE_NAME (mode
));
15012 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15015 rs6000_cannot_change_mode_class (enum machine_mode from
,
15016 enum machine_mode to
,
15017 enum reg_class rclass
)
15019 unsigned from_size
= GET_MODE_SIZE (from
);
15020 unsigned to_size
= GET_MODE_SIZE (to
);
15022 if (from_size
!= to_size
)
15024 enum reg_class xclass
= (TARGET_VSX
) ? VSX_REGS
: FLOAT_REGS
;
15025 return ((from_size
< 8 || to_size
< 8 || TARGET_IEEEQUAD
)
15026 && reg_classes_intersect_p (xclass
, rclass
));
15029 if (TARGET_E500_DOUBLE
15030 && ((((to
) == DFmode
) + ((from
) == DFmode
)) == 1
15031 || (((to
) == TFmode
) + ((from
) == TFmode
)) == 1
15032 || (((to
) == DDmode
) + ((from
) == DDmode
)) == 1
15033 || (((to
) == TDmode
) + ((from
) == TDmode
)) == 1
15034 || (((to
) == DImode
) + ((from
) == DImode
)) == 1))
15037 /* Since the VSX register set includes traditional floating point registers
15038 and altivec registers, just check for the size being different instead of
15039 trying to check whether the modes are vector modes. Otherwise it won't
15040 allow say DF and DI to change classes. */
15041 if (TARGET_VSX
&& VSX_REG_CLASS_P (rclass
))
15042 return (from_size
!= 8 && from_size
!= 16);
15044 if (TARGET_ALTIVEC
&& rclass
== ALTIVEC_REGS
15045 && (ALTIVEC_VECTOR_MODE (from
) + ALTIVEC_VECTOR_MODE (to
)) == 1)
15048 if (TARGET_SPE
&& (SPE_VECTOR_MODE (from
) + SPE_VECTOR_MODE (to
)) == 1
15049 && reg_classes_intersect_p (GENERAL_REGS
, rclass
))
15055 /* Debug version of rs6000_cannot_change_mode_class. */
15057 rs6000_debug_cannot_change_mode_class (enum machine_mode from
,
15058 enum machine_mode to
,
15059 enum reg_class rclass
)
15061 bool ret
= rs6000_cannot_change_mode_class (from
, to
, rclass
);
15064 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15065 "to = %s, rclass = %s\n",
15066 ret
? "true" : "false",
15067 GET_MODE_NAME (from
), GET_MODE_NAME (to
),
15068 reg_class_names
[rclass
]);
15073 /* Given a comparison operation, return the bit number in CCR to test. We
15074 know this is a valid comparison.
15076 SCC_P is 1 if this is for an scc. That means that %D will have been
15077 used instead of %C, so the bits will be in different places.
15079 Return -1 if OP isn't a valid comparison for some reason. */
15082 ccr_bit (rtx op
, int scc_p
)
15084 enum rtx_code code
= GET_CODE (op
);
15085 enum machine_mode cc_mode
;
15090 if (!COMPARISON_P (op
))
15093 reg
= XEXP (op
, 0);
15095 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
15097 cc_mode
= GET_MODE (reg
);
15098 cc_regnum
= REGNO (reg
);
15099 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
15101 validate_condition_mode (code
, cc_mode
);
15103 /* When generating a sCOND operation, only positive conditions are
15106 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
15107 || code
== GTU
|| code
== LTU
);
15112 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
15114 return base_bit
+ 2;
15115 case GT
: case GTU
: case UNLE
:
15116 return base_bit
+ 1;
15117 case LT
: case LTU
: case UNGE
:
15119 case ORDERED
: case UNORDERED
:
15120 return base_bit
+ 3;
15123 /* If scc, we will have done a cror to put the bit in the
15124 unordered position. So test that bit. For integer, this is ! LT
15125 unless this is an scc insn. */
15126 return scc_p
? base_bit
+ 3 : base_bit
;
15129 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
15132 gcc_unreachable ();
15136 /* Return the GOT register. */
15139 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
15141 /* The second flow pass currently (June 1999) can't update
15142 regs_ever_live without disturbing other parts of the compiler, so
15143 update it here to make the prolog/epilogue code happy. */
15144 if (!can_create_pseudo_p ()
15145 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
))
15146 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM
, true);
15148 crtl
->uses_pic_offset_table
= 1;
15150 return pic_offset_table_rtx
;
15153 /* Function to init struct machine_function.
15154 This will be called, via a pointer variable,
15155 from push_function_context. */
15157 static struct machine_function
*
15158 rs6000_init_machine_status (void)
15160 return ggc_alloc_cleared_machine_function ();
15163 /* These macros test for integers and extract the low-order bits. */
15165 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15166 && GET_MODE (X) == VOIDmode)
15168 #define INT_LOWPART(X) \
15169 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15172 extract_MB (rtx op
)
15175 unsigned long val
= INT_LOWPART (op
);
15177 /* If the high bit is zero, the value is the first 1 bit we find
15179 if ((val
& 0x80000000) == 0)
15181 gcc_assert (val
& 0xffffffff);
15184 while (((val
<<= 1) & 0x80000000) == 0)
15189 /* If the high bit is set and the low bit is not, or the mask is all
15190 1's, the value is zero. */
15191 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
15194 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15197 while (((val
>>= 1) & 1) != 0)
15204 extract_ME (rtx op
)
15207 unsigned long val
= INT_LOWPART (op
);
15209 /* If the low bit is zero, the value is the first 1 bit we find from
15211 if ((val
& 1) == 0)
15213 gcc_assert (val
& 0xffffffff);
15216 while (((val
>>= 1) & 1) == 0)
15222 /* If the low bit is set and the high bit is not, or the mask is all
15223 1's, the value is 31. */
15224 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
15227 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15230 while (((val
<<= 1) & 0x80000000) != 0)
15236 /* Locate some local-dynamic symbol still in use by this function
15237 so that we can print its name in some tls_ld pattern. */
15239 static const char *
15240 rs6000_get_some_local_dynamic_name (void)
15244 if (cfun
->machine
->some_ld_name
)
15245 return cfun
->machine
->some_ld_name
;
15247 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
15249 && for_each_rtx (&PATTERN (insn
),
15250 rs6000_get_some_local_dynamic_name_1
, 0))
15251 return cfun
->machine
->some_ld_name
;
15253 gcc_unreachable ();
15256 /* Helper function for rs6000_get_some_local_dynamic_name. */
15259 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
15263 if (GET_CODE (x
) == SYMBOL_REF
)
15265 const char *str
= XSTR (x
, 0);
15266 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
15268 cfun
->machine
->some_ld_name
= str
;
15276 /* Write out a function code label. */
15279 rs6000_output_function_entry (FILE *file
, const char *fname
)
15281 if (fname
[0] != '.')
15283 switch (DEFAULT_ABI
)
15286 gcc_unreachable ();
15292 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
15301 RS6000_OUTPUT_BASENAME (file
, fname
);
15304 /* Print an operand. Recognize special options, documented below. */
15307 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15308 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15310 #define SMALL_DATA_RELOC "sda21"
15311 #define SMALL_DATA_REG 0
15315 print_operand (FILE *file
, rtx x
, int code
)
15319 unsigned HOST_WIDE_INT uval
;
15324 /* Write out an instruction after the call which may be replaced
15325 with glue code by the loader. This depends on the AIX version. */
15326 asm_fprintf (file
, RS6000_CALL_GLUE
);
15329 /* %a is output_address. */
15332 /* If X is a constant integer whose low-order 5 bits are zero,
15333 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15334 in the AIX assembler where "sri" with a zero shift count
15335 writes a trash instruction. */
15336 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
15343 /* If constant, low-order 16 bits of constant, unsigned.
15344 Otherwise, write normally. */
15346 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
15348 print_operand (file
, x
, 0);
15352 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15353 for 64-bit mask direction. */
15354 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
15357 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15361 /* X is a CR register. Print the number of the GT bit of the CR. */
15362 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15363 output_operand_lossage ("invalid %%c value");
15365 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
15369 /* Like 'J' but get to the GT bit only. */
15370 gcc_assert (GET_CODE (x
) == REG
);
15372 /* Bit 1 is GT bit. */
15373 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 1;
15375 /* Add one for shift count in rlinm for scc. */
15376 fprintf (file
, "%d", i
+ 1);
15380 /* X is a CR register. Print the number of the EQ bit of the CR */
15381 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15382 output_operand_lossage ("invalid %%E value");
15384 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
15388 /* X is a CR register. Print the shift count needed to move it
15389 to the high-order four bits. */
15390 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15391 output_operand_lossage ("invalid %%f value");
15393 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
15397 /* Similar, but print the count for the rotate in the opposite
15399 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15400 output_operand_lossage ("invalid %%F value");
15402 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
15406 /* X is a constant integer. If it is negative, print "m",
15407 otherwise print "z". This is to make an aze or ame insn. */
15408 if (GET_CODE (x
) != CONST_INT
)
15409 output_operand_lossage ("invalid %%G value");
15410 else if (INTVAL (x
) >= 0)
15417 /* If constant, output low-order five bits. Otherwise, write
15420 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
15422 print_operand (file
, x
, 0);
15426 /* If constant, output low-order six bits. Otherwise, write
15429 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
15431 print_operand (file
, x
, 0);
15435 /* Print `i' if this is a constant, else nothing. */
15441 /* Write the bit number in CCR for jump. */
15442 i
= ccr_bit (x
, 0);
15444 output_operand_lossage ("invalid %%j code");
15446 fprintf (file
, "%d", i
);
15450 /* Similar, but add one for shift count in rlinm for scc and pass
15451 scc flag to `ccr_bit'. */
15452 i
= ccr_bit (x
, 1);
15454 output_operand_lossage ("invalid %%J code");
15456 /* If we want bit 31, write a shift count of zero, not 32. */
15457 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
15461 /* X must be a constant. Write the 1's complement of the
15464 output_operand_lossage ("invalid %%k value");
15466 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
15470 /* X must be a symbolic constant on ELF. Write an
15471 expression suitable for an 'addi' that adds in the low 16
15472 bits of the MEM. */
15473 if (GET_CODE (x
) == CONST
)
15475 if (GET_CODE (XEXP (x
, 0)) != PLUS
15476 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
15477 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
15478 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
15479 output_operand_lossage ("invalid %%K value");
15481 print_operand_address (file
, x
);
15482 fputs ("@l", file
);
15485 /* %l is output_asm_label. */
15488 /* Write second word of DImode or DFmode reference. Works on register
15489 or non-indexed memory only. */
15490 if (GET_CODE (x
) == REG
)
15491 fputs (reg_names
[REGNO (x
) + 1], file
);
15492 else if (GET_CODE (x
) == MEM
)
15494 /* Handle possible auto-increment. Since it is pre-increment and
15495 we have already done it, we can just use an offset of word. */
15496 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
15497 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
15498 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
15500 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
15501 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
15504 output_address (XEXP (adjust_address_nv (x
, SImode
,
15508 if (small_data_operand (x
, GET_MODE (x
)))
15509 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
15510 reg_names
[SMALL_DATA_REG
]);
15515 /* MB value for a mask operand. */
15516 if (! mask_operand (x
, SImode
))
15517 output_operand_lossage ("invalid %%m value");
15519 fprintf (file
, "%d", extract_MB (x
));
15523 /* ME value for a mask operand. */
15524 if (! mask_operand (x
, SImode
))
15525 output_operand_lossage ("invalid %%M value");
15527 fprintf (file
, "%d", extract_ME (x
));
15530 /* %n outputs the negative of its operand. */
15533 /* Write the number of elements in the vector times 4. */
15534 if (GET_CODE (x
) != PARALLEL
)
15535 output_operand_lossage ("invalid %%N value");
15537 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
15541 /* Similar, but subtract 1 first. */
15542 if (GET_CODE (x
) != PARALLEL
)
15543 output_operand_lossage ("invalid %%O value");
15545 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
15549 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15551 || INT_LOWPART (x
) < 0
15552 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
15553 output_operand_lossage ("invalid %%p value");
15555 fprintf (file
, "%d", i
);
15559 /* The operand must be an indirect memory reference. The result
15560 is the register name. */
15561 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
15562 || REGNO (XEXP (x
, 0)) >= 32)
15563 output_operand_lossage ("invalid %%P value");
15565 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
15569 /* This outputs the logical code corresponding to a boolean
15570 expression. The expression may have one or both operands
15571 negated (if one, only the first one). For condition register
15572 logical operations, it will also treat the negated
15573 CR codes as NOTs, but not handle NOTs of them. */
15575 const char *const *t
= 0;
15577 enum rtx_code code
= GET_CODE (x
);
15578 static const char * const tbl
[3][3] = {
15579 { "and", "andc", "nor" },
15580 { "or", "orc", "nand" },
15581 { "xor", "eqv", "xor" } };
15585 else if (code
== IOR
)
15587 else if (code
== XOR
)
15590 output_operand_lossage ("invalid %%q value");
15592 if (GET_CODE (XEXP (x
, 0)) != NOT
)
15596 if (GET_CODE (XEXP (x
, 1)) == NOT
)
15614 /* X is a CR register. Print the mask for `mtcrf'. */
15615 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
15616 output_operand_lossage ("invalid %%R value");
15618 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
15622 /* Low 5 bits of 32 - value */
15624 output_operand_lossage ("invalid %%s value");
15626 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
15630 /* PowerPC64 mask position. All 0's is excluded.
15631 CONST_INT 32-bit mask is considered sign-extended so any
15632 transition must occur within the CONST_INT, not on the boundary. */
15633 if (! mask64_operand (x
, DImode
))
15634 output_operand_lossage ("invalid %%S value");
15636 uval
= INT_LOWPART (x
);
15638 if (uval
& 1) /* Clear Left */
15640 #if HOST_BITS_PER_WIDE_INT > 64
15641 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
15645 else /* Clear Right */
15648 #if HOST_BITS_PER_WIDE_INT > 64
15649 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
15655 gcc_assert (i
>= 0);
15656 fprintf (file
, "%d", i
);
15660 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15661 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
15663 /* Bit 3 is OV bit. */
15664 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
15666 /* If we want bit 31, write a shift count of zero, not 32. */
15667 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
15671 /* Print the symbolic name of a branch target register. */
15672 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LR_REGNO
15673 && REGNO (x
) != CTR_REGNO
))
15674 output_operand_lossage ("invalid %%T value");
15675 else if (REGNO (x
) == LR_REGNO
)
15676 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
15678 fputs ("ctr", file
);
15682 /* High-order 16 bits of constant for use in unsigned operand. */
15684 output_operand_lossage ("invalid %%u value");
15686 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
15687 (INT_LOWPART (x
) >> 16) & 0xffff);
15691 /* High-order 16 bits of constant for use in signed operand. */
15693 output_operand_lossage ("invalid %%v value");
15695 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
15696 (INT_LOWPART (x
) >> 16) & 0xffff);
15700 /* Print `u' if this has an auto-increment or auto-decrement. */
15701 if (GET_CODE (x
) == MEM
15702 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
15703 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
15704 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
))
15709 /* Print the trap code for this operand. */
15710 switch (GET_CODE (x
))
15713 fputs ("eq", file
); /* 4 */
15716 fputs ("ne", file
); /* 24 */
15719 fputs ("lt", file
); /* 16 */
15722 fputs ("le", file
); /* 20 */
15725 fputs ("gt", file
); /* 8 */
15728 fputs ("ge", file
); /* 12 */
15731 fputs ("llt", file
); /* 2 */
15734 fputs ("lle", file
); /* 6 */
15737 fputs ("lgt", file
); /* 1 */
15740 fputs ("lge", file
); /* 5 */
15743 gcc_unreachable ();
15748 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15751 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
15752 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
15754 print_operand (file
, x
, 0);
15758 /* MB value for a PowerPC64 rldic operand. */
15759 val
= (GET_CODE (x
) == CONST_INT
15760 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
15765 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
15766 if ((val
<<= 1) < 0)
15769 #if HOST_BITS_PER_WIDE_INT == 32
15770 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
15771 i
+= 32; /* zero-extend high-part was all 0's */
15772 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
15774 val
= CONST_DOUBLE_LOW (x
);
15780 for ( ; i
< 64; i
++)
15781 if ((val
<<= 1) < 0)
15786 fprintf (file
, "%d", i
+ 1);
15790 /* X is a FPR or Altivec register used in a VSX context. */
15791 if (GET_CODE (x
) != REG
|| !VSX_REGNO_P (REGNO (x
)))
15792 output_operand_lossage ("invalid %%x value");
15795 int reg
= REGNO (x
);
15796 int vsx_reg
= (FP_REGNO_P (reg
)
15798 : reg
- FIRST_ALTIVEC_REGNO
+ 32);
15800 #ifdef TARGET_REGNAMES
15801 if (TARGET_REGNAMES
)
15802 fprintf (file
, "%%vs%d", vsx_reg
);
15805 fprintf (file
, "%d", vsx_reg
);
15810 if (GET_CODE (x
) == MEM
15811 && (legitimate_indexed_address_p (XEXP (x
, 0), 0)
15812 || (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
15813 && legitimate_indexed_address_p (XEXP (XEXP (x
, 0), 1), 0))))
15818 /* Like 'L', for third word of TImode */
15819 if (GET_CODE (x
) == REG
)
15820 fputs (reg_names
[REGNO (x
) + 2], file
);
15821 else if (GET_CODE (x
) == MEM
)
15823 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
15824 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
15825 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
15826 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
15827 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
15829 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
15830 if (small_data_operand (x
, GET_MODE (x
)))
15831 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
15832 reg_names
[SMALL_DATA_REG
]);
15837 /* X is a SYMBOL_REF. Write out the name preceded by a
15838 period and without any trailing data in brackets. Used for function
15839 names. If we are configured for System V (or the embedded ABI) on
15840 the PowerPC, do not emit the period, since those systems do not use
15841 TOCs and the like. */
15842 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
15844 /* Mark the decl as referenced so that cgraph will output the
15846 if (SYMBOL_REF_DECL (x
))
15847 mark_decl_referenced (SYMBOL_REF_DECL (x
));
15849 /* For macho, check to see if we need a stub. */
15852 const char *name
= XSTR (x
, 0);
15854 if (darwin_emit_branch_islands
15855 && MACHOPIC_INDIRECT
15856 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
15857 name
= machopic_indirection_name (x
, /*stub_p=*/true);
15859 assemble_name (file
, name
);
15861 else if (!DOT_SYMBOLS
)
15862 assemble_name (file
, XSTR (x
, 0));
15864 rs6000_output_function_entry (file
, XSTR (x
, 0));
15868 /* Like 'L', for last word of TImode. */
15869 if (GET_CODE (x
) == REG
)
15870 fputs (reg_names
[REGNO (x
) + 3], file
);
15871 else if (GET_CODE (x
) == MEM
)
15873 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
15874 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
15875 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
15876 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
15877 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
15879 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
15880 if (small_data_operand (x
, GET_MODE (x
)))
15881 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
15882 reg_names
[SMALL_DATA_REG
]);
15886 /* Print AltiVec or SPE memory operand. */
15891 gcc_assert (GET_CODE (x
) == MEM
);
15895 /* Ugly hack because %y is overloaded. */
15896 if ((TARGET_SPE
|| TARGET_E500_DOUBLE
)
15897 && (GET_MODE_SIZE (GET_MODE (x
)) == 8
15898 || GET_MODE (x
) == TFmode
15899 || GET_MODE (x
) == TImode
))
15901 /* Handle [reg]. */
15902 if (GET_CODE (tmp
) == REG
)
15904 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
15907 /* Handle [reg+UIMM]. */
15908 else if (GET_CODE (tmp
) == PLUS
&&
15909 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
15913 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
15915 x
= INTVAL (XEXP (tmp
, 1));
15916 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
15920 /* Fall through. Must be [reg+reg]. */
15922 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x
))
15923 && GET_CODE (tmp
) == AND
15924 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
15925 && INTVAL (XEXP (tmp
, 1)) == -16)
15926 tmp
= XEXP (tmp
, 0);
15927 else if (VECTOR_MEM_VSX_P (GET_MODE (x
))
15928 && GET_CODE (tmp
) == PRE_MODIFY
)
15929 tmp
= XEXP (tmp
, 1);
15930 if (GET_CODE (tmp
) == REG
)
15931 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
15934 if (!GET_CODE (tmp
) == PLUS
15935 || !REG_P (XEXP (tmp
, 0))
15936 || !REG_P (XEXP (tmp
, 1)))
15938 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15942 if (REGNO (XEXP (tmp
, 0)) == 0)
15943 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
15944 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
15946 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
15947 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
15953 if (GET_CODE (x
) == REG
)
15954 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
15955 else if (GET_CODE (x
) == MEM
)
15957 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15958 know the width from the mode. */
15959 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
15960 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
15961 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
15962 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
15963 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
15964 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
15965 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
15966 output_address (XEXP (XEXP (x
, 0), 1));
15968 output_address (XEXP (x
, 0));
15971 output_addr_const (file
, x
);
15975 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
15979 output_operand_lossage ("invalid %%xn code");
15983 /* Print the address of an operand. */
15986 print_operand_address (FILE *file
, rtx x
)
15988 if (GET_CODE (x
) == REG
)
15989 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
15990 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
15991 || GET_CODE (x
) == LABEL_REF
)
15993 output_addr_const (file
, x
);
15994 if (small_data_operand (x
, GET_MODE (x
)))
15995 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
15996 reg_names
[SMALL_DATA_REG
]);
15998 gcc_assert (!TARGET_TOC
);
16000 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
16002 gcc_assert (REG_P (XEXP (x
, 0)));
16003 if (REGNO (XEXP (x
, 0)) == 0)
16004 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
16005 reg_names
[ REGNO (XEXP (x
, 0)) ]);
16007 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
16008 reg_names
[ REGNO (XEXP (x
, 1)) ]);
16010 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
16011 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
16012 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
16014 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
16015 && CONSTANT_P (XEXP (x
, 1)))
16017 fprintf (file
, "lo16(");
16018 output_addr_const (file
, XEXP (x
, 1));
16019 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
16022 else if (legitimate_constant_pool_address_p (x
, true))
16024 /* This hack along with a corresponding hack in
16025 rs6000_output_addr_const_extra arranges to output addends
16026 where the assembler expects to find them. eg.
16028 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16029 without this hack would be output as "x@toc+8@l(9)". We
16030 want "x+8@toc@l(9)". */
16031 output_addr_const (file
, tocrel_base
);
16032 if (GET_CODE (x
) == LO_SUM
)
16033 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
16035 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
16038 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
16039 && CONSTANT_P (XEXP (x
, 1)))
16041 output_addr_const (file
, XEXP (x
, 1));
16042 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
16046 gcc_unreachable ();
16049 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16052 rs6000_output_addr_const_extra (FILE *file
, rtx x
)
16054 if (GET_CODE (x
) == UNSPEC
)
16055 switch (XINT (x
, 1))
16057 case UNSPEC_TOCREL
:
16058 gcc_assert (GET_CODE (XVECEXP (x
, 0, 0)) == SYMBOL_REF
);
16059 output_addr_const (file
, XVECEXP (x
, 0, 0));
16060 if (x
== tocrel_base
&& tocrel_offset
!= const0_rtx
)
16062 if (INTVAL (tocrel_offset
) >= 0)
16063 fprintf (file
, "+");
16064 output_addr_const (file
, tocrel_offset
);
16066 if (!TARGET_AIX
|| (TARGET_ELF
&& TARGET_MINIMAL_TOC
))
16069 assemble_name (file
, toc_label_name
);
16071 else if (TARGET_ELF
)
16072 fputs ("@toc", file
);
16076 case UNSPEC_MACHOPIC_OFFSET
:
16077 output_addr_const (file
, XVECEXP (x
, 0, 0));
16079 machopic_output_function_base_name (file
);
16086 /* Target hook for assembling integer objects. The PowerPC version has
16087 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16088 is defined. It also needs to handle DI-mode objects on 64-bit
16092 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
16094 #ifdef RELOCATABLE_NEEDS_FIXUP
16095 /* Special handling for SI values. */
16096 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
16098 static int recurse
= 0;
16100 /* For -mrelocatable, we mark all addresses that need to be fixed up
16101 in the .fixup section. */
16102 if (TARGET_RELOCATABLE
16103 && in_section
!= toc_section
16104 && in_section
!= text_section
16105 && !unlikely_text_section_p (in_section
)
16107 && GET_CODE (x
) != CONST_INT
16108 && GET_CODE (x
) != CONST_DOUBLE
16114 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
16116 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
16117 fprintf (asm_out_file
, "\t.long\t(");
16118 output_addr_const (asm_out_file
, x
);
16119 fprintf (asm_out_file
, ")@fixup\n");
16120 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
16121 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
16122 fprintf (asm_out_file
, "\t.long\t");
16123 assemble_name (asm_out_file
, buf
);
16124 fprintf (asm_out_file
, "\n\t.previous\n");
16128 /* Remove initial .'s to turn a -mcall-aixdesc function
16129 address into the address of the descriptor, not the function
16131 else if (GET_CODE (x
) == SYMBOL_REF
16132 && XSTR (x
, 0)[0] == '.'
16133 && DEFAULT_ABI
== ABI_AIX
)
16135 const char *name
= XSTR (x
, 0);
16136 while (*name
== '.')
16139 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
16143 #endif /* RELOCATABLE_NEEDS_FIXUP */
16144 return default_assemble_integer (x
, size
, aligned_p
);
16147 #ifdef HAVE_GAS_HIDDEN
16148 /* Emit an assembler directive to set symbol visibility for DECL to
16149 VISIBILITY_TYPE. */
16152 rs6000_assemble_visibility (tree decl
, int vis
)
16154 /* Functions need to have their entry point symbol visibility set as
16155 well as their descriptor symbol visibility. */
16156 if (DEFAULT_ABI
== ABI_AIX
16158 && TREE_CODE (decl
) == FUNCTION_DECL
)
16160 static const char * const visibility_types
[] = {
16161 NULL
, "internal", "hidden", "protected"
16164 const char *name
, *type
;
16166 name
= ((* targetm
.strip_name_encoding
)
16167 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
16168 type
= visibility_types
[vis
];
16170 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
16171 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
16174 default_assemble_visibility (decl
, vis
);
16179 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
16181 /* Reversal of FP compares takes care -- an ordered compare
16182 becomes an unordered compare and vice versa. */
16183 if (mode
== CCFPmode
16184 && (!flag_finite_math_only
16185 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
16186 || code
== UNEQ
|| code
== LTGT
))
16187 return reverse_condition_maybe_unordered (code
);
16189 return reverse_condition (code
);
16192 /* Generate a compare for CODE. Return a brand-new rtx that
16193 represents the result of the compare. */
16196 rs6000_generate_compare (rtx cmp
, enum machine_mode mode
)
16198 enum machine_mode comp_mode
;
16199 rtx compare_result
;
16200 enum rtx_code code
= GET_CODE (cmp
);
16201 rtx op0
= XEXP (cmp
, 0);
16202 rtx op1
= XEXP (cmp
, 1);
16204 if (FLOAT_MODE_P (mode
))
16205 comp_mode
= CCFPmode
;
16206 else if (code
== GTU
|| code
== LTU
16207 || code
== GEU
|| code
== LEU
)
16208 comp_mode
= CCUNSmode
;
16209 else if ((code
== EQ
|| code
== NE
)
16210 && GET_CODE (op0
) == SUBREG
16211 && GET_CODE (op1
) == SUBREG
16212 && SUBREG_PROMOTED_UNSIGNED_P (op0
)
16213 && SUBREG_PROMOTED_UNSIGNED_P (op1
))
16214 /* These are unsigned values, perhaps there will be a later
16215 ordering compare that can be shared with this one.
16216 Unfortunately we cannot detect the signedness of the operands
16217 for non-subregs. */
16218 comp_mode
= CCUNSmode
;
16220 comp_mode
= CCmode
;
16222 /* First, the compare. */
16223 compare_result
= gen_reg_rtx (comp_mode
);
16225 /* E500 FP compare instructions on the GPRs. Yuck! */
16226 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
)
16227 && FLOAT_MODE_P (mode
))
16229 rtx cmp
, or_result
, compare_result2
;
16230 enum machine_mode op_mode
= GET_MODE (op0
);
16232 if (op_mode
== VOIDmode
)
16233 op_mode
= GET_MODE (op1
);
16235 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16236 This explains the following mess. */
16240 case EQ
: case UNEQ
: case NE
: case LTGT
:
16244 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16245 ? gen_tstsfeq_gpr (compare_result
, op0
, op1
)
16246 : gen_cmpsfeq_gpr (compare_result
, op0
, op1
);
16250 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16251 ? gen_tstdfeq_gpr (compare_result
, op0
, op1
)
16252 : gen_cmpdfeq_gpr (compare_result
, op0
, op1
);
16256 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16257 ? gen_tsttfeq_gpr (compare_result
, op0
, op1
)
16258 : gen_cmptfeq_gpr (compare_result
, op0
, op1
);
16262 gcc_unreachable ();
16266 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
16270 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16271 ? gen_tstsfgt_gpr (compare_result
, op0
, op1
)
16272 : gen_cmpsfgt_gpr (compare_result
, op0
, op1
);
16276 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16277 ? gen_tstdfgt_gpr (compare_result
, op0
, op1
)
16278 : gen_cmpdfgt_gpr (compare_result
, op0
, op1
);
16282 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16283 ? gen_tsttfgt_gpr (compare_result
, op0
, op1
)
16284 : gen_cmptfgt_gpr (compare_result
, op0
, op1
);
16288 gcc_unreachable ();
16292 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
16296 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16297 ? gen_tstsflt_gpr (compare_result
, op0
, op1
)
16298 : gen_cmpsflt_gpr (compare_result
, op0
, op1
);
16302 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16303 ? gen_tstdflt_gpr (compare_result
, op0
, op1
)
16304 : gen_cmpdflt_gpr (compare_result
, op0
, op1
);
16308 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16309 ? gen_tsttflt_gpr (compare_result
, op0
, op1
)
16310 : gen_cmptflt_gpr (compare_result
, op0
, op1
);
16314 gcc_unreachable ();
16318 gcc_unreachable ();
16321 /* Synthesize LE and GE from LT/GT || EQ. */
16322 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
16328 case LE
: code
= LT
; break;
16329 case GE
: code
= GT
; break;
16330 case LEU
: code
= LT
; break;
16331 case GEU
: code
= GT
; break;
16332 default: gcc_unreachable ();
16335 compare_result2
= gen_reg_rtx (CCFPmode
);
16341 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16342 ? gen_tstsfeq_gpr (compare_result2
, op0
, op1
)
16343 : gen_cmpsfeq_gpr (compare_result2
, op0
, op1
);
16347 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16348 ? gen_tstdfeq_gpr (compare_result2
, op0
, op1
)
16349 : gen_cmpdfeq_gpr (compare_result2
, op0
, op1
);
16353 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
16354 ? gen_tsttfeq_gpr (compare_result2
, op0
, op1
)
16355 : gen_cmptfeq_gpr (compare_result2
, op0
, op1
);
16359 gcc_unreachable ();
16363 /* OR them together. */
16364 or_result
= gen_reg_rtx (CCFPmode
);
16365 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
16367 compare_result
= or_result
;
16372 if (code
== NE
|| code
== LTGT
)
16382 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16383 CLOBBERs to match cmptf_internal2 pattern. */
16384 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
16385 && GET_MODE (op0
) == TFmode
16386 && !TARGET_IEEEQUAD
16387 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
16388 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
16390 gen_rtx_SET (VOIDmode
,
16392 gen_rtx_COMPARE (comp_mode
, op0
, op1
)),
16393 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16394 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16395 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16396 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16397 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16398 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16399 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16400 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
16401 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (Pmode
)))));
16402 else if (GET_CODE (op1
) == UNSPEC
16403 && XINT (op1
, 1) == UNSPEC_SP_TEST
)
16405 rtx op1b
= XVECEXP (op1
, 0, 0);
16406 comp_mode
= CCEQmode
;
16407 compare_result
= gen_reg_rtx (CCEQmode
);
16409 emit_insn (gen_stack_protect_testdi (compare_result
, op0
, op1b
));
16411 emit_insn (gen_stack_protect_testsi (compare_result
, op0
, op1b
));
16414 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
16415 gen_rtx_COMPARE (comp_mode
, op0
, op1
)));
16418 /* Some kinds of FP comparisons need an OR operation;
16419 under flag_finite_math_only we don't bother. */
16420 if (FLOAT_MODE_P (mode
)
16421 && !flag_finite_math_only
16422 && !(TARGET_HARD_FLOAT
&& !TARGET_FPRS
)
16423 && (code
== LE
|| code
== GE
16424 || code
== UNEQ
|| code
== LTGT
16425 || code
== UNGT
|| code
== UNLT
))
16427 enum rtx_code or1
, or2
;
16428 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
16429 rtx or_result
= gen_reg_rtx (CCEQmode
);
16433 case LE
: or1
= LT
; or2
= EQ
; break;
16434 case GE
: or1
= GT
; or2
= EQ
; break;
16435 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
16436 case LTGT
: or1
= LT
; or2
= GT
; break;
16437 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
16438 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
16439 default: gcc_unreachable ();
16441 validate_condition_mode (or1
, comp_mode
);
16442 validate_condition_mode (or2
, comp_mode
);
16443 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
16444 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
16445 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
16446 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
16448 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
16450 compare_result
= or_result
;
16454 validate_condition_mode (code
, GET_MODE (compare_result
));
16456 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
16460 /* Emit the RTL for an sISEL pattern. */
16463 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED
, rtx operands
[])
16465 rs6000_emit_int_cmove (operands
[0], operands
[1], const1_rtx
, const0_rtx
);
16469 rs6000_emit_sCOND (enum machine_mode mode
, rtx operands
[])
16472 enum machine_mode op_mode
;
16473 enum rtx_code cond_code
;
16474 rtx result
= operands
[0];
16476 if (TARGET_ISEL
&& (mode
== SImode
|| mode
== DImode
))
16478 rs6000_emit_sISEL (mode
, operands
);
16482 condition_rtx
= rs6000_generate_compare (operands
[1], mode
);
16483 cond_code
= GET_CODE (condition_rtx
);
16485 if (FLOAT_MODE_P (mode
)
16486 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
16490 PUT_MODE (condition_rtx
, SImode
);
16491 t
= XEXP (condition_rtx
, 0);
16493 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
16495 if (cond_code
== NE
)
16496 emit_insn (gen_e500_flip_gt_bit (t
, t
));
16498 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
16502 if (cond_code
== NE
16503 || cond_code
== GE
|| cond_code
== LE
16504 || cond_code
== GEU
|| cond_code
== LEU
16505 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
16507 rtx not_result
= gen_reg_rtx (CCEQmode
);
16508 rtx not_op
, rev_cond_rtx
;
16509 enum machine_mode cc_mode
;
16511 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
16513 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
16514 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
16515 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
16516 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
16517 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
16520 op_mode
= GET_MODE (XEXP (operands
[1], 0));
16521 if (op_mode
== VOIDmode
)
16522 op_mode
= GET_MODE (XEXP (operands
[1], 1));
16524 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| FLOAT_MODE_P (mode
)))
16526 PUT_MODE (condition_rtx
, DImode
);
16527 convert_move (result
, condition_rtx
, 0);
16531 PUT_MODE (condition_rtx
, SImode
);
16532 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
16536 /* Emit a branch of kind CODE to location LOC. */
16539 rs6000_emit_cbranch (enum machine_mode mode
, rtx operands
[])
16541 rtx condition_rtx
, loc_ref
;
16543 condition_rtx
= rs6000_generate_compare (operands
[0], mode
);
16544 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
16545 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
16546 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
16547 loc_ref
, pc_rtx
)));
16550 /* Return the string to output a conditional branch to LABEL, which is
16551 the operand number of the label, or -1 if the branch is really a
16552 conditional return.
16554 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16555 condition code register and its mode specifies what kind of
16556 comparison we made.
16558 REVERSED is nonzero if we should reverse the sense of the comparison.
16560 INSN is the insn. */
16563 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
16565 static char string
[64];
16566 enum rtx_code code
= GET_CODE (op
);
16567 rtx cc_reg
= XEXP (op
, 0);
16568 enum machine_mode mode
= GET_MODE (cc_reg
);
16569 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
16570 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
16571 int really_reversed
= reversed
^ need_longbranch
;
16577 validate_condition_mode (code
, mode
);
16579 /* Work out which way this really branches. We could use
16580 reverse_condition_maybe_unordered here always but this
16581 makes the resulting assembler clearer. */
16582 if (really_reversed
)
16584 /* Reversal of FP compares takes care -- an ordered compare
16585 becomes an unordered compare and vice versa. */
16586 if (mode
== CCFPmode
)
16587 code
= reverse_condition_maybe_unordered (code
);
16589 code
= reverse_condition (code
);
16592 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
16594 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16599 /* Opposite of GT. */
16608 gcc_unreachable ();
16614 /* Not all of these are actually distinct opcodes, but
16615 we distinguish them for clarity of the resulting assembler. */
16616 case NE
: case LTGT
:
16617 ccode
= "ne"; break;
16618 case EQ
: case UNEQ
:
16619 ccode
= "eq"; break;
16621 ccode
= "ge"; break;
16622 case GT
: case GTU
: case UNGT
:
16623 ccode
= "gt"; break;
16625 ccode
= "le"; break;
16626 case LT
: case LTU
: case UNLT
:
16627 ccode
= "lt"; break;
16628 case UNORDERED
: ccode
= "un"; break;
16629 case ORDERED
: ccode
= "nu"; break;
16630 case UNGE
: ccode
= "nl"; break;
16631 case UNLE
: ccode
= "ng"; break;
16633 gcc_unreachable ();
16636 /* Maybe we have a guess as to how likely the branch is.
16637 The old mnemonics don't have a way to specify this information. */
16639 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
16640 if (note
!= NULL_RTX
)
16642 /* PROB is the difference from 50%. */
16643 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
16645 /* Only hint for highly probable/improbable branches on newer
16646 cpus as static prediction overrides processor dynamic
16647 prediction. For older cpus we may as well always hint, but
16648 assume not taken for branches that are very close to 50% as a
16649 mispredicted taken branch is more expensive than a
16650 mispredicted not-taken branch. */
16651 if (rs6000_always_hint
16652 || (abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48
16653 && br_prob_note_reliable_p (note
)))
16655 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
16656 && ((prob
> 0) ^ need_longbranch
))
16664 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
16666 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
16668 /* We need to escape any '%' characters in the reg_names string.
16669 Assume they'd only be the first character.... */
16670 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
16672 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
16676 /* If the branch distance was too far, we may have to use an
16677 unconditional branch to go the distance. */
16678 if (need_longbranch
)
16679 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
16681 s
+= sprintf (s
, ",%s", label
);
16687 /* Return the string to flip the GT bit on a CR. */
16689 output_e500_flip_gt_bit (rtx dst
, rtx src
)
16691 static char string
[64];
16694 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
16695 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
16698 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
16699 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
16701 sprintf (string
, "crnot %d,%d", a
, b
);
16705 /* Return insn for VSX or Altivec comparisons. */
16708 rs6000_emit_vector_compare_inner (enum rtx_code code
, rtx op0
, rtx op1
)
16711 enum machine_mode mode
= GET_MODE (op0
);
16719 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
)
16725 mask
= gen_reg_rtx (mode
);
16726 emit_insn (gen_rtx_SET (VOIDmode
,
16728 gen_rtx_fmt_ee (code
, mode
, op0
, op1
)));
16735 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16736 DMODE is expected destination mode. This is a recursive function. */
16739 rs6000_emit_vector_compare (enum rtx_code rcode
,
16741 enum machine_mode dmode
)
16744 bool swap_operands
= false;
16745 bool try_again
= false;
16747 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode
));
16748 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
16750 /* See if the comparison works as is. */
16751 mask
= rs6000_emit_vector_compare_inner (rcode
, op0
, op1
);
16759 swap_operands
= true;
16764 swap_operands
= true;
16772 /* Invert condition and try again.
16773 e.g., A != B becomes ~(A==B). */
16775 enum rtx_code rev_code
;
16776 enum insn_code nor_code
;
16779 rev_code
= reverse_condition_maybe_unordered (rcode
);
16780 if (rev_code
== UNKNOWN
)
16783 nor_code
= optab_handler (one_cmpl_optab
, dmode
);
16784 if (nor_code
== CODE_FOR_nothing
)
16787 mask2
= rs6000_emit_vector_compare (rev_code
, op0
, op1
, dmode
);
16791 mask
= gen_reg_rtx (dmode
);
16792 emit_insn (GEN_FCN (nor_code
) (mask
, mask2
));
16800 /* Try GT/GTU/LT/LTU OR EQ */
16803 enum insn_code ior_code
;
16804 enum rtx_code new_code
;
16825 gcc_unreachable ();
16828 ior_code
= optab_handler (ior_optab
, dmode
);
16829 if (ior_code
== CODE_FOR_nothing
)
16832 c_rtx
= rs6000_emit_vector_compare (new_code
, op0
, op1
, dmode
);
16836 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
, dmode
);
16840 mask
= gen_reg_rtx (dmode
);
16841 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
16859 mask
= rs6000_emit_vector_compare_inner (rcode
, op0
, op1
);
16864 /* You only get two chances. */
16868 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16869 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16870 operands for the relation operation COND. */
16873 rs6000_emit_vector_cond_expr (rtx dest
, rtx op_true
, rtx op_false
,
16874 rtx cond
, rtx cc_op0
, rtx cc_op1
)
16876 enum machine_mode dest_mode
= GET_MODE (dest
);
16877 enum rtx_code rcode
= GET_CODE (cond
);
16878 enum machine_mode cc_mode
= CCmode
;
16882 bool invert_move
= false;
16884 if (VECTOR_UNIT_NONE_P (dest_mode
))
16889 /* Swap operands if we can, and fall back to doing the operation as
16890 specified, and doing a NOR to invert the test. */
16896 /* Invert condition and try again.
16897 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16898 invert_move
= true;
16899 rcode
= reverse_condition_maybe_unordered (rcode
);
16900 if (rcode
== UNKNOWN
)
16904 /* Mark unsigned tests with CCUNSmode. */
16909 cc_mode
= CCUNSmode
;
16916 /* Get the vector mask for the given relational operations. */
16917 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
16925 op_true
= op_false
;
16929 cond2
= gen_rtx_fmt_ee (NE
, cc_mode
, mask
, const0_rtx
);
16930 emit_insn (gen_rtx_SET (VOIDmode
,
16932 gen_rtx_IF_THEN_ELSE (dest_mode
,
16939 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16940 operands of the last comparison is nonzero/true, FALSE_COND if it
16941 is zero/false. Return 0 if the hardware has no such operation. */
16944 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
16946 enum rtx_code code
= GET_CODE (op
);
16947 rtx op0
= XEXP (op
, 0);
16948 rtx op1
= XEXP (op
, 1);
16949 REAL_VALUE_TYPE c1
;
16950 enum machine_mode compare_mode
= GET_MODE (op0
);
16951 enum machine_mode result_mode
= GET_MODE (dest
);
16953 bool is_against_zero
;
16955 /* These modes should always match. */
16956 if (GET_MODE (op1
) != compare_mode
16957 /* In the isel case however, we can use a compare immediate, so
16958 op1 may be a small constant. */
16959 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
16961 if (GET_MODE (true_cond
) != result_mode
)
16963 if (GET_MODE (false_cond
) != result_mode
)
16966 /* First, work out if the hardware can do this at all, or
16967 if it's too slow.... */
16968 if (!FLOAT_MODE_P (compare_mode
))
16971 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
16974 else if (TARGET_HARD_FLOAT
&& !TARGET_FPRS
16975 && SCALAR_FLOAT_MODE_P (compare_mode
))
16978 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
16980 /* A floating-point subtract might overflow, underflow, or produce
16981 an inexact result, thus changing the floating-point flags, so it
16982 can't be generated if we care about that. It's safe if one side
16983 of the construct is zero, since then no subtract will be
16985 if (SCALAR_FLOAT_MODE_P (compare_mode
)
16986 && flag_trapping_math
&& ! is_against_zero
)
16989 /* Eliminate half of the comparisons by switching operands, this
16990 makes the remaining code simpler. */
16991 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
16992 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
16994 code
= reverse_condition_maybe_unordered (code
);
16996 true_cond
= false_cond
;
17000 /* UNEQ and LTGT take four instructions for a comparison with zero,
17001 it'll probably be faster to use a branch here too. */
17002 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
17005 if (GET_CODE (op1
) == CONST_DOUBLE
)
17006 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
17008 /* We're going to try to implement comparisons by performing
17009 a subtract, then comparing against zero. Unfortunately,
17010 Inf - Inf is NaN which is not zero, and so if we don't
17011 know that the operand is finite and the comparison
17012 would treat EQ different to UNORDERED, we can't do it. */
17013 if (HONOR_INFINITIES (compare_mode
)
17014 && code
!= GT
&& code
!= UNGE
17015 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
17016 /* Constructs of the form (a OP b ? a : b) are safe. */
17017 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
17018 || (! rtx_equal_p (op0
, true_cond
)
17019 && ! rtx_equal_p (op1
, true_cond
))))
17022 /* At this point we know we can use fsel. */
17024 /* Reduce the comparison to a comparison against zero. */
17025 if (! is_against_zero
)
17027 temp
= gen_reg_rtx (compare_mode
);
17028 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17029 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
17031 op1
= CONST0_RTX (compare_mode
);
17034 /* If we don't care about NaNs we can reduce some of the comparisons
17035 down to faster ones. */
17036 if (! HONOR_NANS (compare_mode
))
17042 true_cond
= false_cond
;
17055 /* Now, reduce everything down to a GE. */
17062 temp
= gen_reg_rtx (compare_mode
);
17063 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
17068 temp
= gen_reg_rtx (compare_mode
);
17069 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
17074 temp
= gen_reg_rtx (compare_mode
);
17075 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17076 gen_rtx_NEG (compare_mode
,
17077 gen_rtx_ABS (compare_mode
, op0
))));
17082 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17083 temp
= gen_reg_rtx (result_mode
);
17084 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17085 gen_rtx_IF_THEN_ELSE (result_mode
,
17086 gen_rtx_GE (VOIDmode
,
17088 true_cond
, false_cond
)));
17089 false_cond
= true_cond
;
17092 temp
= gen_reg_rtx (compare_mode
);
17093 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
17098 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17099 temp
= gen_reg_rtx (result_mode
);
17100 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
17101 gen_rtx_IF_THEN_ELSE (result_mode
,
17102 gen_rtx_GE (VOIDmode
,
17104 true_cond
, false_cond
)));
17105 true_cond
= false_cond
;
17108 temp
= gen_reg_rtx (compare_mode
);
17109 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
17114 gcc_unreachable ();
17117 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
17118 gen_rtx_IF_THEN_ELSE (result_mode
,
17119 gen_rtx_GE (VOIDmode
,
17121 true_cond
, false_cond
)));
17125 /* Same as above, but for ints (isel). */
17128 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
17130 rtx condition_rtx
, cr
;
17131 enum machine_mode mode
= GET_MODE (dest
);
17132 enum rtx_code cond_code
;
17133 rtx (*isel_func
) (rtx
, rtx
, rtx
, rtx
, rtx
);
17136 if (mode
!= SImode
&& (!TARGET_POWERPC64
|| mode
!= DImode
))
17139 /* We still have to do the compare, because isel doesn't do a
17140 compare, it just looks at the CRx bits set by a previous compare
17142 condition_rtx
= rs6000_generate_compare (op
, mode
);
17143 cond_code
= GET_CODE (condition_rtx
);
17144 cr
= XEXP (condition_rtx
, 0);
17145 signedp
= GET_MODE (cr
) == CCmode
;
17147 isel_func
= (mode
== SImode
17148 ? (signedp
? gen_isel_signed_si
: gen_isel_unsigned_si
)
17149 : (signedp
? gen_isel_signed_di
: gen_isel_unsigned_di
));
17153 case LT
: case GT
: case LTU
: case GTU
: case EQ
:
17154 /* isel handles these directly. */
17158 /* We need to swap the sense of the comparison. */
17161 true_cond
= false_cond
;
17163 PUT_CODE (condition_rtx
, reverse_condition (cond_code
));
17168 false_cond
= force_reg (mode
, false_cond
);
17169 if (true_cond
!= const0_rtx
)
17170 true_cond
= force_reg (mode
, true_cond
);
17172 emit_insn (isel_func (dest
, condition_rtx
, true_cond
, false_cond
, cr
));
17178 output_isel (rtx
*operands
)
17180 enum rtx_code code
;
17182 code
= GET_CODE (operands
[1]);
17184 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
17186 gcc_assert (GET_CODE (operands
[2]) == REG
17187 && GET_CODE (operands
[3]) == REG
);
17188 PUT_CODE (operands
[1], reverse_condition (code
));
17189 return "isel %0,%3,%2,%j1";
17192 return "isel %0,%2,%3,%j1";
17196 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
17198 enum machine_mode mode
= GET_MODE (op0
);
17202 /* VSX/altivec have direct min/max insns. */
17203 if ((code
== SMAX
|| code
== SMIN
) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode
))
17205 emit_insn (gen_rtx_SET (VOIDmode
,
17207 gen_rtx_fmt_ee (code
, mode
, op0
, op1
)));
17211 if (code
== SMAX
|| code
== SMIN
)
17216 if (code
== SMAX
|| code
== UMAX
)
17217 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
17218 op0
, op1
, mode
, 0);
17220 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
17221 op1
, op0
, mode
, 0);
17222 gcc_assert (target
);
17223 if (target
!= dest
)
17224 emit_move_insn (dest
, target
);
17227 /* Emit instructions to perform a load-reserved/store-conditional operation.
17228 The operation performed is an atomic
17229 (set M (CODE:MODE M OP))
17230 If not NULL, BEFORE is atomically set to M before the operation, and
17231 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17232 If SYNC_P then a memory barrier is emitted before the operation.
17233 Either OP or M may be wrapped in a NOT operation. */
17236 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
17237 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
17240 enum machine_mode used_mode
;
17241 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
17244 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
17245 rtx shift
= NULL_RTX
;
17248 emit_insn (gen_lwsync ());
17252 /* If this is smaller than SImode, we'll have to use SImode with
17254 if (mode
== QImode
|| mode
== HImode
)
17258 if (MEM_ALIGN (used_m
) >= 32)
17261 if (BYTES_BIG_ENDIAN
)
17262 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
17264 shift
= GEN_INT (ishift
);
17265 used_m
= change_address (used_m
, SImode
, 0);
17269 rtx addrSI
, aligned_addr
;
17270 int shift_mask
= mode
== QImode
? 0x18 : 0x10;
17272 addrSI
= gen_lowpart_common (SImode
,
17273 force_reg (Pmode
, XEXP (used_m
, 0)));
17274 addrSI
= force_reg (SImode
, addrSI
);
17275 shift
= gen_reg_rtx (SImode
);
17277 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
17278 GEN_INT (shift_mask
)));
17279 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
17281 aligned_addr
= expand_binop (Pmode
, and_optab
,
17283 GEN_INT (-4), NULL_RTX
,
17284 1, OPTAB_LIB_WIDEN
);
17285 used_m
= change_address (used_m
, SImode
, aligned_addr
);
17286 set_mem_align (used_m
, 32);
17288 /* It's safe to keep the old alias set of USED_M, because
17289 the operation is atomic and only affects the original
17293 if (GET_CODE (op
) == NOT
)
17295 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
17296 oldop
= gen_rtx_NOT (SImode
, oldop
);
17299 oldop
= lowpart_subreg (SImode
, op
, mode
);
17305 newop
= expand_binop (SImode
, and_optab
,
17306 oldop
, GEN_INT (imask
), NULL_RTX
,
17307 1, OPTAB_LIB_WIDEN
);
17308 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
17311 case NOT
: /* NAND */
17312 newop
= expand_binop (SImode
, ior_optab
,
17313 oldop
, GEN_INT (~imask
), NULL_RTX
,
17314 1, OPTAB_LIB_WIDEN
);
17315 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
17319 newop
= expand_binop (SImode
, ior_optab
,
17320 oldop
, GEN_INT (~imask
), NULL_RTX
,
17321 1, OPTAB_LIB_WIDEN
);
17322 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
17330 newop
= expand_binop (SImode
, and_optab
,
17331 oldop
, GEN_INT (imask
), NULL_RTX
,
17332 1, OPTAB_LIB_WIDEN
);
17333 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
17335 mask
= gen_reg_rtx (SImode
);
17336 emit_move_insn (mask
, GEN_INT (imask
));
17337 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
17340 newop
= gen_rtx_PLUS (SImode
, m
, newop
);
17342 newop
= gen_rtx_MINUS (SImode
, m
, newop
);
17343 newop
= gen_rtx_AND (SImode
, newop
, mask
);
17344 newop
= gen_rtx_IOR (SImode
, newop
,
17345 gen_rtx_AND (SImode
,
17346 gen_rtx_NOT (SImode
, mask
),
17352 gcc_unreachable ();
17356 used_mode
= SImode
;
17357 before
= gen_reg_rtx (used_mode
);
17358 after
= gen_reg_rtx (used_mode
);
17363 before
= before_param
;
17364 after
= after_param
;
17366 if (before
== NULL_RTX
)
17367 before
= gen_reg_rtx (used_mode
);
17368 if (after
== NULL_RTX
)
17369 after
= gen_reg_rtx (used_mode
);
17372 if ((code
== PLUS
|| code
== MINUS
)
17373 && used_mode
!= mode
)
17374 the_op
= op
; /* Computed above. */
17375 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
17376 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
17377 else if (code
== NOT
)
17378 the_op
= gen_rtx_fmt_ee (IOR
, used_mode
,
17379 gen_rtx_NOT (used_mode
, m
),
17380 gen_rtx_NOT (used_mode
, op
));
17382 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
17384 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
17385 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
17386 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
17387 gen_rtx_UNSPEC (used_mode
,
17388 gen_rtvec (1, the_op
),
17390 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
17392 if ((code
== PLUS
|| code
== MINUS
) && used_mode
!= mode
)
17393 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
17394 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
17396 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
17397 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
17399 /* Shift and mask the return values properly. */
17400 if (used_mode
!= mode
&& before_param
)
17402 emit_insn (gen_lshrsi3 (before
, before
, shift
));
17403 convert_move (before_param
, before
, 1);
17406 if (used_mode
!= mode
&& after_param
)
17408 emit_insn (gen_lshrsi3 (after
, after
, shift
));
17409 convert_move (after_param
, after
, 1);
17412 /* The previous sequence will end with a branch that's dependent on
17413 the conditional store, so placing an isync will ensure that no
17414 other instructions (especially, no load or store instructions)
17415 can start before the atomic operation completes. */
17417 emit_insn (gen_isync ());
17420 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17421 COND is true. Mark the jump as unlikely to be taken. */
17424 emit_unlikely_jump (rtx cond
, rtx label
)
17426 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
17429 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
17430 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
17431 add_reg_note (x
, REG_BR_PROB
, very_unlikely
);
17434 /* A subroutine of the atomic operation splitters. Emit a load-locked
17435 instruction in MODE. */
17438 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
17440 rtx (*fn
) (rtx
, rtx
) = NULL
;
17441 if (mode
== SImode
)
17442 fn
= gen_load_locked_si
;
17443 else if (mode
== DImode
)
17444 fn
= gen_load_locked_di
;
17445 emit_insn (fn (reg
, mem
));
17448 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17449 instruction in MODE. */
17452 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
17454 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
17455 if (mode
== SImode
)
17456 fn
= gen_store_conditional_si
;
17457 else if (mode
== DImode
)
17458 fn
= gen_store_conditional_di
;
17460 /* Emit sync before stwcx. to address PPC405 Erratum. */
17461 if (PPC405_ERRATUM77
)
17462 emit_insn (gen_memory_barrier ());
17464 emit_insn (fn (res
, mem
, val
));
17467 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17468 to perform. MEM is the memory on which to operate. VAL is the second
17469 operand of the binary operator. BEFORE and AFTER are optional locations to
17470 return the value of MEM either before of after the operation. SCRATCH is
17471 a scratch register. */
17474 rs6000_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
17475 rtx before
, rtx after
, rtx scratch
)
17477 enum machine_mode mode
= GET_MODE (mem
);
17478 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
17480 emit_insn (gen_lwsync ());
17482 label
= gen_label_rtx ();
17483 emit_label (label
);
17484 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
17486 if (before
== NULL_RTX
)
17488 emit_load_locked (mode
, before
, mem
);
17491 x
= gen_rtx_IOR (mode
,
17492 gen_rtx_NOT (mode
, before
),
17493 gen_rtx_NOT (mode
, val
));
17494 else if (code
== AND
)
17495 x
= gen_rtx_UNSPEC (mode
, gen_rtvec (2, before
, val
), UNSPEC_AND
);
17497 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
17499 if (after
!= NULL_RTX
)
17500 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
17501 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
17503 emit_store_conditional (mode
, cond
, mem
, scratch
);
17505 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17506 emit_unlikely_jump (x
, label
);
17508 emit_insn (gen_isync ());
17511 /* Expand an atomic compare and swap operation. MEM is the memory on which
17512 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17513 value to be stored. SCRATCH is a scratch GPR. */
17516 rs6000_split_compare_and_swap (rtx retval
, rtx mem
, rtx oldval
, rtx newval
,
17519 enum machine_mode mode
= GET_MODE (mem
);
17520 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
17522 emit_insn (gen_lwsync ());
17524 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17525 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17526 emit_label (XEXP (label1
, 0));
17528 emit_load_locked (mode
, retval
, mem
);
17530 x
= gen_rtx_COMPARE (CCmode
, retval
, oldval
);
17531 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
17533 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17534 emit_unlikely_jump (x
, label2
);
17536 emit_move_insn (scratch
, newval
);
17537 emit_store_conditional (mode
, cond
, mem
, scratch
);
17539 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17540 emit_unlikely_jump (x
, label1
);
17542 emit_insn (gen_isync ());
17543 emit_label (XEXP (label2
, 0));
17546 /* Expand an atomic test and set operation. MEM is the memory on which
17547 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17550 rs6000_split_lock_test_and_set (rtx retval
, rtx mem
, rtx val
, rtx scratch
)
17552 enum machine_mode mode
= GET_MODE (mem
);
17553 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
17555 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17556 emit_label (XEXP (label
, 0));
17558 emit_load_locked (mode
, retval
, mem
);
17559 emit_move_insn (scratch
, val
);
17560 emit_store_conditional (mode
, cond
, mem
, scratch
);
17562 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17563 emit_unlikely_jump (x
, label
);
17565 emit_insn (gen_isync ());
17569 rs6000_expand_compare_and_swapqhi (rtx dst
, rtx mem
, rtx oldval
, rtx newval
)
17571 enum machine_mode mode
= GET_MODE (mem
);
17572 rtx addrSI
, align
, wdst
, shift
, mask
;
17573 HOST_WIDE_INT shift_mask
= mode
== QImode
? 0x18 : 0x10;
17574 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
17576 /* Shift amount for subword relative to aligned word. */
17577 addrSI
= force_reg (GET_MODE (XEXP (mem
, 0)), XEXP (mem
, 0));
17578 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
, addrSI
));
17579 shift
= gen_reg_rtx (SImode
);
17580 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
17581 GEN_INT (shift_mask
)));
17582 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
17584 /* Shift and mask old value into position within word. */
17585 oldval
= convert_modes (SImode
, mode
, oldval
, 1);
17586 oldval
= expand_binop (SImode
, and_optab
,
17587 oldval
, GEN_INT (imask
), NULL_RTX
,
17588 1, OPTAB_LIB_WIDEN
);
17589 emit_insn (gen_ashlsi3 (oldval
, oldval
, shift
));
17591 /* Shift and mask new value into position within word. */
17592 newval
= convert_modes (SImode
, mode
, newval
, 1);
17593 newval
= expand_binop (SImode
, and_optab
,
17594 newval
, GEN_INT (imask
), NULL_RTX
,
17595 1, OPTAB_LIB_WIDEN
);
17596 emit_insn (gen_ashlsi3 (newval
, newval
, shift
));
17598 /* Mask for insertion. */
17599 mask
= gen_reg_rtx (SImode
);
17600 emit_move_insn (mask
, GEN_INT (imask
));
17601 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
17603 /* Address of aligned word containing subword. */
17604 align
= expand_binop (Pmode
, and_optab
, XEXP (mem
, 0), GEN_INT (-4),
17605 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
17606 mem
= change_address (mem
, SImode
, align
);
17607 set_mem_align (mem
, 32);
17608 MEM_VOLATILE_P (mem
) = 1;
17610 wdst
= gen_reg_rtx (SImode
);
17611 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst
, mask
,
17612 oldval
, newval
, mem
));
17614 /* Shift the result back. */
17615 emit_insn (gen_lshrsi3 (wdst
, wdst
, shift
));
17617 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
17621 rs6000_split_compare_and_swapqhi (rtx dest
, rtx mask
,
17622 rtx oldval
, rtx newval
, rtx mem
,
17625 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
17627 emit_insn (gen_lwsync ());
17628 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17629 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
17630 emit_label (XEXP (label1
, 0));
17632 emit_load_locked (SImode
, scratch
, mem
);
17634 /* Mask subword within loaded value for comparison with oldval.
17635 Use UNSPEC_AND to avoid clobber.*/
17636 emit_insn (gen_rtx_SET (SImode
, dest
,
17637 gen_rtx_UNSPEC (SImode
,
17638 gen_rtvec (2, scratch
, mask
),
17641 x
= gen_rtx_COMPARE (CCmode
, dest
, oldval
);
17642 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
17644 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17645 emit_unlikely_jump (x
, label2
);
17647 /* Clear subword within loaded value for insertion of new value. */
17648 emit_insn (gen_rtx_SET (SImode
, scratch
,
17649 gen_rtx_AND (SImode
,
17650 gen_rtx_NOT (SImode
, mask
), scratch
)));
17651 emit_insn (gen_iorsi3 (scratch
, scratch
, newval
));
17652 emit_store_conditional (SImode
, cond
, mem
, scratch
);
17654 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
17655 emit_unlikely_jump (x
, label1
);
17657 emit_insn (gen_isync ());
17658 emit_label (XEXP (label2
, 0));
17662 /* Emit instructions to move SRC to DST. Called by splitters for
17663 multi-register moves. It will emit at most one instruction for
17664 each register that is accessed; that is, it won't emit li/lis pairs
17665 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17669 rs6000_split_multireg_move (rtx dst
, rtx src
)
17671 /* The register number of the first register being moved. */
17673 /* The mode that is to be moved. */
17674 enum machine_mode mode
;
17675 /* The mode that the move is being done in, and its size. */
17676 enum machine_mode reg_mode
;
17678 /* The number of registers that will be moved. */
17681 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
17682 mode
= GET_MODE (dst
);
17683 nregs
= hard_regno_nregs
[reg
][mode
];
17684 if (FP_REGNO_P (reg
))
17685 reg_mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
:
17686 ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? DFmode
: SFmode
);
17687 else if (ALTIVEC_REGNO_P (reg
))
17688 reg_mode
= V16QImode
;
17689 else if (TARGET_E500_DOUBLE
&& mode
== TFmode
)
17692 reg_mode
= word_mode
;
17693 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
17695 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
17697 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
17699 /* Move register range backwards, if we might have destructive
17702 for (i
= nregs
- 1; i
>= 0; i
--)
17703 emit_insn (gen_rtx_SET (VOIDmode
,
17704 simplify_gen_subreg (reg_mode
, dst
, mode
,
17705 i
* reg_mode_size
),
17706 simplify_gen_subreg (reg_mode
, src
, mode
,
17707 i
* reg_mode_size
)));
17713 bool used_update
= false;
17714 rtx restore_basereg
= NULL_RTX
;
17716 if (MEM_P (src
) && INT_REGNO_P (reg
))
17720 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
17721 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
17724 breg
= XEXP (XEXP (src
, 0), 0);
17725 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
17726 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
17727 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
17728 emit_insn (gen_add3_insn (breg
, breg
, delta_rtx
));
17729 src
= replace_equiv_address (src
, breg
);
17731 else if (! rs6000_offsettable_memref_p (src
))
17733 if (GET_CODE (XEXP (src
, 0)) == PRE_MODIFY
)
17735 rtx basereg
= XEXP (XEXP (src
, 0), 0);
17738 rtx ndst
= simplify_gen_subreg (reg_mode
, dst
, mode
, 0);
17739 emit_insn (gen_rtx_SET (VOIDmode
, ndst
,
17740 gen_rtx_MEM (reg_mode
, XEXP (src
, 0))));
17741 used_update
= true;
17744 emit_insn (gen_rtx_SET (VOIDmode
, basereg
,
17745 XEXP (XEXP (src
, 0), 1)));
17746 src
= replace_equiv_address (src
, basereg
);
17750 rtx basereg
= gen_rtx_REG (Pmode
, reg
);
17751 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
17752 src
= replace_equiv_address (src
, basereg
);
17756 breg
= XEXP (src
, 0);
17757 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
17758 breg
= XEXP (breg
, 0);
17760 /* If the base register we are using to address memory is
17761 also a destination reg, then change that register last. */
17763 && REGNO (breg
) >= REGNO (dst
)
17764 && REGNO (breg
) < REGNO (dst
) + nregs
)
17765 j
= REGNO (breg
) - REGNO (dst
);
17767 else if (MEM_P (dst
) && INT_REGNO_P (reg
))
17771 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
17772 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
17775 breg
= XEXP (XEXP (dst
, 0), 0);
17776 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
17777 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
17778 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
17780 /* We have to update the breg before doing the store.
17781 Use store with update, if available. */
17785 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
17786 emit_insn (TARGET_32BIT
17787 ? (TARGET_POWERPC64
17788 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
17789 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
17790 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
17791 used_update
= true;
17794 emit_insn (gen_add3_insn (breg
, breg
, delta_rtx
));
17795 dst
= replace_equiv_address (dst
, breg
);
17797 else if (!rs6000_offsettable_memref_p (dst
)
17798 && GET_CODE (XEXP (dst
, 0)) != LO_SUM
)
17800 if (GET_CODE (XEXP (dst
, 0)) == PRE_MODIFY
)
17802 rtx basereg
= XEXP (XEXP (dst
, 0), 0);
17805 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
17806 emit_insn (gen_rtx_SET (VOIDmode
,
17807 gen_rtx_MEM (reg_mode
, XEXP (dst
, 0)), nsrc
));
17808 used_update
= true;
17811 emit_insn (gen_rtx_SET (VOIDmode
, basereg
,
17812 XEXP (XEXP (dst
, 0), 1)));
17813 dst
= replace_equiv_address (dst
, basereg
);
17817 rtx basereg
= XEXP (XEXP (dst
, 0), 0);
17818 rtx offsetreg
= XEXP (XEXP (dst
, 0), 1);
17819 gcc_assert (GET_CODE (XEXP (dst
, 0)) == PLUS
17821 && REG_P (offsetreg
)
17822 && REGNO (basereg
) != REGNO (offsetreg
));
17823 if (REGNO (basereg
) == 0)
17825 rtx tmp
= offsetreg
;
17826 offsetreg
= basereg
;
17829 emit_insn (gen_add3_insn (basereg
, basereg
, offsetreg
));
17830 restore_basereg
= gen_sub3_insn (basereg
, basereg
, offsetreg
);
17831 dst
= replace_equiv_address (dst
, basereg
);
17834 else if (GET_CODE (XEXP (dst
, 0)) != LO_SUM
)
17835 gcc_assert (rs6000_offsettable_memref_p (dst
));
17838 for (i
= 0; i
< nregs
; i
++)
17840 /* Calculate index to next subword. */
17845 /* If compiler already emitted move of first word by
17846 store with update, no need to do anything. */
17847 if (j
== 0 && used_update
)
17850 emit_insn (gen_rtx_SET (VOIDmode
,
17851 simplify_gen_subreg (reg_mode
, dst
, mode
,
17852 j
* reg_mode_size
),
17853 simplify_gen_subreg (reg_mode
, src
, mode
,
17854 j
* reg_mode_size
)));
17856 if (restore_basereg
!= NULL_RTX
)
17857 emit_insn (restore_basereg
);
17862 /* This page contains routines that are used to determine what the
17863 function prologue and epilogue code will do and write them out. */
17865 /* Return the first fixed-point register that is required to be
17866 saved. 32 if none. */
17869 first_reg_to_save (void)
17873 /* Find lowest numbered live register. */
17874 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
17875 if (df_regs_ever_live_p (first_reg
)
17876 && (! call_used_regs
[first_reg
]
17877 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
17878 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
17879 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
17880 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
17885 && crtl
->uses_pic_offset_table
17886 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
17887 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
17893 /* Similar, for FP regs. */
17896 first_fp_reg_to_save (void)
17900 /* Find lowest numbered live register. */
17901 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
17902 if (df_regs_ever_live_p (first_reg
))
17908 /* Similar, for AltiVec regs. */
17911 first_altivec_reg_to_save (void)
17915 /* Stack frame remains as is unless we are in AltiVec ABI. */
17916 if (! TARGET_ALTIVEC_ABI
)
17917 return LAST_ALTIVEC_REGNO
+ 1;
17919 /* On Darwin, the unwind routines are compiled without
17920 TARGET_ALTIVEC, and use save_world to save/restore the
17921 altivec registers when necessary. */
17922 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
17923 && ! TARGET_ALTIVEC
)
17924 return FIRST_ALTIVEC_REGNO
+ 20;
17926 /* Find lowest numbered live register. */
17927 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
17928 if (df_regs_ever_live_p (i
))
17934 /* Return a 32-bit mask of the AltiVec registers we need to set in
17935 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17936 the 32-bit word is 0. */
17938 static unsigned int
17939 compute_vrsave_mask (void)
17941 unsigned int i
, mask
= 0;
17943 /* On Darwin, the unwind routines are compiled without
17944 TARGET_ALTIVEC, and use save_world to save/restore the
17945 call-saved altivec registers when necessary. */
17946 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
17947 && ! TARGET_ALTIVEC
)
17950 /* First, find out if we use _any_ altivec registers. */
17951 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
17952 if (df_regs_ever_live_p (i
))
17953 mask
|= ALTIVEC_REG_BIT (i
);
17958 /* Next, remove the argument registers from the set. These must
17959 be in the VRSAVE mask set by the caller, so we don't need to add
17960 them in again. More importantly, the mask we compute here is
17961 used to generate CLOBBERs in the set_vrsave insn, and we do not
17962 wish the argument registers to die. */
17963 for (i
= crtl
->args
.info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
17964 mask
&= ~ALTIVEC_REG_BIT (i
);
17966 /* Similarly, remove the return value from the set. */
17969 diddle_return_value (is_altivec_return_reg
, &yes
);
17971 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
17977 /* For a very restricted set of circumstances, we can cut down the
17978 size of prologues/epilogues by calling our own save/restore-the-world
17982 compute_save_world_info (rs6000_stack_t
*info_ptr
)
17984 info_ptr
->world_save_p
= 1;
17985 info_ptr
->world_save_p
17986 = (WORLD_SAVE_P (info_ptr
)
17987 && DEFAULT_ABI
== ABI_DARWIN
17988 && ! (cfun
->calls_setjmp
&& flag_exceptions
)
17989 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
17990 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
17991 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
17992 && info_ptr
->cr_save_p
);
17994 /* This will not work in conjunction with sibcalls. Make sure there
17995 are none. (This check is expensive, but seldom executed.) */
17996 if (WORLD_SAVE_P (info_ptr
))
17999 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
18000 if ( GET_CODE (insn
) == CALL_INSN
18001 && SIBLING_CALL_P (insn
))
18003 info_ptr
->world_save_p
= 0;
18008 if (WORLD_SAVE_P (info_ptr
))
18010 /* Even if we're not touching VRsave, make sure there's room on the
18011 stack for it, if it looks like we're calling SAVE_WORLD, which
18012 will attempt to save it. */
18013 info_ptr
->vrsave_size
= 4;
18015 /* If we are going to save the world, we need to save the link register too. */
18016 info_ptr
->lr_save_p
= 1;
18018 /* "Save" the VRsave register too if we're saving the world. */
18019 if (info_ptr
->vrsave_mask
== 0)
18020 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
18022 /* Because the Darwin register save/restore routines only handle
18023 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18025 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
18026 && (info_ptr
->first_altivec_reg_save
18027 >= FIRST_SAVED_ALTIVEC_REGNO
));
18034 is_altivec_return_reg (rtx reg
, void *xyes
)
18036 bool *yes
= (bool *) xyes
;
18037 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
18042 /* Calculate the stack information for the current function. This is
18043 complicated by having two separate calling sequences, the AIX calling
18044 sequence and the V.4 calling sequence.
18046 AIX (and Darwin/Mac OS X) stack frames look like:
18048 SP----> +---------------------------------------+
18049 | back chain to caller | 0 0
18050 +---------------------------------------+
18051 | saved CR | 4 8 (8-11)
18052 +---------------------------------------+
18054 +---------------------------------------+
18055 | reserved for compilers | 12 24
18056 +---------------------------------------+
18057 | reserved for binders | 16 32
18058 +---------------------------------------+
18059 | saved TOC pointer | 20 40
18060 +---------------------------------------+
18061 | Parameter save area (P) | 24 48
18062 +---------------------------------------+
18063 | Alloca space (A) | 24+P etc.
18064 +---------------------------------------+
18065 | Local variable space (L) | 24+P+A
18066 +---------------------------------------+
18067 | Float/int conversion temporary (X) | 24+P+A+L
18068 +---------------------------------------+
18069 | Save area for AltiVec registers (W) | 24+P+A+L+X
18070 +---------------------------------------+
18071 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18072 +---------------------------------------+
18073 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18074 +---------------------------------------+
18075 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18076 +---------------------------------------+
18077 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18078 +---------------------------------------+
18079 old SP->| back chain to caller's caller |
18080 +---------------------------------------+
18082 The required alignment for AIX configurations is two words (i.e., 8
18086 V.4 stack frames look like:
18088 SP----> +---------------------------------------+
18089 | back chain to caller | 0
18090 +---------------------------------------+
18091 | caller's saved LR | 4
18092 +---------------------------------------+
18093 | Parameter save area (P) | 8
18094 +---------------------------------------+
18095 | Alloca space (A) | 8+P
18096 +---------------------------------------+
18097 | Varargs save area (V) | 8+P+A
18098 +---------------------------------------+
18099 | Local variable space (L) | 8+P+A+V
18100 +---------------------------------------+
18101 | Float/int conversion temporary (X) | 8+P+A+V+L
18102 +---------------------------------------+
18103 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18104 +---------------------------------------+
18105 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18106 +---------------------------------------+
18107 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18108 +---------------------------------------+
18109 | SPE: area for 64-bit GP registers |
18110 +---------------------------------------+
18111 | SPE alignment padding |
18112 +---------------------------------------+
18113 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18114 +---------------------------------------+
18115 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18116 +---------------------------------------+
18117 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18118 +---------------------------------------+
18119 old SP->| back chain to caller's caller |
18120 +---------------------------------------+
18122 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18123 given. (But note below and in sysv4.h that we require only 8 and
18124 may round up the size of our stack frame anyways. The historical
18125 reason is early versions of powerpc-linux which didn't properly
18126 align the stack at program startup. A happy side-effect is that
18127 -mno-eabi libraries can be used with -meabi programs.)
18129 The EABI configuration defaults to the V.4 layout. However,
18130 the stack alignment requirements may differ. If -mno-eabi is not
18131 given, the required stack alignment is 8 bytes; if -mno-eabi is
18132 given, the required alignment is 16 bytes. (But see V.4 comment
18135 #ifndef ABI_STACK_BOUNDARY
18136 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18139 static rs6000_stack_t
*
18140 rs6000_stack_info (void)
18142 static rs6000_stack_t info
;
18143 rs6000_stack_t
*info_ptr
= &info
;
18144 int reg_size
= TARGET_32BIT
? 4 : 8;
18148 HOST_WIDE_INT non_fixed_size
;
18150 memset (&info
, 0, sizeof (info
));
18154 /* Cache value so we don't rescan instruction chain over and over. */
18155 if (cfun
->machine
->insn_chain_scanned_p
== 0)
18156 cfun
->machine
->insn_chain_scanned_p
18157 = spe_func_has_64bit_regs_p () + 1;
18158 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
18161 /* Select which calling sequence. */
18162 info_ptr
->abi
= DEFAULT_ABI
;
18164 /* Calculate which registers need to be saved & save area size. */
18165 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
18166 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18167 even if it currently looks like we won't. Reload may need it to
18168 get at a constant; if so, it will have already created a constant
18169 pool entry for it. */
18170 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
18171 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
18172 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
18173 && crtl
->uses_const_pool
18174 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
18175 first_gp
= RS6000_PIC_OFFSET_TABLE_REGNUM
;
18177 first_gp
= info_ptr
->first_gp_reg_save
;
18179 info_ptr
->gp_size
= reg_size
* (32 - first_gp
);
18181 /* For the SPE, we have an additional upper 32-bits on each GPR.
18182 Ideally we should save the entire 64-bits only when the upper
18183 half is used in SIMD instructions. Since we only record
18184 registers live (not the size they are used in), this proves
18185 difficult because we'd have to traverse the instruction chain at
18186 the right time, taking reload into account. This is a real pain,
18187 so we opt to save the GPRs in 64-bits always if but one register
18188 gets used in 64-bits. Otherwise, all the registers in the frame
18189 get saved in 32-bits.
18191 So... since when we save all GPRs (except the SP) in 64-bits, the
18192 traditional GP save area will be empty. */
18193 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18194 info_ptr
->gp_size
= 0;
18196 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
18197 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
18199 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
18200 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
18201 - info_ptr
->first_altivec_reg_save
);
18203 /* Does this function call anything? */
18204 info_ptr
->calls_p
= (! current_function_is_leaf
18205 || cfun
->machine
->ra_needs_full_frame
);
18207 /* Determine if we need to save the link register. */
18208 if ((DEFAULT_ABI
== ABI_AIX
18210 && !TARGET_PROFILE_KERNEL
)
18211 #ifdef TARGET_RELOCATABLE
18212 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
18214 || (info_ptr
->first_fp_reg_save
!= 64
18215 && !FP_SAVE_INLINE (info_ptr
->first_fp_reg_save
))
18216 || (DEFAULT_ABI
== ABI_V4
&& cfun
->calls_alloca
)
18217 || info_ptr
->calls_p
18218 || rs6000_ra_ever_killed ())
18220 info_ptr
->lr_save_p
= 1;
18221 df_set_regs_ever_live (LR_REGNO
, true);
18224 /* Determine if we need to save the condition code registers. */
18225 if (df_regs_ever_live_p (CR2_REGNO
)
18226 || df_regs_ever_live_p (CR3_REGNO
)
18227 || df_regs_ever_live_p (CR4_REGNO
))
18229 info_ptr
->cr_save_p
= 1;
18230 if (DEFAULT_ABI
== ABI_V4
)
18231 info_ptr
->cr_size
= reg_size
;
18234 /* If the current function calls __builtin_eh_return, then we need
18235 to allocate stack space for registers that will hold data for
18236 the exception handler. */
18237 if (crtl
->calls_eh_return
)
18240 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
18243 /* SPE saves EH registers in 64-bits. */
18244 ehrd_size
= i
* (TARGET_SPE_ABI
18245 && info_ptr
->spe_64bit_regs_used
!= 0
18246 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
18251 /* Determine various sizes. */
18252 info_ptr
->reg_size
= reg_size
;
18253 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
18254 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
18255 info_ptr
->parm_size
= RS6000_ALIGN (crtl
->outgoing_args_size
,
18256 TARGET_ALTIVEC
? 16 : 8);
18257 if (FRAME_GROWS_DOWNWARD
)
18258 info_ptr
->vars_size
18259 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
18260 + info_ptr
->parm_size
,
18261 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
18262 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
18263 + info_ptr
->parm_size
);
18265 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18266 info_ptr
->spe_gp_size
= 8 * (32 - first_gp
);
18268 info_ptr
->spe_gp_size
= 0;
18270 if (TARGET_ALTIVEC_ABI
)
18271 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
18273 info_ptr
->vrsave_mask
= 0;
18275 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
18276 info_ptr
->vrsave_size
= 4;
18278 info_ptr
->vrsave_size
= 0;
18280 compute_save_world_info (info_ptr
);
18282 /* Calculate the offsets. */
18283 switch (DEFAULT_ABI
)
18287 gcc_unreachable ();
18291 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
18292 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
18294 if (TARGET_ALTIVEC_ABI
)
18296 info_ptr
->vrsave_save_offset
18297 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
18299 /* Align stack so vector save area is on a quadword boundary.
18300 The padding goes above the vectors. */
18301 if (info_ptr
->altivec_size
!= 0)
18302 info_ptr
->altivec_padding_size
18303 = info_ptr
->vrsave_save_offset
& 0xF;
18305 info_ptr
->altivec_padding_size
= 0;
18307 info_ptr
->altivec_save_offset
18308 = info_ptr
->vrsave_save_offset
18309 - info_ptr
->altivec_padding_size
18310 - info_ptr
->altivec_size
;
18311 gcc_assert (info_ptr
->altivec_size
== 0
18312 || info_ptr
->altivec_save_offset
% 16 == 0);
18314 /* Adjust for AltiVec case. */
18315 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
18318 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
18319 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
18320 info_ptr
->lr_save_offset
= 2*reg_size
;
18324 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
18325 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
18326 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
18328 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
18330 /* Align stack so SPE GPR save area is aligned on a
18331 double-word boundary. */
18332 if (info_ptr
->spe_gp_size
!= 0 && info_ptr
->cr_save_offset
!= 0)
18333 info_ptr
->spe_padding_size
18334 = 8 - (-info_ptr
->cr_save_offset
% 8);
18336 info_ptr
->spe_padding_size
= 0;
18338 info_ptr
->spe_gp_save_offset
18339 = info_ptr
->cr_save_offset
18340 - info_ptr
->spe_padding_size
18341 - info_ptr
->spe_gp_size
;
18343 /* Adjust for SPE case. */
18344 info_ptr
->ehrd_offset
= info_ptr
->spe_gp_save_offset
;
18346 else if (TARGET_ALTIVEC_ABI
)
18348 info_ptr
->vrsave_save_offset
18349 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
18351 /* Align stack so vector save area is on a quadword boundary. */
18352 if (info_ptr
->altivec_size
!= 0)
18353 info_ptr
->altivec_padding_size
18354 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
18356 info_ptr
->altivec_padding_size
= 0;
18358 info_ptr
->altivec_save_offset
18359 = info_ptr
->vrsave_save_offset
18360 - info_ptr
->altivec_padding_size
18361 - info_ptr
->altivec_size
;
18363 /* Adjust for AltiVec case. */
18364 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
;
18367 info_ptr
->ehrd_offset
= info_ptr
->cr_save_offset
;
18368 info_ptr
->ehrd_offset
-= ehrd_size
;
18369 info_ptr
->lr_save_offset
= reg_size
;
18373 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
18374 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
18375 + info_ptr
->gp_size
18376 + info_ptr
->altivec_size
18377 + info_ptr
->altivec_padding_size
18378 + info_ptr
->spe_gp_size
18379 + info_ptr
->spe_padding_size
18381 + info_ptr
->cr_size
18382 + info_ptr
->vrsave_size
,
18385 non_fixed_size
= (info_ptr
->vars_size
18386 + info_ptr
->parm_size
18387 + info_ptr
->save_size
);
18389 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
18390 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
18392 /* Determine if we need to allocate any stack frame:
18394 For AIX we need to push the stack if a frame pointer is needed
18395 (because the stack might be dynamically adjusted), if we are
18396 debugging, if we make calls, or if the sum of fp_save, gp_save,
18397 and local variables are more than the space needed to save all
18398 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18399 + 18*8 = 288 (GPR13 reserved).
18401 For V.4 we don't have the stack cushion that AIX uses, but assume
18402 that the debugger can handle stackless frames. */
18404 if (info_ptr
->calls_p
)
18405 info_ptr
->push_p
= 1;
18407 else if (DEFAULT_ABI
== ABI_V4
)
18408 info_ptr
->push_p
= non_fixed_size
!= 0;
18410 else if (frame_pointer_needed
)
18411 info_ptr
->push_p
= 1;
18413 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
18414 info_ptr
->push_p
= 1;
18417 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
18419 /* Zero offsets if we're not saving those registers. */
18420 if (info_ptr
->fp_size
== 0)
18421 info_ptr
->fp_save_offset
= 0;
18423 if (info_ptr
->gp_size
== 0)
18424 info_ptr
->gp_save_offset
= 0;
18426 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
18427 info_ptr
->altivec_save_offset
= 0;
18429 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
18430 info_ptr
->vrsave_save_offset
= 0;
18432 if (! TARGET_SPE_ABI
18433 || info_ptr
->spe_64bit_regs_used
== 0
18434 || info_ptr
->spe_gp_size
== 0)
18435 info_ptr
->spe_gp_save_offset
= 0;
18437 if (! info_ptr
->lr_save_p
)
18438 info_ptr
->lr_save_offset
= 0;
18440 if (! info_ptr
->cr_save_p
)
18441 info_ptr
->cr_save_offset
= 0;
18446 /* Return true if the current function uses any GPRs in 64-bit SIMD
18450 spe_func_has_64bit_regs_p (void)
18454 /* Functions that save and restore all the call-saved registers will
18455 need to save/restore the registers in 64-bits. */
18456 if (crtl
->calls_eh_return
18457 || cfun
->calls_setjmp
18458 || crtl
->has_nonlocal_goto
)
18461 insns
= get_insns ();
18463 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
18469 /* FIXME: This should be implemented with attributes...
18471 (set_attr "spe64" "true")....then,
18472 if (get_spe64(insn)) return true;
18474 It's the only reliable way to do the stuff below. */
18476 i
= PATTERN (insn
);
18477 if (GET_CODE (i
) == SET
)
18479 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
18481 if (SPE_VECTOR_MODE (mode
))
18483 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
))
18493 debug_stack_info (rs6000_stack_t
*info
)
18495 const char *abi_string
;
18498 info
= rs6000_stack_info ();
18500 fprintf (stderr
, "\nStack information for function %s:\n",
18501 ((current_function_decl
&& DECL_NAME (current_function_decl
))
18502 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
18507 default: abi_string
= "Unknown"; break;
18508 case ABI_NONE
: abi_string
= "NONE"; break;
18509 case ABI_AIX
: abi_string
= "AIX"; break;
18510 case ABI_DARWIN
: abi_string
= "Darwin"; break;
18511 case ABI_V4
: abi_string
= "V.4"; break;
18514 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
18516 if (TARGET_ALTIVEC_ABI
)
18517 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
18519 if (TARGET_SPE_ABI
)
18520 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
18522 if (info
->first_gp_reg_save
!= 32)
18523 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
18525 if (info
->first_fp_reg_save
!= 64)
18526 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
18528 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
18529 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
18530 info
->first_altivec_reg_save
);
18532 if (info
->lr_save_p
)
18533 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
18535 if (info
->cr_save_p
)
18536 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
18538 if (info
->vrsave_mask
)
18539 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
18542 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
18545 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
18547 if (info
->gp_save_offset
)
18548 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
18550 if (info
->fp_save_offset
)
18551 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
18553 if (info
->altivec_save_offset
)
18554 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
18555 info
->altivec_save_offset
);
18557 if (info
->spe_gp_save_offset
)
18558 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
18559 info
->spe_gp_save_offset
);
18561 if (info
->vrsave_save_offset
)
18562 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
18563 info
->vrsave_save_offset
);
18565 if (info
->lr_save_offset
)
18566 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
18568 if (info
->cr_save_offset
)
18569 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
18571 if (info
->varargs_save_offset
)
18572 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
18574 if (info
->total_size
)
18575 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
18578 if (info
->vars_size
)
18579 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
18582 if (info
->parm_size
)
18583 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
18585 if (info
->fixed_size
)
18586 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
18589 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
18591 if (info
->spe_gp_size
)
18592 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
18595 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
18597 if (info
->altivec_size
)
18598 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
18600 if (info
->vrsave_size
)
18601 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
18603 if (info
->altivec_padding_size
)
18604 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
18605 info
->altivec_padding_size
);
18607 if (info
->spe_padding_size
)
18608 fprintf (stderr
, "\tspe_padding_size = %5d\n",
18609 info
->spe_padding_size
);
18612 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
18614 if (info
->save_size
)
18615 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
18617 if (info
->reg_size
!= 4)
18618 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
18620 fprintf (stderr
, "\n");
18624 rs6000_return_addr (int count
, rtx frame
)
18626 /* Currently we don't optimize very well between prolog and body
18627 code and for PIC code the code can be actually quite bad, so
18628 don't try to be too clever here. */
18629 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
18631 cfun
->machine
->ra_needs_full_frame
= 1;
18638 plus_constant (copy_to_reg
18639 (gen_rtx_MEM (Pmode
,
18640 memory_address (Pmode
, frame
))),
18641 RETURN_ADDRESS_OFFSET
)));
18644 cfun
->machine
->ra_need_lr
= 1;
18645 return get_hard_reg_initial_val (Pmode
, LR_REGNO
);
18648 /* Say whether a function is a candidate for sibcall handling or not.
18649 We do not allow indirect calls to be optimized into sibling calls.
18650 Also, we can't do it if there are any vector parameters; there's
18651 nowhere to put the VRsave code so it works; note that functions with
18652 vector parameters are required to have a prototype, so the argument
18653 type info must be available here. (The tail recursion case can work
18654 with vector parameters, but there's no way to distinguish here.) */
18656 rs6000_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
18661 if (TARGET_ALTIVEC_VRSAVE
)
18663 for (type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
18664 type
; type
= TREE_CHAIN (type
))
18666 if (TREE_CODE (TREE_VALUE (type
)) == VECTOR_TYPE
)
18670 if (DEFAULT_ABI
== ABI_DARWIN
18671 || ((*targetm
.binds_local_p
) (decl
)
18672 && (DEFAULT_ABI
!= ABI_AIX
|| !DECL_EXTERNAL (decl
))))
18674 tree attr_list
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
18676 if (!lookup_attribute ("longcall", attr_list
)
18677 || lookup_attribute ("shortcall", attr_list
))
18684 /* NULL if INSN insn is valid within a low-overhead loop.
18685 Otherwise return why doloop cannot be applied.
18686 PowerPC uses the COUNT register for branch on table instructions. */
18688 static const char *
18689 rs6000_invalid_within_doloop (const_rtx insn
)
18692 return "Function call in the loop.";
18695 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
18696 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
18697 return "Computed branch in the loop.";
18703 rs6000_ra_ever_killed (void)
18709 if (cfun
->is_thunk
)
18712 if (cfun
->machine
->lr_save_state
)
18713 return cfun
->machine
->lr_save_state
- 1;
18715 /* regs_ever_live has LR marked as used if any sibcalls are present,
18716 but this should not force saving and restoring in the
18717 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18718 clobbers LR, so that is inappropriate. */
18720 /* Also, the prologue can generate a store into LR that
18721 doesn't really count, like this:
18724 bcl to set PIC register
18728 When we're called from the epilogue, we need to avoid counting
18729 this as a store. */
18731 push_topmost_sequence ();
18732 top
= get_insns ();
18733 pop_topmost_sequence ();
18734 reg
= gen_rtx_REG (Pmode
, LR_REGNO
);
18736 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
18742 if (!SIBLING_CALL_P (insn
))
18745 else if (find_regno_note (insn
, REG_INC
, LR_REGNO
))
18747 else if (set_of (reg
, insn
) != NULL_RTX
18748 && !prologue_epilogue_contains (insn
))
18755 /* Emit instructions needed to load the TOC register.
18756 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18757 a constant pool; or for SVR4 -fpic. */
18760 rs6000_emit_load_toc_table (int fromprolog
)
18763 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
18765 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
18768 rtx lab
, tmp1
, tmp2
, got
;
18770 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
18771 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
18773 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
18775 got
= rs6000_got_sym ();
18776 tmp1
= tmp2
= dest
;
18779 tmp1
= gen_reg_rtx (Pmode
);
18780 tmp2
= gen_reg_rtx (Pmode
);
18782 emit_insn (gen_load_toc_v4_PIC_1 (lab
));
18783 emit_move_insn (tmp1
,
18784 gen_rtx_REG (Pmode
, LR_REGNO
));
18785 emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
18786 emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
18788 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
18790 emit_insn (gen_load_toc_v4_pic_si ());
18791 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
18793 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
18796 rtx temp0
= (fromprolog
18797 ? gen_rtx_REG (Pmode
, 0)
18798 : gen_reg_rtx (Pmode
));
18804 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
18805 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
18807 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
18808 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
18810 emit_insn (gen_load_toc_v4_PIC_1 (symF
));
18811 emit_move_insn (dest
,
18812 gen_rtx_REG (Pmode
, LR_REGNO
));
18813 emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
, symL
, symF
));
18819 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
18820 lab
= gen_label_rtx ();
18821 emit_insn (gen_load_toc_v4_PIC_1b (tocsym
, lab
));
18822 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
18823 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
18825 emit_insn (gen_addsi3 (dest
, temp0
, dest
));
18827 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
18829 /* This is for AIX code running in non-PIC ELF32. */
18832 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
18833 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
18835 emit_insn (gen_elf_high (dest
, realsym
));
18836 emit_insn (gen_elf_low (dest
, dest
, realsym
));
18840 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
18843 emit_insn (gen_load_toc_aix_si (dest
));
18845 emit_insn (gen_load_toc_aix_di (dest
));
18849 /* Emit instructions to restore the link register after determining where
18850 its value has been stored. */
18853 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
18855 rs6000_stack_t
*info
= rs6000_stack_info ();
18858 operands
[0] = source
;
18859 operands
[1] = scratch
;
18861 if (info
->lr_save_p
)
18863 rtx frame_rtx
= stack_pointer_rtx
;
18864 HOST_WIDE_INT sp_offset
= 0;
18867 if (frame_pointer_needed
18868 || cfun
->calls_alloca
18869 || info
->total_size
> 32767)
18871 tmp
= gen_frame_mem (Pmode
, frame_rtx
);
18872 emit_move_insn (operands
[1], tmp
);
18873 frame_rtx
= operands
[1];
18875 else if (info
->push_p
)
18876 sp_offset
= info
->total_size
;
18878 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
18879 tmp
= gen_frame_mem (Pmode
, tmp
);
18880 emit_move_insn (tmp
, operands
[0]);
18883 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
), operands
[0]);
18885 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18886 state of lr_save_p so any change from here on would be a bug. In
18887 particular, stop rs6000_ra_ever_killed from considering the SET
18888 of lr we may have added just above. */
18889 cfun
->machine
->lr_save_state
= info
->lr_save_p
+ 1;
18892 static GTY(()) alias_set_type set
= -1;
18895 get_TOC_alias_set (void)
18898 set
= new_alias_set ();
18902 /* This returns nonzero if the current function uses the TOC. This is
18903 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18904 is generated by the ABI_V4 load_toc_* patterns. */
18911 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
18914 rtx pat
= PATTERN (insn
);
18917 if (GET_CODE (pat
) == PARALLEL
)
18918 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
18920 rtx sub
= XVECEXP (pat
, 0, i
);
18921 if (GET_CODE (sub
) == USE
)
18923 sub
= XEXP (sub
, 0);
18924 if (GET_CODE (sub
) == UNSPEC
18925 && XINT (sub
, 1) == UNSPEC_TOC
)
18935 create_TOC_reference (rtx symbol
, rtx largetoc_reg
)
18937 rtx tocrel
, tocreg
;
18939 if (TARGET_DEBUG_ADDR
)
18941 if (GET_CODE (symbol
) == SYMBOL_REF
)
18942 fprintf (stderr
, "\ncreate_TOC_reference, (symbol_ref %s)\n",
18946 fprintf (stderr
, "\ncreate_TOC_reference, code %s:\n",
18947 GET_RTX_NAME (GET_CODE (symbol
)));
18948 debug_rtx (symbol
);
18952 if (!can_create_pseudo_p ())
18953 df_set_regs_ever_live (TOC_REGISTER
, true);
18955 tocrel
= gen_rtx_CONST (Pmode
,
18956 gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, symbol
),
18958 tocreg
= gen_rtx_REG (Pmode
, TOC_REGISTER
);
18959 if (TARGET_CMODEL
!= CMODEL_SMALL
)
18961 rtx hi
= gen_rtx_PLUS (Pmode
, tocreg
, gen_rtx_HIGH (Pmode
, tocrel
));
18962 if (largetoc_reg
!= NULL
)
18964 emit_move_insn (largetoc_reg
, hi
);
18967 return gen_rtx_LO_SUM (Pmode
, hi
, copy_rtx (tocrel
));
18970 return gen_rtx_PLUS (Pmode
, tocreg
, tocrel
);
18973 /* Issue assembly directives that create a reference to the given DWARF
18974 FRAME_TABLE_LABEL from the current function section. */
18976 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label
)
18978 fprintf (asm_out_file
, "\t.ref %s\n",
18979 TARGET_STRIP_NAME_ENCODING (frame_table_label
));
18982 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18983 and the change to the stack pointer. */
18986 rs6000_emit_stack_tie (void)
18988 rtx mem
= gen_frame_mem (BLKmode
,
18989 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
18991 emit_insn (gen_stack_tie (mem
));
18994 /* Emit the correct code for allocating stack space, as insns.
18995 If COPY_REG, make sure a copy of the old frame is left there.
18996 The generated code may use hard register 0 as a temporary. */
18999 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, rtx copy_reg
)
19002 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
19003 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
19004 rtx todec
= gen_int_mode (-size
, Pmode
);
19007 if (INTVAL (todec
) != -size
)
19009 warning (0, "stack frame too large");
19010 emit_insn (gen_trap ());
19014 if (crtl
->limit_stack
)
19016 if (REG_P (stack_limit_rtx
)
19017 && REGNO (stack_limit_rtx
) > 1
19018 && REGNO (stack_limit_rtx
) <= 31)
19020 emit_insn (gen_add3_insn (tmp_reg
, stack_limit_rtx
, GEN_INT (size
)));
19021 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
19024 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
19026 && DEFAULT_ABI
== ABI_V4
)
19028 rtx toload
= gen_rtx_CONST (VOIDmode
,
19029 gen_rtx_PLUS (Pmode
,
19033 emit_insn (gen_elf_high (tmp_reg
, toload
));
19034 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
19035 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
19039 warning (0, "stack limit expression is not supported");
19043 emit_move_insn (copy_reg
, stack_reg
);
19047 /* Need a note here so that try_split doesn't get confused. */
19048 if (get_last_insn () == NULL_RTX
)
19049 emit_note (NOTE_INSN_DELETED
);
19050 insn
= emit_move_insn (tmp_reg
, todec
);
19051 try_split (PATTERN (insn
), insn
, 0);
19055 insn
= emit_insn (TARGET_32BIT
19056 ? gen_movsi_update_stack (stack_reg
, stack_reg
,
19058 : gen_movdi_di_update_stack (stack_reg
, stack_reg
,
19059 todec
, stack_reg
));
19060 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19061 it now and set the alias set/attributes. The above gen_*_update
19062 calls will generate a PARALLEL with the MEM set being the first
19064 par
= PATTERN (insn
);
19065 gcc_assert (GET_CODE (par
) == PARALLEL
);
19066 set
= XVECEXP (par
, 0, 0);
19067 gcc_assert (GET_CODE (set
) == SET
);
19068 mem
= SET_DEST (set
);
19069 gcc_assert (MEM_P (mem
));
19070 MEM_NOTRAP_P (mem
) = 1;
19071 set_mem_alias_set (mem
, get_frame_alias_set ());
19073 RTX_FRAME_RELATED_P (insn
) = 1;
19074 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
19075 gen_rtx_SET (VOIDmode
, stack_reg
,
19076 gen_rtx_PLUS (Pmode
, stack_reg
,
19077 GEN_INT (-size
))));
19080 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19082 #if PROBE_INTERVAL > 32768
19083 #error Cannot use indexed addressing mode for stack probing
19086 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19087 inclusive. These are offsets from the current stack pointer. */
19090 rs6000_emit_probe_stack_range (HOST_WIDE_INT first
, HOST_WIDE_INT size
)
19092 /* See if we have a constant small number of probes to generate. If so,
19093 that's the easy case. */
19094 if (first
+ size
<= 32768)
19098 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19099 it exceeds SIZE. If only one probe is needed, this will not
19100 generate any code. Then probe at FIRST + SIZE. */
19101 for (i
= PROBE_INTERVAL
; i
< size
; i
+= PROBE_INTERVAL
)
19102 emit_stack_probe (plus_constant (stack_pointer_rtx
, -(first
+ i
)));
19104 emit_stack_probe (plus_constant (stack_pointer_rtx
, -(first
+ size
)));
19107 /* Otherwise, do the same as above, but in a loop. Note that we must be
19108 extra careful with variables wrapping around because we might be at
19109 the very top (or the very bottom) of the address space and we have
19110 to be able to handle this case properly; in particular, we use an
19111 equality test for the loop condition. */
19114 HOST_WIDE_INT rounded_size
;
19115 rtx r12
= gen_rtx_REG (Pmode
, 12);
19116 rtx r0
= gen_rtx_REG (Pmode
, 0);
19118 /* Sanity check for the addressing mode we're going to use. */
19119 gcc_assert (first
<= 32768);
19121 /* Step 1: round SIZE to the previous multiple of the interval. */
19123 rounded_size
= size
& -PROBE_INTERVAL
;
19126 /* Step 2: compute initial and final value of the loop counter. */
19128 /* TEST_ADDR = SP + FIRST. */
19129 emit_insn (gen_rtx_SET (VOIDmode
, r12
,
19130 plus_constant (stack_pointer_rtx
, -first
)));
19132 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19133 if (rounded_size
> 32768)
19135 emit_move_insn (r0
, GEN_INT (-rounded_size
));
19136 emit_insn (gen_rtx_SET (VOIDmode
, r0
,
19137 gen_rtx_PLUS (Pmode
, r12
, r0
)));
19140 emit_insn (gen_rtx_SET (VOIDmode
, r0
,
19141 plus_constant (r12
, -rounded_size
)));
19144 /* Step 3: the loop
19146 while (TEST_ADDR != LAST_ADDR)
19148 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19152 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19153 until it is equal to ROUNDED_SIZE. */
19156 emit_insn (gen_probe_stack_rangedi (r12
, r12
, r0
));
19158 emit_insn (gen_probe_stack_rangesi (r12
, r12
, r0
));
19161 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19162 that SIZE is equal to ROUNDED_SIZE. */
19164 if (size
!= rounded_size
)
19165 emit_stack_probe (plus_constant (r12
, rounded_size
- size
));
19169 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19170 absolute addresses. */
19173 output_probe_stack_range (rtx reg1
, rtx reg2
)
19175 static int labelno
= 0;
19176 char loop_lab
[32], end_lab
[32];
19179 ASM_GENERATE_INTERNAL_LABEL (loop_lab
, "LPSRL", labelno
);
19180 ASM_GENERATE_INTERNAL_LABEL (end_lab
, "LPSRE", labelno
++);
19182 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, loop_lab
);
19184 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19188 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops
);
19190 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops
);
19192 fputs ("\tbeq 0,", asm_out_file
);
19193 assemble_name_raw (asm_out_file
, end_lab
);
19194 fputc ('\n', asm_out_file
);
19196 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19197 xops
[1] = GEN_INT (-PROBE_INTERVAL
);
19198 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops
);
19200 /* Probe at TEST_ADDR and branch. */
19201 output_asm_insn ("{st|stw} 0,0(%0)", xops
);
19202 fprintf (asm_out_file
, "\tb ");
19203 assemble_name_raw (asm_out_file
, loop_lab
);
19204 fputc ('\n', asm_out_file
);
19206 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, end_lab
);
19211 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19212 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19213 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19214 deduce these equivalences by itself so it wasn't necessary to hold
19215 its hand so much. */
19218 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
19219 rtx reg2
, rtx rreg
)
19223 /* copy_rtx will not make unique copies of registers, so we need to
19224 ensure we don't have unwanted sharing here. */
19226 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
19229 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
19231 real
= copy_rtx (PATTERN (insn
));
19233 if (reg2
!= NULL_RTX
)
19234 real
= replace_rtx (real
, reg2
, rreg
);
19236 real
= replace_rtx (real
, reg
,
19237 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
19238 STACK_POINTER_REGNUM
),
19241 /* We expect that 'real' is either a SET or a PARALLEL containing
19242 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19243 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19245 if (GET_CODE (real
) == SET
)
19249 temp
= simplify_rtx (SET_SRC (set
));
19251 SET_SRC (set
) = temp
;
19252 temp
= simplify_rtx (SET_DEST (set
));
19254 SET_DEST (set
) = temp
;
19255 if (GET_CODE (SET_DEST (set
)) == MEM
)
19257 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
19259 XEXP (SET_DEST (set
), 0) = temp
;
19266 gcc_assert (GET_CODE (real
) == PARALLEL
);
19267 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
19268 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
19270 rtx set
= XVECEXP (real
, 0, i
);
19272 temp
= simplify_rtx (SET_SRC (set
));
19274 SET_SRC (set
) = temp
;
19275 temp
= simplify_rtx (SET_DEST (set
));
19277 SET_DEST (set
) = temp
;
19278 if (GET_CODE (SET_DEST (set
)) == MEM
)
19280 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
19282 XEXP (SET_DEST (set
), 0) = temp
;
19284 RTX_FRAME_RELATED_P (set
) = 1;
19288 RTX_FRAME_RELATED_P (insn
) = 1;
19289 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, real
);
19292 /* Returns an insn that has a vrsave set operation with the
19293 appropriate CLOBBERs. */
19296 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
19299 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
19300 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
19303 = gen_rtx_SET (VOIDmode
,
19305 gen_rtx_UNSPEC_VOLATILE (SImode
,
19306 gen_rtvec (2, reg
, vrsave
),
19307 UNSPECV_SET_VRSAVE
));
19311 /* We need to clobber the registers in the mask so the scheduler
19312 does not move sets to VRSAVE before sets of AltiVec registers.
19314 However, if the function receives nonlocal gotos, reload will set
19315 all call saved registers live. We will end up with:
19317 (set (reg 999) (mem))
19318 (parallel [ (set (reg vrsave) (unspec blah))
19319 (clobber (reg 999))])
19321 The clobber will cause the store into reg 999 to be dead, and
19322 flow will attempt to delete an epilogue insn. In this case, we
19323 need an unspec use/set of the register. */
19325 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
19326 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
19328 if (!epiloguep
|| call_used_regs
[i
])
19329 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
19330 gen_rtx_REG (V4SImode
, i
));
19333 rtx reg
= gen_rtx_REG (V4SImode
, i
);
19336 = gen_rtx_SET (VOIDmode
,
19338 gen_rtx_UNSPEC (V4SImode
,
19339 gen_rtvec (1, reg
), 27));
19343 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
19345 for (i
= 0; i
< nclobs
; ++i
)
19346 XVECEXP (insn
, 0, i
) = clobs
[i
];
19351 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19352 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19355 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
19356 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
19358 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
19359 rtx replacea
, replaceb
;
19361 int_rtx
= GEN_INT (offset
);
19363 /* Some cases that need register indexed addressing. */
19364 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
19365 || (TARGET_VSX
&& VSX_VECTOR_MODE (mode
))
19366 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
19368 && SPE_VECTOR_MODE (mode
)
19369 && !SPE_CONST_OFFSET_OK (offset
)))
19371 /* Whomever calls us must make sure r11 is available in the
19372 flow path of instructions in the prologue. */
19373 offset_rtx
= gen_rtx_REG (Pmode
, 11);
19374 emit_move_insn (offset_rtx
, int_rtx
);
19376 replacea
= offset_rtx
;
19377 replaceb
= int_rtx
;
19381 offset_rtx
= int_rtx
;
19382 replacea
= NULL_RTX
;
19383 replaceb
= NULL_RTX
;
19386 reg
= gen_rtx_REG (mode
, regno
);
19387 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
19388 mem
= gen_frame_mem (mode
, addr
);
19390 insn
= emit_move_insn (mem
, reg
);
19392 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
19395 /* Emit an offset memory reference suitable for a frame store, while
19396 converting to a valid addressing mode. */
19399 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
19401 rtx int_rtx
, offset_rtx
;
19403 int_rtx
= GEN_INT (offset
);
19405 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
19406 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
19408 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
19409 emit_move_insn (offset_rtx
, int_rtx
);
19412 offset_rtx
= int_rtx
;
19414 return gen_frame_mem (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
19417 /* Look for user-defined global regs. We should not save and restore these,
19418 and cannot use stmw/lmw if there are any in its range. */
19421 no_global_regs_above (int first
, bool gpr
)
19424 int last
= gpr
? 32 : 64;
19425 for (i
= first
; i
< last
; i
++)
19426 if (global_regs
[i
])
19431 #ifndef TARGET_FIX_AND_CONTINUE
19432 #define TARGET_FIX_AND_CONTINUE 0
19435 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19436 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19437 #define LAST_SAVRES_REGISTER 31
19438 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19440 static GTY(()) rtx savres_routine_syms
[N_SAVRES_REGISTERS
][8];
19442 /* Temporary holding space for an out-of-line register save/restore
19444 static char savres_routine_name
[30];
19446 /* Return the name for an out-of-line register save/restore routine.
19447 We are saving/restoring GPRs if GPR is true. */
19450 rs6000_savres_routine_name (rs6000_stack_t
*info
, int regno
,
19451 bool savep
, bool gpr
, bool lr
)
19453 const char *prefix
= "";
19454 const char *suffix
= "";
19456 /* Different targets are supposed to define
19457 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19458 routine name could be defined with:
19460 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19462 This is a nice idea in practice, but in reality, things are
19463 complicated in several ways:
19465 - ELF targets have save/restore routines for GPRs.
19467 - SPE targets use different prefixes for 32/64-bit registers, and
19468 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19470 - PPC64 ELF targets have routines for save/restore of GPRs that
19471 differ in what they do with the link register, so having a set
19472 prefix doesn't work. (We only use one of the save routines at
19473 the moment, though.)
19475 - PPC32 elf targets have "exit" versions of the restore routines
19476 that restore the link register and can save some extra space.
19477 These require an extra suffix. (There are also "tail" versions
19478 of the restore routines and "GOT" versions of the save routines,
19479 but we don't generate those at present. Same problems apply,
19482 We deal with all this by synthesizing our own prefix/suffix and
19483 using that for the simple sprintf call shown above. */
19486 /* No floating point saves on the SPE. */
19490 prefix
= info
->spe_64bit_regs_used
? "_save64gpr_" : "_save32gpr_";
19492 prefix
= info
->spe_64bit_regs_used
? "_rest64gpr_" : "_rest32gpr_";
19497 else if (DEFAULT_ABI
== ABI_V4
)
19503 prefix
= savep
? "_savegpr_" : "_restgpr_";
19505 prefix
= savep
? "_savefpr_" : "_restfpr_";
19510 else if (DEFAULT_ABI
== ABI_AIX
)
19512 #ifndef POWERPC_LINUX
19513 /* No out-of-line save/restore routines for GPRs on AIX. */
19514 gcc_assert (!TARGET_AIX
|| !gpr
);
19520 ? (lr
? "_savegpr0_" : "_savegpr1_")
19521 : (lr
? "_restgpr0_" : "_restgpr1_"));
19522 #ifdef POWERPC_LINUX
19524 prefix
= (savep
? "_savefpr_" : "_restfpr_");
19528 prefix
= savep
? SAVE_FP_PREFIX
: RESTORE_FP_PREFIX
;
19529 suffix
= savep
? SAVE_FP_SUFFIX
: RESTORE_FP_SUFFIX
;
19532 else if (DEFAULT_ABI
== ABI_DARWIN
)
19533 sorry ("Out-of-line save/restore routines not supported on Darwin");
19535 sprintf (savres_routine_name
, "%s%d%s", prefix
, regno
, suffix
);
19537 return savres_routine_name
;
19540 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19541 We are saving/restoring GPRs if GPR is true. */
19544 rs6000_savres_routine_sym (rs6000_stack_t
*info
, bool savep
,
19547 int regno
= gpr
? info
->first_gp_reg_save
: (info
->first_fp_reg_save
- 32);
19549 int select
= ((savep
? 1 : 0) << 2
19551 /* On the SPE, we never have any FPRs, but we do have
19552 32/64-bit versions of the routines. */
19553 ? (info
->spe_64bit_regs_used
? 1 : 0)
19554 : (gpr
? 1 : 0)) << 1)
19557 /* Don't generate bogus routine names. */
19558 gcc_assert (FIRST_SAVRES_REGISTER
<= regno
19559 && regno
<= LAST_SAVRES_REGISTER
);
19561 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
];
19567 name
= rs6000_savres_routine_name (info
, regno
, savep
, gpr
, lr
);
19569 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
]
19570 = gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (name
));
19571 SYMBOL_REF_FLAGS (sym
) |= SYMBOL_FLAG_FUNCTION
;
19577 /* Emit a sequence of insns, including a stack tie if needed, for
19578 resetting the stack pointer. If SAVRES is true, then don't reset the
19579 stack pointer, but move the base of the frame into r11 for use by
19580 out-of-line register restore routines. */
19583 rs6000_emit_stack_reset (rs6000_stack_t
*info
,
19584 rtx sp_reg_rtx
, rtx frame_reg_rtx
,
19585 int sp_offset
, bool savres
)
19587 /* This blockage is needed so that sched doesn't decide to move
19588 the sp change before the register restores. */
19589 if (frame_reg_rtx
!= sp_reg_rtx
19591 && info
->spe_64bit_regs_used
!= 0
19592 && info
->first_gp_reg_save
!= 32))
19593 rs6000_emit_stack_tie ();
19595 if (frame_reg_rtx
!= sp_reg_rtx
)
19597 if (sp_offset
!= 0)
19599 rtx dest_reg
= savres
? gen_rtx_REG (Pmode
, 11) : sp_reg_rtx
;
19600 return emit_insn (gen_add3_insn (dest_reg
, frame_reg_rtx
,
19601 GEN_INT (sp_offset
)));
19604 return emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
19606 else if (sp_offset
!= 0)
19608 /* If we are restoring registers out-of-line, we will be using the
19609 "exit" variants of the restore routines, which will reset the
19610 stack for us. But we do need to point r11 into the right place
19611 for those routines. */
19612 rtx dest_reg
= (savres
19613 ? gen_rtx_REG (Pmode
, 11)
19616 rtx insn
= emit_insn (gen_add3_insn (dest_reg
, sp_reg_rtx
,
19617 GEN_INT (sp_offset
)));
19624 /* Construct a parallel rtx describing the effect of a call to an
19625 out-of-line register save/restore routine. */
19628 rs6000_make_savres_rtx (rs6000_stack_t
*info
,
19629 rtx frame_reg_rtx
, int save_area_offset
,
19630 enum machine_mode reg_mode
,
19631 bool savep
, bool gpr
, bool lr
)
19634 int offset
, start_reg
, end_reg
, n_regs
;
19635 int reg_size
= GET_MODE_SIZE (reg_mode
);
19641 ? info
->first_gp_reg_save
19642 : info
->first_fp_reg_save
);
19643 end_reg
= gpr
? 32 : 64;
19644 n_regs
= end_reg
- start_reg
;
19645 p
= rtvec_alloc ((lr
? 4 : 3) + n_regs
);
19648 RTVEC_ELT (p
, offset
++) = gen_rtx_RETURN (VOIDmode
);
19650 RTVEC_ELT (p
, offset
++)
19651 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 65));
19653 sym
= rs6000_savres_routine_sym (info
, savep
, gpr
, lr
);
19654 RTVEC_ELT (p
, offset
++) = gen_rtx_USE (VOIDmode
, sym
);
19655 RTVEC_ELT (p
, offset
++)
19656 = gen_rtx_USE (VOIDmode
,
19657 gen_rtx_REG (Pmode
, DEFAULT_ABI
!= ABI_AIX
? 11
19661 for (i
= 0; i
< end_reg
- start_reg
; i
++)
19663 rtx addr
, reg
, mem
;
19664 reg
= gen_rtx_REG (reg_mode
, start_reg
+ i
);
19665 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19666 GEN_INT (save_area_offset
+ reg_size
*i
));
19667 mem
= gen_frame_mem (reg_mode
, addr
);
19669 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
,
19671 savep
? reg
: mem
);
19676 rtx addr
, reg
, mem
;
19677 reg
= gen_rtx_REG (Pmode
, 0);
19678 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19679 GEN_INT (info
->lr_save_offset
));
19680 mem
= gen_frame_mem (Pmode
, addr
);
19681 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
19684 return gen_rtx_PARALLEL (VOIDmode
, p
);
19687 /* Determine whether the gp REG is really used. */
19690 rs6000_reg_live_or_pic_offset_p (int reg
)
19692 return ((df_regs_ever_live_p (reg
)
19693 && (!call_used_regs
[reg
]
19694 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
19695 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
19696 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
19697 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
19698 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))));
19702 SAVRES_MULTIPLE
= 0x1,
19703 SAVRES_INLINE_FPRS
= 0x2,
19704 SAVRES_INLINE_GPRS
= 0x4,
19705 SAVRES_NOINLINE_GPRS_SAVES_LR
= 0x8,
19706 SAVRES_NOINLINE_FPRS_SAVES_LR
= 0x10,
19707 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR
= 0x20
19710 /* Determine the strategy for savings/restoring registers. */
19713 rs6000_savres_strategy (rs6000_stack_t
*info
, bool savep
,
19714 int using_static_chain_p
, int sibcall
)
19716 bool using_multiple_p
;
19718 bool savres_fprs_inline
;
19719 bool savres_gprs_inline
;
19720 bool noclobber_global_gprs
19721 = no_global_regs_above (info
->first_gp_reg_save
, /*gpr=*/true);
19724 using_multiple_p
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
19725 && (!TARGET_SPE_ABI
19726 || info
->spe_64bit_regs_used
== 0)
19727 && info
->first_gp_reg_save
< 31
19728 && noclobber_global_gprs
);
19729 /* Don't bother to try to save things out-of-line if r11 is occupied
19730 by the static chain. It would require too much fiddling and the
19731 static chain is rarely used anyway. */
19732 common
= (using_static_chain_p
19734 || crtl
->calls_eh_return
19735 || !info
->lr_save_p
19736 || cfun
->machine
->ra_need_lr
19737 || info
->total_size
> 32767);
19738 savres_fprs_inline
= (common
19739 || info
->first_fp_reg_save
== 64
19740 || !no_global_regs_above (info
->first_fp_reg_save
,
19742 /* The out-of-line FP routines use
19743 double-precision stores; we can't use those
19744 routines if we don't have such stores. */
19745 || (TARGET_HARD_FLOAT
&& !TARGET_DOUBLE_FLOAT
)
19746 || FP_SAVE_INLINE (info
->first_fp_reg_save
));
19747 savres_gprs_inline
= (common
19748 /* Saving CR interferes with the exit routines
19749 used on the SPE, so just punt here. */
19752 && info
->spe_64bit_regs_used
!= 0
19753 && info
->cr_save_p
!= 0)
19754 || info
->first_gp_reg_save
== 32
19755 || !noclobber_global_gprs
19756 || GP_SAVE_INLINE (info
->first_gp_reg_save
));
19759 /* If we are going to use store multiple, then don't even bother
19760 with the out-of-line routines, since the store-multiple instruction
19761 will always be smaller. */
19762 savres_gprs_inline
= savres_gprs_inline
|| using_multiple_p
;
19765 /* The situation is more complicated with load multiple. We'd
19766 prefer to use the out-of-line routines for restores, since the
19767 "exit" out-of-line routines can handle the restore of LR and
19768 the frame teardown. But we can only use the out-of-line
19769 routines if we know that we've used store multiple or
19770 out-of-line routines in the prologue, i.e. if we've saved all
19771 the registers from first_gp_reg_save. Otherwise, we risk
19772 loading garbage from the stack. Furthermore, we can only use
19773 the "exit" out-of-line gpr restore if we haven't saved any
19775 bool saved_all
= !savres_gprs_inline
|| using_multiple_p
;
19777 if (saved_all
&& info
->first_fp_reg_save
!= 64)
19778 /* We can't use the exit routine; use load multiple if it's
19780 savres_gprs_inline
= savres_gprs_inline
|| using_multiple_p
;
19783 strategy
= (using_multiple_p
19784 | (savres_fprs_inline
<< 1)
19785 | (savres_gprs_inline
<< 2));
19786 #ifdef POWERPC_LINUX
19789 if (!savres_fprs_inline
)
19790 strategy
|= SAVRES_NOINLINE_FPRS_SAVES_LR
;
19791 else if (!savres_gprs_inline
&& info
->first_fp_reg_save
== 64)
19792 strategy
|= SAVRES_NOINLINE_GPRS_SAVES_LR
;
19795 if (TARGET_AIX
&& !savres_fprs_inline
)
19796 strategy
|= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR
;
19801 /* Emit function prologue as insns. */
19804 rs6000_emit_prologue (void)
19806 rs6000_stack_t
*info
= rs6000_stack_info ();
19807 enum machine_mode reg_mode
= Pmode
;
19808 int reg_size
= TARGET_32BIT
? 4 : 8;
19809 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
19810 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
19811 rtx frame_reg_rtx
= sp_reg_rtx
;
19812 rtx cr_save_rtx
= NULL_RTX
;
19815 int saving_FPRs_inline
;
19816 int saving_GPRs_inline
;
19817 int using_store_multiple
;
19818 int using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
19819 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
19820 && call_used_regs
[STATIC_CHAIN_REGNUM
]);
19821 HOST_WIDE_INT sp_offset
= 0;
19823 if (flag_stack_usage
)
19824 current_function_static_stack_size
= info
->total_size
;
19826 if (flag_stack_check
== STATIC_BUILTIN_STACK_CHECK
&& info
->total_size
)
19827 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT
, info
->total_size
);
19829 if (TARGET_FIX_AND_CONTINUE
)
19831 /* gdb on darwin arranges to forward a function from the old
19832 address by modifying the first 5 instructions of the function
19833 to branch to the overriding function. This is necessary to
19834 permit function pointers that point to the old function to
19835 actually forward to the new function. */
19836 emit_insn (gen_nop ());
19837 emit_insn (gen_nop ());
19838 emit_insn (gen_nop ());
19839 emit_insn (gen_nop ());
19840 emit_insn (gen_nop ());
19843 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
19845 reg_mode
= V2SImode
;
19849 strategy
= rs6000_savres_strategy (info
, /*savep=*/true,
19850 /*static_chain_p=*/using_static_chain_p
,
19852 using_store_multiple
= strategy
& SAVRES_MULTIPLE
;
19853 saving_FPRs_inline
= strategy
& SAVRES_INLINE_FPRS
;
19854 saving_GPRs_inline
= strategy
& SAVRES_INLINE_GPRS
;
19856 /* For V.4, update stack before we do any saving and set back pointer. */
19857 if (! WORLD_SAVE_P (info
)
19859 && (DEFAULT_ABI
== ABI_V4
19860 || crtl
->calls_eh_return
))
19862 bool need_r11
= (TARGET_SPE
19863 ? (!saving_GPRs_inline
19864 && info
->spe_64bit_regs_used
== 0)
19865 : (!saving_FPRs_inline
|| !saving_GPRs_inline
));
19866 rtx copy_reg
= need_r11
? gen_rtx_REG (Pmode
, 11) : NULL
;
19868 if (info
->total_size
< 32767)
19869 sp_offset
= info
->total_size
;
19871 frame_reg_rtx
= copy_reg
;
19872 else if (info
->cr_save_p
19874 || info
->first_fp_reg_save
< 64
19875 || info
->first_gp_reg_save
< 32
19876 || info
->altivec_size
!= 0
19877 || info
->vrsave_mask
!= 0
19878 || crtl
->calls_eh_return
)
19880 copy_reg
= frame_ptr_rtx
;
19881 frame_reg_rtx
= copy_reg
;
19885 /* The prologue won't be saving any regs so there is no need
19886 to set up a frame register to access any frame save area.
19887 We also won't be using sp_offset anywhere below, but set
19888 the correct value anyway to protect against future
19889 changes to this function. */
19890 sp_offset
= info
->total_size
;
19892 rs6000_emit_allocate_stack (info
->total_size
, copy_reg
);
19893 if (frame_reg_rtx
!= sp_reg_rtx
)
19894 rs6000_emit_stack_tie ();
19897 /* Handle world saves specially here. */
19898 if (WORLD_SAVE_P (info
))
19905 /* save_world expects lr in r0. */
19906 reg0
= gen_rtx_REG (Pmode
, 0);
19907 if (info
->lr_save_p
)
19909 insn
= emit_move_insn (reg0
,
19910 gen_rtx_REG (Pmode
, LR_REGNO
));
19911 RTX_FRAME_RELATED_P (insn
) = 1;
19914 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19915 assumptions about the offsets of various bits of the stack
19917 gcc_assert (info
->gp_save_offset
== -220
19918 && info
->fp_save_offset
== -144
19919 && info
->lr_save_offset
== 8
19920 && info
->cr_save_offset
== 4
19923 && (!crtl
->calls_eh_return
19924 || info
->ehrd_offset
== -432)
19925 && info
->vrsave_save_offset
== -224
19926 && info
->altivec_save_offset
== -416);
19928 treg
= gen_rtx_REG (SImode
, 11);
19929 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
19931 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19932 in R11. It also clobbers R12, so beware! */
19934 /* Preserve CR2 for save_world prologues */
19936 sz
+= 32 - info
->first_gp_reg_save
;
19937 sz
+= 64 - info
->first_fp_reg_save
;
19938 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
19939 p
= rtvec_alloc (sz
);
19941 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
19942 gen_rtx_REG (SImode
,
19944 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
19945 gen_rtx_SYMBOL_REF (Pmode
,
19947 /* We do floats first so that the instruction pattern matches
19949 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
19951 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
19952 ? DFmode
: SFmode
),
19953 info
->first_fp_reg_save
+ i
);
19954 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19955 GEN_INT (info
->fp_save_offset
19956 + sp_offset
+ 8 * i
));
19957 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
19958 ? DFmode
: SFmode
), addr
);
19960 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
19962 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
19964 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
19965 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19966 GEN_INT (info
->altivec_save_offset
19967 + sp_offset
+ 16 * i
));
19968 rtx mem
= gen_frame_mem (V4SImode
, addr
);
19970 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
19972 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
19974 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
19975 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19976 GEN_INT (info
->gp_save_offset
19977 + sp_offset
+ reg_size
* i
));
19978 rtx mem
= gen_frame_mem (reg_mode
, addr
);
19980 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
19984 /* CR register traditionally saved as CR2. */
19985 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
19986 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19987 GEN_INT (info
->cr_save_offset
19989 rtx mem
= gen_frame_mem (reg_mode
, addr
);
19991 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
19993 /* Explain about use of R0. */
19994 if (info
->lr_save_p
)
19996 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19997 GEN_INT (info
->lr_save_offset
19999 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20001 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg0
);
20003 /* Explain what happens to the stack pointer. */
20005 rtx newval
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
, treg
);
20006 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, sp_reg_rtx
, newval
);
20009 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20010 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20011 treg
, GEN_INT (-info
->total_size
));
20012 sp_offset
= info
->total_size
;
20015 /* If we use the link register, get it into r0. */
20016 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
20018 rtx addr
, reg
, mem
;
20020 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
20021 gen_rtx_REG (Pmode
, LR_REGNO
));
20022 RTX_FRAME_RELATED_P (insn
) = 1;
20024 if (!(strategy
& (SAVRES_NOINLINE_GPRS_SAVES_LR
20025 | SAVRES_NOINLINE_FPRS_SAVES_LR
)))
20027 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20028 GEN_INT (info
->lr_save_offset
+ sp_offset
));
20029 reg
= gen_rtx_REG (Pmode
, 0);
20030 mem
= gen_rtx_MEM (Pmode
, addr
);
20031 /* This should not be of rs6000_sr_alias_set, because of
20032 __builtin_return_address. */
20034 insn
= emit_move_insn (mem
, reg
);
20035 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20036 NULL_RTX
, NULL_RTX
);
20040 /* If we need to save CR, put it into r12 or r11. */
20041 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
20046 = gen_rtx_REG (SImode
, DEFAULT_ABI
== ABI_AIX
&& !saving_GPRs_inline
20048 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
20049 RTX_FRAME_RELATED_P (insn
) = 1;
20050 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20051 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20052 But that's OK. All we have to do is specify that _one_ condition
20053 code register is saved in this stack slot. The thrower's epilogue
20054 will then restore all the call-saved registers.
20055 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20056 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
20057 gen_rtx_REG (SImode
, CR2_REGNO
));
20058 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
20061 /* Do any required saving of fpr's. If only one or two to save, do
20062 it ourselves. Otherwise, call function. */
20063 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
20066 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
20067 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
20068 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
20069 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
,
20070 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20072 info
->first_fp_reg_save
+ i
,
20073 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
20076 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
20080 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
20081 info
->fp_save_offset
+ sp_offset
,
20083 /*savep=*/true, /*gpr=*/false,
20085 & SAVRES_NOINLINE_FPRS_SAVES_LR
)
20087 insn
= emit_insn (par
);
20088 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20089 NULL_RTX
, NULL_RTX
);
20092 /* Save GPRs. This is done as a PARALLEL if we are using
20093 the store-multiple instructions. */
20094 if (!WORLD_SAVE_P (info
)
20096 && info
->spe_64bit_regs_used
!= 0
20097 && info
->first_gp_reg_save
!= 32)
20100 rtx spe_save_area_ptr
;
20102 /* Determine whether we can address all of the registers that need
20103 to be saved with an offset from the stack pointer that fits in
20104 the small const field for SPE memory instructions. */
20105 int spe_regs_addressable_via_sp
20106 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
20107 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
20108 && saving_GPRs_inline
);
20111 if (spe_regs_addressable_via_sp
)
20113 spe_save_area_ptr
= frame_reg_rtx
;
20114 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
20118 /* Make r11 point to the start of the SPE save area. We need
20119 to be careful here if r11 is holding the static chain. If
20120 it is, then temporarily save it in r0. We would use r0 as
20121 our base register here, but using r0 as a base register in
20122 loads and stores means something different from what we
20124 int ool_adjust
= (saving_GPRs_inline
20126 : (info
->first_gp_reg_save
20127 - (FIRST_SAVRES_REGISTER
+1))*8);
20128 HOST_WIDE_INT offset
= (info
->spe_gp_save_offset
20129 + sp_offset
- ool_adjust
);
20131 if (using_static_chain_p
)
20133 rtx r0
= gen_rtx_REG (Pmode
, 0);
20134 gcc_assert (info
->first_gp_reg_save
> 11);
20136 emit_move_insn (r0
, gen_rtx_REG (Pmode
, 11));
20139 spe_save_area_ptr
= gen_rtx_REG (Pmode
, 11);
20140 insn
= emit_insn (gen_addsi3 (spe_save_area_ptr
,
20142 GEN_INT (offset
)));
20143 /* We need to make sure the move to r11 gets noted for
20144 properly outputting unwind information. */
20145 if (!saving_GPRs_inline
)
20146 rs6000_frame_related (insn
, frame_reg_rtx
, offset
,
20147 NULL_RTX
, NULL_RTX
);
20151 if (saving_GPRs_inline
)
20153 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20154 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
20156 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20157 rtx offset
, addr
, mem
;
20159 /* We're doing all this to ensure that the offset fits into
20160 the immediate offset of 'evstdd'. */
20161 gcc_assert (SPE_CONST_OFFSET_OK (reg_size
* i
+ spe_offset
));
20163 offset
= GEN_INT (reg_size
* i
+ spe_offset
);
20164 addr
= gen_rtx_PLUS (Pmode
, spe_save_area_ptr
, offset
);
20165 mem
= gen_rtx_MEM (V2SImode
, addr
);
20167 insn
= emit_move_insn (mem
, reg
);
20169 rs6000_frame_related (insn
, spe_save_area_ptr
,
20170 info
->spe_gp_save_offset
20171 + sp_offset
+ reg_size
* i
,
20172 offset
, const0_rtx
);
20179 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
20181 /*savep=*/true, /*gpr=*/true,
20183 insn
= emit_insn (par
);
20184 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20185 NULL_RTX
, NULL_RTX
);
20189 /* Move the static chain pointer back. */
20190 if (using_static_chain_p
&& !spe_regs_addressable_via_sp
)
20191 emit_move_insn (gen_rtx_REG (Pmode
, 11), gen_rtx_REG (Pmode
, 0));
20193 else if (!WORLD_SAVE_P (info
) && !saving_GPRs_inline
)
20197 /* Need to adjust r11 (r12) if we saved any FPRs. */
20198 if (info
->first_fp_reg_save
!= 64)
20200 rtx dest_reg
= gen_rtx_REG (reg_mode
, DEFAULT_ABI
== ABI_AIX
20202 rtx offset
= GEN_INT (sp_offset
20203 + (-8 * (64-info
->first_fp_reg_save
)));
20204 emit_insn (gen_add3_insn (dest_reg
, frame_reg_rtx
, offset
));
20207 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
20208 info
->gp_save_offset
+ sp_offset
,
20210 /*savep=*/true, /*gpr=*/true,
20212 & SAVRES_NOINLINE_GPRS_SAVES_LR
)
20214 insn
= emit_insn (par
);
20215 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20216 NULL_RTX
, NULL_RTX
);
20218 else if (!WORLD_SAVE_P (info
) && using_store_multiple
)
20222 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
20223 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20225 rtx addr
, reg
, mem
;
20226 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20227 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20228 GEN_INT (info
->gp_save_offset
20231 mem
= gen_frame_mem (reg_mode
, addr
);
20233 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
20235 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20236 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20237 NULL_RTX
, NULL_RTX
);
20239 else if (!WORLD_SAVE_P (info
))
20242 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20243 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
20245 rtx addr
, reg
, mem
;
20246 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20248 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20249 GEN_INT (info
->gp_save_offset
20252 mem
= gen_frame_mem (reg_mode
, addr
);
20254 insn
= emit_move_insn (mem
, reg
);
20255 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20256 NULL_RTX
, NULL_RTX
);
20260 /* ??? There's no need to emit actual instructions here, but it's the
20261 easiest way to get the frame unwind information emitted. */
20262 if (crtl
->calls_eh_return
)
20264 unsigned int i
, regno
;
20268 regno
= EH_RETURN_DATA_REGNO (i
);
20269 if (regno
== INVALID_REGNUM
)
20272 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
20273 info
->ehrd_offset
+ sp_offset
20274 + reg_size
* (int) i
,
20279 /* In AIX ABI we need to make sure r2 is really saved. */
20280 if (TARGET_AIX
&& crtl
->calls_eh_return
)
20282 rtx tmp_reg
, tmp_reg_si
, hi
, lo
, compare_result
, toc_save_done
, jump
;
20283 long toc_restore_insn
;
20285 gcc_assert (frame_reg_rtx
== frame_ptr_rtx
20286 || frame_reg_rtx
== sp_reg_rtx
);
20287 tmp_reg
= gen_rtx_REG (Pmode
, 11);
20288 tmp_reg_si
= gen_rtx_REG (SImode
, 11);
20289 if (using_static_chain_p
)
20290 emit_move_insn (gen_rtx_REG (Pmode
, 0), tmp_reg
);
20291 gcc_assert (saving_GPRs_inline
&& saving_FPRs_inline
);
20292 emit_move_insn (tmp_reg
, gen_rtx_REG (Pmode
, LR_REGNO
));
20293 /* Peek at instruction to which this function returns. If it's
20294 restoring r2, then we know we've already saved r2. We can't
20295 unconditionally save r2 because the value we have will already
20296 be updated if we arrived at this function via a plt call or
20297 toc adjusting stub. */
20298 emit_move_insn (tmp_reg_si
, gen_rtx_MEM (SImode
, tmp_reg
));
20299 toc_restore_insn
= TARGET_32BIT
? 0x80410014 : 0xE8410028;
20300 hi
= gen_int_mode (toc_restore_insn
& ~0xffff, SImode
);
20301 emit_insn (gen_xorsi3 (tmp_reg_si
, tmp_reg_si
, hi
));
20302 compare_result
= gen_rtx_REG (CCUNSmode
, CR0_REGNO
);
20303 validate_condition_mode (EQ
, CCUNSmode
);
20304 lo
= gen_int_mode (toc_restore_insn
& 0xffff, SImode
);
20305 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
20306 gen_rtx_COMPARE (CCUNSmode
, tmp_reg_si
, lo
)));
20307 toc_save_done
= gen_label_rtx ();
20308 jump
= gen_rtx_IF_THEN_ELSE (VOIDmode
,
20309 gen_rtx_EQ (VOIDmode
, compare_result
,
20311 gen_rtx_LABEL_REF (VOIDmode
, toc_save_done
),
20313 jump
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, jump
));
20314 JUMP_LABEL (jump
) = toc_save_done
;
20315 LABEL_NUSES (toc_save_done
) += 1;
20317 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, 2,
20318 sp_offset
+ 5 * reg_size
, info
->total_size
);
20319 emit_label (toc_save_done
);
20320 if (using_static_chain_p
)
20321 emit_move_insn (tmp_reg
, gen_rtx_REG (Pmode
, 0));
20324 /* Save CR if we use any that must be preserved. */
20325 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
20327 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20328 GEN_INT (info
->cr_save_offset
+ sp_offset
));
20329 rtx mem
= gen_frame_mem (SImode
, addr
);
20330 /* See the large comment above about why CR2_REGNO is used. */
20331 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
20333 /* If r12 was used to hold the original sp, copy cr into r0 now
20335 if (REGNO (frame_reg_rtx
) == 12)
20339 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
20340 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
20341 RTX_FRAME_RELATED_P (insn
) = 1;
20342 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
20343 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
20345 insn
= emit_move_insn (mem
, cr_save_rtx
);
20347 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20348 NULL_RTX
, NULL_RTX
);
20351 /* Update stack and set back pointer unless this is V.4,
20352 for which it was done previously. */
20353 if (!WORLD_SAVE_P (info
) && info
->push_p
20354 && !(DEFAULT_ABI
== ABI_V4
|| crtl
->calls_eh_return
))
20356 rtx copy_reg
= NULL
;
20358 if (info
->total_size
< 32767)
20359 sp_offset
= info
->total_size
;
20360 else if (info
->altivec_size
!= 0
20361 || info
->vrsave_mask
!= 0)
20363 copy_reg
= frame_ptr_rtx
;
20364 frame_reg_rtx
= copy_reg
;
20367 sp_offset
= info
->total_size
;
20368 rs6000_emit_allocate_stack (info
->total_size
, copy_reg
);
20369 if (frame_reg_rtx
!= sp_reg_rtx
)
20370 rs6000_emit_stack_tie ();
20373 /* Set frame pointer, if needed. */
20374 if (frame_pointer_needed
)
20376 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
20378 RTX_FRAME_RELATED_P (insn
) = 1;
20381 /* Save AltiVec registers if needed. Save here because the red zone does
20382 not include AltiVec registers. */
20383 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
20387 /* There should be a non inline version of this, for when we
20388 are saving lots of vector registers. */
20389 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
20390 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
20392 rtx areg
, savereg
, mem
;
20395 offset
= info
->altivec_save_offset
+ sp_offset
20396 + 16 * (i
- info
->first_altivec_reg_save
);
20398 savereg
= gen_rtx_REG (V4SImode
, i
);
20400 areg
= gen_rtx_REG (Pmode
, 0);
20401 emit_move_insn (areg
, GEN_INT (offset
));
20403 /* AltiVec addressing mode is [reg+reg]. */
20404 mem
= gen_frame_mem (V4SImode
,
20405 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
20407 insn
= emit_move_insn (mem
, savereg
);
20409 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
20410 areg
, GEN_INT (offset
));
20414 /* VRSAVE is a bit vector representing which AltiVec registers
20415 are used. The OS uses this to determine which vector
20416 registers to save on a context switch. We need to save
20417 VRSAVE on the stack frame, add whatever AltiVec registers we
20418 used in this function, and do the corresponding magic in the
20421 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
20422 && info
->vrsave_mask
!= 0)
20424 rtx reg
, mem
, vrsave
;
20427 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20428 as frame_reg_rtx and r11 as the static chain pointer for
20429 nested functions. */
20430 reg
= gen_rtx_REG (SImode
, 0);
20431 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
20433 emit_insn (gen_get_vrsave_internal (reg
));
20435 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
20437 if (!WORLD_SAVE_P (info
))
20440 offset
= info
->vrsave_save_offset
+ sp_offset
;
20441 mem
= gen_frame_mem (SImode
,
20442 gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20443 GEN_INT (offset
)));
20444 insn
= emit_move_insn (mem
, reg
);
20447 /* Include the registers in the mask. */
20448 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
20450 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
20453 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20454 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
20455 || (DEFAULT_ABI
== ABI_V4
20456 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
20457 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
)))
20459 /* If emit_load_toc_table will use the link register, we need to save
20460 it. We use R12 for this purpose because emit_load_toc_table
20461 can use register 0. This allows us to use a plain 'blr' to return
20462 from the procedure more often. */
20463 int save_LR_around_toc_setup
= (TARGET_ELF
20464 && DEFAULT_ABI
!= ABI_AIX
20466 && ! info
->lr_save_p
20467 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
20468 if (save_LR_around_toc_setup
)
20470 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
20472 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
20473 RTX_FRAME_RELATED_P (insn
) = 1;
20475 rs6000_emit_load_toc_table (TRUE
);
20477 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
20478 RTX_FRAME_RELATED_P (insn
) = 1;
20481 rs6000_emit_load_toc_table (TRUE
);
20485 if (DEFAULT_ABI
== ABI_DARWIN
20486 && flag_pic
&& crtl
->uses_pic_offset_table
)
20488 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
20489 rtx src
= gen_rtx_SYMBOL_REF (Pmode
, MACHOPIC_FUNCTION_BASE_NAME
);
20491 /* Save and restore LR locally around this call (in R0). */
20492 if (!info
->lr_save_p
)
20493 emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
);
20495 emit_insn (gen_load_macho_picbase (src
));
20497 emit_move_insn (gen_rtx_REG (Pmode
,
20498 RS6000_PIC_OFFSET_TABLE_REGNUM
),
20501 if (!info
->lr_save_p
)
20502 emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0));
20507 /* Write function prologue. */
20510 rs6000_output_function_prologue (FILE *file
,
20511 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
20513 rs6000_stack_t
*info
= rs6000_stack_info ();
20515 if (TARGET_DEBUG_STACK
)
20516 debug_stack_info (info
);
20518 /* Write .extern for any function we will call to save and restore
20520 if (info
->first_fp_reg_save
< 64
20521 && !FP_SAVE_INLINE (info
->first_fp_reg_save
))
20524 int regno
= info
->first_fp_reg_save
- 32;
20526 name
= rs6000_savres_routine_name (info
, regno
, /*savep=*/true,
20527 /*gpr=*/false, /*lr=*/false);
20528 fprintf (file
, "\t.extern %s\n", name
);
20530 name
= rs6000_savres_routine_name (info
, regno
, /*savep=*/false,
20531 /*gpr=*/false, /*lr=*/true);
20532 fprintf (file
, "\t.extern %s\n", name
);
20535 /* Write .extern for AIX common mode routines, if needed. */
20536 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
20538 fputs ("\t.extern __mulh\n", file
);
20539 fputs ("\t.extern __mull\n", file
);
20540 fputs ("\t.extern __divss\n", file
);
20541 fputs ("\t.extern __divus\n", file
);
20542 fputs ("\t.extern __quoss\n", file
);
20543 fputs ("\t.extern __quous\n", file
);
20544 common_mode_defined
= 1;
20547 if (! HAVE_prologue
)
20553 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20554 the "toplevel" insn chain. */
20555 emit_note (NOTE_INSN_DELETED
);
20556 rs6000_emit_prologue ();
20557 emit_note (NOTE_INSN_DELETED
);
20559 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20563 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
20565 INSN_ADDRESSES_NEW (insn
, addr
);
20570 prologue
= get_insns ();
20573 if (TARGET_DEBUG_STACK
)
20574 debug_rtx_list (prologue
, 100);
20576 emit_insn_before_noloc (prologue
, BB_HEAD (ENTRY_BLOCK_PTR
->next_bb
),
20580 rs6000_pic_labelno
++;
20583 /* Non-zero if vmx regs are restored before the frame pop, zero if
20584 we restore after the pop when possible. */
20585 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20587 /* Reload CR from REG. */
20590 rs6000_restore_saved_cr (rtx reg
, int using_mfcr_multiple
)
20595 if (using_mfcr_multiple
)
20597 for (i
= 0; i
< 8; i
++)
20598 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
20600 gcc_assert (count
);
20603 if (using_mfcr_multiple
&& count
> 1)
20608 p
= rtvec_alloc (count
);
20611 for (i
= 0; i
< 8; i
++)
20612 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
20614 rtvec r
= rtvec_alloc (2);
20615 RTVEC_ELT (r
, 0) = reg
;
20616 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
20617 RTVEC_ELT (p
, ndx
) =
20618 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
20619 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
20622 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20623 gcc_assert (ndx
== count
);
20626 for (i
= 0; i
< 8; i
++)
20627 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
20629 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
20635 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20636 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20637 below stack pointer not cloberred by signals. */
20640 offset_below_red_zone_p (HOST_WIDE_INT offset
)
20642 return offset
< (DEFAULT_ABI
== ABI_V4
20644 : TARGET_32BIT
? -220 : -288);
20647 /* Emit function epilogue as insns. */
20650 rs6000_emit_epilogue (int sibcall
)
20652 rs6000_stack_t
*info
;
20653 int restoring_GPRs_inline
;
20654 int restoring_FPRs_inline
;
20655 int using_load_multiple
;
20656 int using_mtcr_multiple
;
20657 int use_backchain_to_restore_sp
;
20661 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
20662 rtx frame_reg_rtx
= sp_reg_rtx
;
20663 rtx cfa_restores
= NULL_RTX
;
20665 rtx cr_save_reg
= NULL_RTX
;
20666 enum machine_mode reg_mode
= Pmode
;
20667 int reg_size
= TARGET_32BIT
? 4 : 8;
20670 info
= rs6000_stack_info ();
20672 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
20674 reg_mode
= V2SImode
;
20678 strategy
= rs6000_savres_strategy (info
, /*savep=*/false,
20679 /*static_chain_p=*/0, sibcall
);
20680 using_load_multiple
= strategy
& SAVRES_MULTIPLE
;
20681 restoring_FPRs_inline
= strategy
& SAVRES_INLINE_FPRS
;
20682 restoring_GPRs_inline
= strategy
& SAVRES_INLINE_GPRS
;
20683 using_mtcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
20684 || rs6000_cpu
== PROCESSOR_PPC603
20685 || rs6000_cpu
== PROCESSOR_PPC750
20687 /* Restore via the backchain when we have a large frame, since this
20688 is more efficient than an addis, addi pair. The second condition
20689 here will not trigger at the moment; We don't actually need a
20690 frame pointer for alloca, but the generic parts of the compiler
20691 give us one anyway. */
20692 use_backchain_to_restore_sp
= (info
->total_size
> 32767
20693 || info
->total_size
20694 + (info
->lr_save_p
? info
->lr_save_offset
: 0)
20696 || (cfun
->calls_alloca
20697 && !frame_pointer_needed
));
20698 restore_lr
= (info
->lr_save_p
20699 && (restoring_FPRs_inline
20700 || (strategy
& SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR
))
20701 && (restoring_GPRs_inline
20702 || info
->first_fp_reg_save
< 64));
20704 if (WORLD_SAVE_P (info
))
20708 const char *alloc_rname
;
20711 /* eh_rest_world_r10 will return to the location saved in the LR
20712 stack slot (which is not likely to be our caller.)
20713 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20714 rest_world is similar, except any R10 parameter is ignored.
20715 The exception-handling stuff that was here in 2.95 is no
20716 longer necessary. */
20720 + 32 - info
->first_gp_reg_save
20721 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
20722 + 63 + 1 - info
->first_fp_reg_save
);
20724 strcpy (rname
, ((crtl
->calls_eh_return
) ?
20725 "*eh_rest_world_r10" : "*rest_world"));
20726 alloc_rname
= ggc_strdup (rname
);
20729 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
20730 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
20731 gen_rtx_REG (Pmode
,
20734 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
20735 /* The instruction pattern requires a clobber here;
20736 it is shared with the restVEC helper. */
20738 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
20741 /* CR register traditionally saved as CR2. */
20742 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
20743 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20744 GEN_INT (info
->cr_save_offset
));
20745 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20747 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
20750 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
20752 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
20753 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20754 GEN_INT (info
->gp_save_offset
20756 rtx mem
= gen_frame_mem (reg_mode
, addr
);
20758 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
20760 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
20762 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
20763 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20764 GEN_INT (info
->altivec_save_offset
20766 rtx mem
= gen_frame_mem (V4SImode
, addr
);
20768 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
20770 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
20772 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20773 ? DFmode
: SFmode
),
20774 info
->first_fp_reg_save
+ i
);
20775 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20776 GEN_INT (info
->fp_save_offset
20778 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
20779 ? DFmode
: SFmode
), addr
);
20781 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
20784 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
20786 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
20788 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
20790 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
20792 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
20793 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
20798 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20800 sp_offset
= info
->total_size
;
20802 /* Restore AltiVec registers if we must do so before adjusting the
20804 if (TARGET_ALTIVEC_ABI
20805 && info
->altivec_size
!= 0
20806 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20807 || (DEFAULT_ABI
!= ABI_V4
20808 && offset_below_red_zone_p (info
->altivec_save_offset
))))
20812 if (use_backchain_to_restore_sp
)
20814 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
20815 emit_move_insn (frame_reg_rtx
,
20816 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
20819 else if (frame_pointer_needed
)
20820 frame_reg_rtx
= hard_frame_pointer_rtx
;
20822 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
20823 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
20825 rtx addr
, areg
, mem
, reg
;
20827 areg
= gen_rtx_REG (Pmode
, 0);
20829 (areg
, GEN_INT (info
->altivec_save_offset
20831 + 16 * (i
- info
->first_altivec_reg_save
)));
20833 /* AltiVec addressing mode is [reg+reg]. */
20834 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
20835 mem
= gen_frame_mem (V4SImode
, addr
);
20837 reg
= gen_rtx_REG (V4SImode
, i
);
20838 emit_move_insn (reg
, mem
);
20839 if (offset_below_red_zone_p (info
->altivec_save_offset
20840 + (i
- info
->first_altivec_reg_save
)
20842 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
20847 /* Restore VRSAVE if we must do so before adjusting the stack. */
20849 && TARGET_ALTIVEC_VRSAVE
20850 && info
->vrsave_mask
!= 0
20851 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20852 || (DEFAULT_ABI
!= ABI_V4
20853 && offset_below_red_zone_p (info
->vrsave_save_offset
))))
20855 rtx addr
, mem
, reg
;
20857 if (frame_reg_rtx
== sp_reg_rtx
)
20859 if (use_backchain_to_restore_sp
)
20861 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
20862 emit_move_insn (frame_reg_rtx
,
20863 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
20866 else if (frame_pointer_needed
)
20867 frame_reg_rtx
= hard_frame_pointer_rtx
;
20870 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20871 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
20872 mem
= gen_frame_mem (SImode
, addr
);
20873 reg
= gen_rtx_REG (SImode
, 12);
20874 emit_move_insn (reg
, mem
);
20876 emit_insn (generate_set_vrsave (reg
, info
, 1));
20880 /* If we have a large stack frame, restore the old stack pointer
20881 using the backchain. */
20882 if (use_backchain_to_restore_sp
)
20884 if (frame_reg_rtx
== sp_reg_rtx
)
20886 /* Under V.4, don't reset the stack pointer until after we're done
20887 loading the saved registers. */
20888 if (DEFAULT_ABI
== ABI_V4
)
20889 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
20891 insn
= emit_move_insn (frame_reg_rtx
,
20892 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
20895 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20896 && DEFAULT_ABI
== ABI_V4
)
20897 /* frame_reg_rtx has been set up by the altivec restore. */
20901 insn
= emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
20902 frame_reg_rtx
= sp_reg_rtx
;
20905 /* If we have a frame pointer, we can restore the old stack pointer
20907 else if (frame_pointer_needed
)
20909 frame_reg_rtx
= sp_reg_rtx
;
20910 if (DEFAULT_ABI
== ABI_V4
)
20911 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
20912 /* Prevent reordering memory accesses against stack pointer restore. */
20913 else if (cfun
->calls_alloca
20914 || offset_below_red_zone_p (-info
->total_size
))
20916 rtx mem1
= gen_rtx_MEM (BLKmode
, hard_frame_pointer_rtx
);
20917 rtx mem2
= gen_rtx_MEM (BLKmode
, sp_reg_rtx
);
20918 MEM_NOTRAP_P (mem1
) = 1;
20919 MEM_NOTRAP_P (mem2
) = 1;
20920 emit_insn (gen_frame_tie (mem1
, mem2
));
20923 insn
= emit_insn (gen_add3_insn (frame_reg_rtx
, hard_frame_pointer_rtx
,
20924 GEN_INT (info
->total_size
)));
20927 else if (info
->push_p
20928 && DEFAULT_ABI
!= ABI_V4
20929 && !crtl
->calls_eh_return
)
20931 /* Prevent reordering memory accesses against stack pointer restore. */
20932 if (cfun
->calls_alloca
20933 || offset_below_red_zone_p (-info
->total_size
))
20935 rtx mem
= gen_rtx_MEM (BLKmode
, sp_reg_rtx
);
20936 MEM_NOTRAP_P (mem
) = 1;
20937 emit_insn (gen_stack_tie (mem
));
20939 insn
= emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
,
20940 GEN_INT (info
->total_size
)));
20943 if (insn
&& frame_reg_rtx
== sp_reg_rtx
)
20947 REG_NOTES (insn
) = cfa_restores
;
20948 cfa_restores
= NULL_RTX
;
20950 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
20951 RTX_FRAME_RELATED_P (insn
) = 1;
20954 /* Restore AltiVec registers if we have not done so already. */
20955 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20956 && TARGET_ALTIVEC_ABI
20957 && info
->altivec_size
!= 0
20958 && (DEFAULT_ABI
== ABI_V4
20959 || !offset_below_red_zone_p (info
->altivec_save_offset
)))
20963 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
20964 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
20966 rtx addr
, areg
, mem
, reg
;
20968 areg
= gen_rtx_REG (Pmode
, 0);
20970 (areg
, GEN_INT (info
->altivec_save_offset
20972 + 16 * (i
- info
->first_altivec_reg_save
)));
20974 /* AltiVec addressing mode is [reg+reg]. */
20975 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
20976 mem
= gen_frame_mem (V4SImode
, addr
);
20978 reg
= gen_rtx_REG (V4SImode
, i
);
20979 emit_move_insn (reg
, mem
);
20980 if (DEFAULT_ABI
== ABI_V4
)
20981 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
20986 /* Restore VRSAVE if we have not done so already. */
20987 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20989 && TARGET_ALTIVEC_VRSAVE
20990 && info
->vrsave_mask
!= 0
20991 && (DEFAULT_ABI
== ABI_V4
20992 || !offset_below_red_zone_p (info
->vrsave_save_offset
)))
20994 rtx addr
, mem
, reg
;
20996 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
20997 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
20998 mem
= gen_frame_mem (SImode
, addr
);
20999 reg
= gen_rtx_REG (SImode
, 12);
21000 emit_move_insn (reg
, mem
);
21002 emit_insn (generate_set_vrsave (reg
, info
, 1));
21005 /* Get the old lr if we saved it. If we are restoring registers
21006 out-of-line, then the out-of-line routines can do this for us. */
21007 if (restore_lr
&& restoring_GPRs_inline
)
21009 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
21010 info
->lr_save_offset
+ sp_offset
);
21012 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
21015 /* Get the old cr if we saved it. */
21016 if (info
->cr_save_p
)
21018 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21019 GEN_INT (info
->cr_save_offset
+ sp_offset
));
21020 rtx mem
= gen_frame_mem (SImode
, addr
);
21022 cr_save_reg
= gen_rtx_REG (SImode
,
21023 DEFAULT_ABI
== ABI_AIX
21024 && !restoring_GPRs_inline
21025 && info
->first_fp_reg_save
< 64
21027 emit_move_insn (cr_save_reg
, mem
);
21030 /* Set LR here to try to overlap restores below. LR is always saved
21031 above incoming stack, so it never needs REG_CFA_RESTORE. */
21032 if (restore_lr
&& restoring_GPRs_inline
)
21033 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
21034 gen_rtx_REG (Pmode
, 0));
21036 /* Load exception handler data registers, if needed. */
21037 if (crtl
->calls_eh_return
)
21039 unsigned int i
, regno
;
21043 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21044 GEN_INT (sp_offset
+ 5 * reg_size
));
21045 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21047 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
21054 regno
= EH_RETURN_DATA_REGNO (i
);
21055 if (regno
== INVALID_REGNUM
)
21058 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
21059 info
->ehrd_offset
+ sp_offset
21060 + reg_size
* (int) i
);
21062 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
21066 /* Restore GPRs. This is done as a PARALLEL if we are using
21067 the load-multiple instructions. */
21069 && info
->spe_64bit_regs_used
!= 0
21070 && info
->first_gp_reg_save
!= 32)
21072 /* Determine whether we can address all of the registers that need
21073 to be saved with an offset from the stack pointer that fits in
21074 the small const field for SPE memory instructions. */
21075 int spe_regs_addressable_via_sp
21076 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
21077 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
21078 && restoring_GPRs_inline
);
21081 if (spe_regs_addressable_via_sp
)
21082 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
21085 rtx old_frame_reg_rtx
= frame_reg_rtx
;
21086 /* Make r11 point to the start of the SPE save area. We worried about
21087 not clobbering it when we were saving registers in the prologue.
21088 There's no need to worry here because the static chain is passed
21089 anew to every function. */
21090 int ool_adjust
= (restoring_GPRs_inline
21092 : (info
->first_gp_reg_save
21093 - (FIRST_SAVRES_REGISTER
+1))*8);
21095 if (frame_reg_rtx
== sp_reg_rtx
)
21096 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
21097 emit_insn (gen_addsi3 (frame_reg_rtx
, old_frame_reg_rtx
,
21098 GEN_INT (info
->spe_gp_save_offset
21101 /* Keep the invariant that frame_reg_rtx + sp_offset points
21102 at the top of the stack frame. */
21103 sp_offset
= -info
->spe_gp_save_offset
;
21108 if (restoring_GPRs_inline
)
21110 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21111 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
21113 rtx offset
, addr
, mem
, reg
;
21115 /* We're doing all this to ensure that the immediate offset
21116 fits into the immediate field of 'evldd'. */
21117 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset
+ reg_size
* i
));
21119 offset
= GEN_INT (spe_offset
+ reg_size
* i
);
21120 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, offset
);
21121 mem
= gen_rtx_MEM (V2SImode
, addr
);
21122 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21124 insn
= emit_move_insn (reg
, mem
);
21125 if (DEFAULT_ABI
== ABI_V4
)
21127 if (frame_pointer_needed
21128 && info
->first_gp_reg_save
+ i
21129 == HARD_FRAME_POINTER_REGNUM
)
21131 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21132 plus_constant (frame_reg_rtx
,
21134 RTX_FRAME_RELATED_P (insn
) = 1;
21137 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21146 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
21148 /*savep=*/false, /*gpr=*/true,
21150 emit_jump_insn (par
);
21151 /* We don't want anybody else emitting things after we jumped
21156 else if (!restoring_GPRs_inline
)
21158 /* We are jumping to an out-of-line function. */
21159 bool can_use_exit
= info
->first_fp_reg_save
== 64;
21162 /* Emit stack reset code if we need it. */
21164 rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
21165 sp_offset
, can_use_exit
);
21168 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode
, DEFAULT_ABI
== ABI_AIX
21171 GEN_INT (sp_offset
- info
->fp_size
)));
21172 if (REGNO (frame_reg_rtx
) == 11)
21173 sp_offset
+= info
->fp_size
;
21176 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
21177 info
->gp_save_offset
, reg_mode
,
21178 /*savep=*/false, /*gpr=*/true,
21179 /*lr=*/can_use_exit
);
21183 if (info
->cr_save_p
)
21185 rs6000_restore_saved_cr (cr_save_reg
, using_mtcr_multiple
);
21186 if (DEFAULT_ABI
== ABI_V4
)
21188 = alloc_reg_note (REG_CFA_RESTORE
,
21189 gen_rtx_REG (SImode
, CR2_REGNO
),
21193 emit_jump_insn (par
);
21195 /* We don't want anybody else emitting things after we jumped
21200 insn
= emit_insn (par
);
21201 if (DEFAULT_ABI
== ABI_V4
)
21203 if (frame_pointer_needed
)
21205 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21206 plus_constant (frame_reg_rtx
, sp_offset
));
21207 RTX_FRAME_RELATED_P (insn
) = 1;
21210 for (i
= info
->first_gp_reg_save
; i
< 32; i
++)
21212 = alloc_reg_note (REG_CFA_RESTORE
,
21213 gen_rtx_REG (reg_mode
, i
), cfa_restores
);
21216 else if (using_load_multiple
)
21219 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
21220 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21222 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21223 GEN_INT (info
->gp_save_offset
21226 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21227 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21229 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, reg
, mem
);
21230 if (DEFAULT_ABI
== ABI_V4
)
21231 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21234 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21235 if (DEFAULT_ABI
== ABI_V4
&& frame_pointer_needed
)
21237 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21238 plus_constant (frame_reg_rtx
, sp_offset
));
21239 RTX_FRAME_RELATED_P (insn
) = 1;
21244 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
21245 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
21247 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21248 GEN_INT (info
->gp_save_offset
21251 rtx mem
= gen_frame_mem (reg_mode
, addr
);
21252 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
21254 insn
= emit_move_insn (reg
, mem
);
21255 if (DEFAULT_ABI
== ABI_V4
)
21257 if (frame_pointer_needed
21258 && info
->first_gp_reg_save
+ i
21259 == HARD_FRAME_POINTER_REGNUM
)
21261 add_reg_note (insn
, REG_CFA_DEF_CFA
,
21262 plus_constant (frame_reg_rtx
, sp_offset
));
21263 RTX_FRAME_RELATED_P (insn
) = 1;
21266 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21272 if (restore_lr
&& !restoring_GPRs_inline
)
21274 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
21275 info
->lr_save_offset
+ sp_offset
);
21277 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
21278 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
21279 gen_rtx_REG (Pmode
, 0));
21282 /* Restore fpr's if we need to do it without calling a function. */
21283 if (restoring_FPRs_inline
)
21284 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
21285 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
21286 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
21288 rtx addr
, mem
, reg
;
21289 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
21290 GEN_INT (info
->fp_save_offset
21293 mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21294 ? DFmode
: SFmode
), addr
);
21295 reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
21296 ? DFmode
: SFmode
),
21297 info
->first_fp_reg_save
+ i
);
21299 emit_move_insn (reg
, mem
);
21300 if (DEFAULT_ABI
== ABI_V4
)
21301 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
21305 /* If we saved cr, restore it here. Just those that were used. */
21306 if (info
->cr_save_p
)
21308 rs6000_restore_saved_cr (cr_save_reg
, using_mtcr_multiple
);
21309 if (DEFAULT_ABI
== ABI_V4
)
21311 = alloc_reg_note (REG_CFA_RESTORE
, gen_rtx_REG (SImode
, CR2_REGNO
),
21315 /* If this is V.4, unwind the stack pointer after all of the loads
21317 insn
= rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
21318 sp_offset
, !restoring_FPRs_inline
);
21323 REG_NOTES (insn
) = cfa_restores
;
21324 cfa_restores
= NULL_RTX
;
21326 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
21327 RTX_FRAME_RELATED_P (insn
) = 1;
21330 if (crtl
->calls_eh_return
)
21332 rtx sa
= EH_RETURN_STACKADJ_RTX
;
21333 emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
, sa
));
21339 bool lr
= (strategy
& SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR
) == 0;
21340 if (! restoring_FPRs_inline
)
21341 p
= rtvec_alloc (4 + 64 - info
->first_fp_reg_save
);
21343 p
= rtvec_alloc (2);
21345 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
21346 RTVEC_ELT (p
, 1) = ((restoring_FPRs_inline
|| !lr
)
21347 ? gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 65))
21348 : gen_rtx_CLOBBER (VOIDmode
,
21349 gen_rtx_REG (Pmode
, 65)));
21351 /* If we have to restore more than two FP registers, branch to the
21352 restore function. It will return to our caller. */
21353 if (! restoring_FPRs_inline
)
21358 sym
= rs6000_savres_routine_sym (info
,
21362 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
, sym
);
21363 RTVEC_ELT (p
, 3) = gen_rtx_USE (VOIDmode
,
21364 gen_rtx_REG (Pmode
,
21365 DEFAULT_ABI
== ABI_AIX
21367 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
21370 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
21371 GEN_INT (info
->fp_save_offset
+ 8*i
));
21372 mem
= gen_frame_mem (DFmode
, addr
);
21374 RTVEC_ELT (p
, i
+4) =
21375 gen_rtx_SET (VOIDmode
,
21376 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
21381 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
21385 /* Write function epilogue. */
21388 rs6000_output_function_epilogue (FILE *file
,
21389 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
21391 if (! HAVE_epilogue
)
21393 rtx insn
= get_last_insn ();
21394 /* If the last insn was a BARRIER, we don't have to write anything except
21395 the trace table. */
21396 if (GET_CODE (insn
) == NOTE
)
21397 insn
= prev_nonnote_insn (insn
);
21398 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
21400 /* This is slightly ugly, but at least we don't have two
21401 copies of the epilogue-emitting code. */
21404 /* A NOTE_INSN_DELETED is supposed to be at the start
21405 and end of the "toplevel" insn chain. */
21406 emit_note (NOTE_INSN_DELETED
);
21407 rs6000_emit_epilogue (FALSE
);
21408 emit_note (NOTE_INSN_DELETED
);
21410 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21414 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
21416 INSN_ADDRESSES_NEW (insn
, addr
);
21421 if (TARGET_DEBUG_STACK
)
21422 debug_rtx_list (get_insns (), 100);
21423 final (get_insns (), file
, FALSE
);
21429 macho_branch_islands ();
21430 /* Mach-O doesn't support labels at the end of objects, so if
21431 it looks like we might want one, insert a NOP. */
21433 rtx insn
= get_last_insn ();
21436 && NOTE_KIND (insn
) != NOTE_INSN_DELETED_LABEL
)
21437 insn
= PREV_INSN (insn
);
21441 && NOTE_KIND (insn
) == NOTE_INSN_DELETED_LABEL
)))
21442 fputs ("\tnop\n", file
);
21446 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21449 We don't output a traceback table if -finhibit-size-directive was
21450 used. The documentation for -finhibit-size-directive reads
21451 ``don't output a @code{.size} assembler directive, or anything
21452 else that would cause trouble if the function is split in the
21453 middle, and the two halves are placed at locations far apart in
21454 memory.'' The traceback table has this property, since it
21455 includes the offset from the start of the function to the
21456 traceback table itself.
21458 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21459 different traceback table. */
21460 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
21461 && rs6000_traceback
!= traceback_none
&& !cfun
->is_thunk
)
21463 const char *fname
= NULL
;
21464 const char *language_string
= lang_hooks
.name
;
21465 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
21467 int optional_tbtab
;
21468 rs6000_stack_t
*info
= rs6000_stack_info ();
21470 if (rs6000_traceback
== traceback_full
)
21471 optional_tbtab
= 1;
21472 else if (rs6000_traceback
== traceback_part
)
21473 optional_tbtab
= 0;
21475 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
21477 if (optional_tbtab
)
21479 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
21480 while (*fname
== '.') /* V.4 encodes . in the name */
21483 /* Need label immediately before tbtab, so we can compute
21484 its offset from the function start. */
21485 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
21486 ASM_OUTPUT_LABEL (file
, fname
);
21489 /* The .tbtab pseudo-op can only be used for the first eight
21490 expressions, since it can't handle the possibly variable
21491 length fields that follow. However, if you omit the optional
21492 fields, the assembler outputs zeros for all optional fields
21493 anyways, giving each variable length field is minimum length
21494 (as defined in sys/debug.h). Thus we can not use the .tbtab
21495 pseudo-op at all. */
21497 /* An all-zero word flags the start of the tbtab, for debuggers
21498 that have to find it by searching forward from the entry
21499 point or from the current pc. */
21500 fputs ("\t.long 0\n", file
);
21502 /* Tbtab format type. Use format type 0. */
21503 fputs ("\t.byte 0,", file
);
21505 /* Language type. Unfortunately, there does not seem to be any
21506 official way to discover the language being compiled, so we
21507 use language_string.
21508 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21509 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21510 a number, so for now use 9. LTO isn't assigned a number either,
21511 so for now use 0. */
21512 if (! strcmp (language_string
, "GNU C")
21513 || ! strcmp (language_string
, "GNU GIMPLE"))
21515 else if (! strcmp (language_string
, "GNU F77")
21516 || ! strcmp (language_string
, "GNU Fortran"))
21518 else if (! strcmp (language_string
, "GNU Pascal"))
21520 else if (! strcmp (language_string
, "GNU Ada"))
21522 else if (! strcmp (language_string
, "GNU C++")
21523 || ! strcmp (language_string
, "GNU Objective-C++"))
21525 else if (! strcmp (language_string
, "GNU Java"))
21527 else if (! strcmp (language_string
, "GNU Objective-C"))
21530 gcc_unreachable ();
21531 fprintf (file
, "%d,", i
);
21533 /* 8 single bit fields: global linkage (not set for C extern linkage,
21534 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21535 from start of procedure stored in tbtab, internal function, function
21536 has controlled storage, function has no toc, function uses fp,
21537 function logs/aborts fp operations. */
21538 /* Assume that fp operations are used if any fp reg must be saved. */
21539 fprintf (file
, "%d,",
21540 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
21542 /* 6 bitfields: function is interrupt handler, name present in
21543 proc table, function calls alloca, on condition directives
21544 (controls stack walks, 3 bits), saves condition reg, saves
21546 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21547 set up as a frame pointer, even when there is no alloca call. */
21548 fprintf (file
, "%d,",
21549 ((optional_tbtab
<< 6)
21550 | ((optional_tbtab
& frame_pointer_needed
) << 5)
21551 | (info
->cr_save_p
<< 1)
21552 | (info
->lr_save_p
)));
21554 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21556 fprintf (file
, "%d,",
21557 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
21559 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21560 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
21562 if (optional_tbtab
)
21564 /* Compute the parameter info from the function decl argument
21567 int next_parm_info_bit
= 31;
21569 for (decl
= DECL_ARGUMENTS (current_function_decl
);
21570 decl
; decl
= DECL_CHAIN (decl
))
21572 rtx parameter
= DECL_INCOMING_RTL (decl
);
21573 enum machine_mode mode
= GET_MODE (parameter
);
21575 if (GET_CODE (parameter
) == REG
)
21577 if (SCALAR_FLOAT_MODE_P (mode
))
21598 gcc_unreachable ();
21601 /* If only one bit will fit, don't or in this entry. */
21602 if (next_parm_info_bit
> 0)
21603 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
21604 next_parm_info_bit
-= 2;
21608 fixed_parms
+= ((GET_MODE_SIZE (mode
)
21609 + (UNITS_PER_WORD
- 1))
21611 next_parm_info_bit
-= 1;
21617 /* Number of fixed point parameters. */
21618 /* This is actually the number of words of fixed point parameters; thus
21619 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21620 fprintf (file
, "%d,", fixed_parms
);
21622 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21624 /* This is actually the number of fp registers that hold parameters;
21625 and thus the maximum value is 13. */
21626 /* Set parameters on stack bit if parameters are not in their original
21627 registers, regardless of whether they are on the stack? Xlc
21628 seems to set the bit when not optimizing. */
21629 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
21631 if (! optional_tbtab
)
21634 /* Optional fields follow. Some are variable length. */
21636 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21637 11 double float. */
21638 /* There is an entry for each parameter in a register, in the order that
21639 they occur in the parameter list. Any intervening arguments on the
21640 stack are ignored. If the list overflows a long (max possible length
21641 34 bits) then completely leave off all elements that don't fit. */
21642 /* Only emit this long if there was at least one parameter. */
21643 if (fixed_parms
|| float_parms
)
21644 fprintf (file
, "\t.long %d\n", parm_info
);
21646 /* Offset from start of code to tb table. */
21647 fputs ("\t.long ", file
);
21648 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
21649 RS6000_OUTPUT_BASENAME (file
, fname
);
21651 rs6000_output_function_entry (file
, fname
);
21654 /* Interrupt handler mask. */
21655 /* Omit this long, since we never set the interrupt handler bit
21658 /* Number of CTL (controlled storage) anchors. */
21659 /* Omit this long, since the has_ctl bit is never set above. */
21661 /* Displacement into stack of each CTL anchor. */
21662 /* Omit this list of longs, because there are no CTL anchors. */
21664 /* Length of function name. */
21667 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
21669 /* Function name. */
21670 assemble_string (fname
, strlen (fname
));
21672 /* Register for alloca automatic storage; this is always reg 31.
21673 Only emit this if the alloca bit was set above. */
21674 if (frame_pointer_needed
)
21675 fputs ("\t.byte 31\n", file
);
21677 fputs ("\t.align 2\n", file
);
21681 /* A C compound statement that outputs the assembler code for a thunk
21682 function, used to implement C++ virtual function calls with
21683 multiple inheritance. The thunk acts as a wrapper around a virtual
21684 function, adjusting the implicit object parameter before handing
21685 control off to the real function.
21687 First, emit code to add the integer DELTA to the location that
21688 contains the incoming first argument. Assume that this argument
21689 contains a pointer, and is the one used to pass the `this' pointer
21690 in C++. This is the incoming argument *before* the function
21691 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21692 values of all other incoming arguments.
21694 After the addition, emit code to jump to FUNCTION, which is a
21695 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21696 not touch the return address. Hence returning from FUNCTION will
21697 return to whoever called the current `thunk'.
21699 The effect must be as if FUNCTION had been called directly with the
21700 adjusted first argument. This macro is responsible for emitting
21701 all of the code for a thunk function; output_function_prologue()
21702 and output_function_epilogue() are not invoked.
21704 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21705 been extracted from it.) It might possibly be useful on some
21706 targets, but probably not.
21708 If you do not define this macro, the target-independent code in the
21709 C++ frontend will generate a less efficient heavyweight thunk that
21710 calls FUNCTION instead of jumping to it. The generic approach does
21711 not support varargs. */
21714 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
21715 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
21718 rtx this_rtx
, insn
, funexp
;
21720 reload_completed
= 1;
21721 epilogue_completed
= 1;
21723 /* Mark the end of the (empty) prologue. */
21724 emit_note (NOTE_INSN_PROLOGUE_END
);
21726 /* Find the "this" pointer. If the function returns a structure,
21727 the structure return pointer is in r3. */
21728 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
21729 this_rtx
= gen_rtx_REG (Pmode
, 4);
21731 this_rtx
= gen_rtx_REG (Pmode
, 3);
21733 /* Apply the constant offset, if required. */
21735 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, GEN_INT (delta
)));
21737 /* Apply the offset from the vtable, if required. */
21740 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
21741 rtx tmp
= gen_rtx_REG (Pmode
, 12);
21743 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this_rtx
));
21744 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
21746 emit_insn (gen_add3_insn (tmp
, tmp
, vcall_offset_rtx
));
21747 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
21751 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
21753 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
21755 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, tmp
));
21758 /* Generate a tail call to the target function. */
21759 if (!TREE_USED (function
))
21761 assemble_external (function
);
21762 TREE_USED (function
) = 1;
21764 funexp
= XEXP (DECL_RTL (function
), 0);
21765 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
21768 if (MACHOPIC_INDIRECT
)
21769 funexp
= machopic_indirect_call_target (funexp
);
21772 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21773 generate sibcall RTL explicitly. */
21774 insn
= emit_call_insn (
21775 gen_rtx_PARALLEL (VOIDmode
,
21777 gen_rtx_CALL (VOIDmode
,
21778 funexp
, const0_rtx
),
21779 gen_rtx_USE (VOIDmode
, const0_rtx
),
21780 gen_rtx_USE (VOIDmode
,
21781 gen_rtx_REG (SImode
,
21783 gen_rtx_RETURN (VOIDmode
))));
21784 SIBLING_CALL_P (insn
) = 1;
21787 /* Run just enough of rest_of_compilation to get the insns emitted.
21788 There's not really enough bulk here to make other passes such as
21789 instruction scheduling worth while. Note that use_thunk calls
21790 assemble_start_function and assemble_end_function. */
21791 insn
= get_insns ();
21792 insn_locators_alloc ();
21793 shorten_branches (insn
);
21794 final_start_function (insn
, file
, 1);
21795 final (insn
, file
, 1);
21796 final_end_function ();
21798 reload_completed
= 0;
21799 epilogue_completed
= 0;
21802 /* A quick summary of the various types of 'constant-pool tables'
21805 Target Flags Name One table per
21806 AIX (none) AIX TOC object file
21807 AIX -mfull-toc AIX TOC object file
21808 AIX -mminimal-toc AIX minimal TOC translation unit
21809 SVR4/EABI (none) SVR4 SDATA object file
21810 SVR4/EABI -fpic SVR4 pic object file
21811 SVR4/EABI -fPIC SVR4 PIC translation unit
21812 SVR4/EABI -mrelocatable EABI TOC function
21813 SVR4/EABI -maix AIX TOC object file
21814 SVR4/EABI -maix -mminimal-toc
21815 AIX minimal TOC translation unit
21817 Name Reg. Set by entries contains:
21818 made by addrs? fp? sum?
21820 AIX TOC 2 crt0 as Y option option
21821 AIX minimal TOC 30 prolog gcc Y Y option
21822 SVR4 SDATA 13 crt0 gcc N Y N
21823 SVR4 pic 30 prolog ld Y not yet N
21824 SVR4 PIC 30 prolog gcc Y option option
21825 EABI TOC 30 prolog gcc Y option option
21829 /* Hash functions for the hash table. */
21832 rs6000_hash_constant (rtx k
)
21834 enum rtx_code code
= GET_CODE (k
);
21835 enum machine_mode mode
= GET_MODE (k
);
21836 unsigned result
= (code
<< 3) ^ mode
;
21837 const char *format
;
21840 format
= GET_RTX_FORMAT (code
);
21841 flen
= strlen (format
);
21847 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
21850 if (mode
!= VOIDmode
)
21851 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
21863 for (; fidx
< flen
; fidx
++)
21864 switch (format
[fidx
])
21869 const char *str
= XSTR (k
, fidx
);
21870 len
= strlen (str
);
21871 result
= result
* 613 + len
;
21872 for (i
= 0; i
< len
; i
++)
21873 result
= result
* 613 + (unsigned) str
[i
];
21878 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
21882 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
21885 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
21886 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
21890 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
21891 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
21898 gcc_unreachable ();
21905 toc_hash_function (const void *hash_entry
)
21907 const struct toc_hash_struct
*thc
=
21908 (const struct toc_hash_struct
*) hash_entry
;
21909 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
21912 /* Compare H1 and H2 for equivalence. */
21915 toc_hash_eq (const void *h1
, const void *h2
)
21917 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
21918 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
21920 if (((const struct toc_hash_struct
*) h1
)->key_mode
21921 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
21924 return rtx_equal_p (r1
, r2
);
21927 /* These are the names given by the C++ front-end to vtables, and
21928 vtable-like objects. Ideally, this logic should not be here;
21929 instead, there should be some programmatic way of inquiring as
21930 to whether or not an object is a vtable. */
21932 #define VTABLE_NAME_P(NAME) \
21933 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21934 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21935 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21936 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21937 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21939 #ifdef NO_DOLLAR_IN_LABEL
21940 /* Return a GGC-allocated character string translating dollar signs in
21941 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21944 rs6000_xcoff_strip_dollar (const char *name
)
21949 p
= strchr (name
, '$');
21951 if (p
== 0 || p
== name
)
21954 len
= strlen (name
);
21955 strip
= (char *) alloca (len
+ 1);
21956 strcpy (strip
, name
);
21957 p
= strchr (strip
, '$');
21961 p
= strchr (p
+ 1, '$');
21964 return ggc_alloc_string (strip
, len
);
21969 rs6000_output_symbol_ref (FILE *file
, rtx x
)
21971 /* Currently C++ toc references to vtables can be emitted before it
21972 is decided whether the vtable is public or private. If this is
21973 the case, then the linker will eventually complain that there is
21974 a reference to an unknown section. Thus, for vtables only,
21975 we emit the TOC reference to reference the symbol and not the
21977 const char *name
= XSTR (x
, 0);
21979 if (VTABLE_NAME_P (name
))
21981 RS6000_OUTPUT_BASENAME (file
, name
);
21984 assemble_name (file
, name
);
21987 /* Output a TOC entry. We derive the entry name from what is being
21991 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
21994 const char *name
= buf
;
21996 HOST_WIDE_INT offset
= 0;
21998 gcc_assert (!TARGET_NO_TOC
);
22000 /* When the linker won't eliminate them, don't output duplicate
22001 TOC entries (this happens on AIX if there is any kind of TOC,
22002 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22004 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
22006 struct toc_hash_struct
*h
;
22009 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22010 time because GGC is not initialized at that point. */
22011 if (toc_hash_table
== NULL
)
22012 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
22013 toc_hash_eq
, NULL
);
22015 h
= ggc_alloc_toc_hash_struct ();
22017 h
->key_mode
= mode
;
22018 h
->labelno
= labelno
;
22020 found
= htab_find_slot (toc_hash_table
, h
, INSERT
);
22021 if (*found
== NULL
)
22023 else /* This is indeed a duplicate.
22024 Set this label equal to that label. */
22026 fputs ("\t.set ", file
);
22027 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
22028 fprintf (file
, "%d,", labelno
);
22029 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
22030 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
22036 /* If we're going to put a double constant in the TOC, make sure it's
22037 aligned properly when strict alignment is on. */
22038 if (GET_CODE (x
) == CONST_DOUBLE
22039 && STRICT_ALIGNMENT
22040 && GET_MODE_BITSIZE (mode
) >= 64
22041 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
22042 ASM_OUTPUT_ALIGN (file
, 3);
22045 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
22047 /* Handle FP constants specially. Note that if we have a minimal
22048 TOC, things we put here aren't actually in the TOC, so we can allow
22050 if (GET_CODE (x
) == CONST_DOUBLE
&&
22051 (GET_MODE (x
) == TFmode
|| GET_MODE (x
) == TDmode
))
22053 REAL_VALUE_TYPE rv
;
22056 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
22057 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22058 REAL_VALUE_TO_TARGET_DECIMAL128 (rv
, k
);
22060 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
22064 if (TARGET_MINIMAL_TOC
)
22065 fputs (DOUBLE_INT_ASM_OP
, file
);
22067 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22068 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22069 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22070 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
22071 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22072 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22077 if (TARGET_MINIMAL_TOC
)
22078 fputs ("\t.long ", file
);
22080 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22081 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22082 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22083 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22084 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
22085 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
22089 else if (GET_CODE (x
) == CONST_DOUBLE
&&
22090 (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DDmode
))
22092 REAL_VALUE_TYPE rv
;
22095 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
22097 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22098 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, k
);
22100 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
22104 if (TARGET_MINIMAL_TOC
)
22105 fputs (DOUBLE_INT_ASM_OP
, file
);
22107 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
22108 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22109 fprintf (file
, "0x%lx%08lx\n",
22110 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22115 if (TARGET_MINIMAL_TOC
)
22116 fputs ("\t.long ", file
);
22118 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
22119 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22120 fprintf (file
, "0x%lx,0x%lx\n",
22121 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
22125 else if (GET_CODE (x
) == CONST_DOUBLE
&&
22126 (GET_MODE (x
) == SFmode
|| GET_MODE (x
) == SDmode
))
22128 REAL_VALUE_TYPE rv
;
22131 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
22132 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
22133 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
22135 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
22139 if (TARGET_MINIMAL_TOC
)
22140 fputs (DOUBLE_INT_ASM_OP
, file
);
22142 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
22143 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
22148 if (TARGET_MINIMAL_TOC
)
22149 fputs ("\t.long ", file
);
22151 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
22152 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
22156 else if (GET_MODE (x
) == VOIDmode
22157 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
22159 unsigned HOST_WIDE_INT low
;
22160 HOST_WIDE_INT high
;
22162 if (GET_CODE (x
) == CONST_DOUBLE
)
22164 low
= CONST_DOUBLE_LOW (x
);
22165 high
= CONST_DOUBLE_HIGH (x
);
22168 #if HOST_BITS_PER_WIDE_INT == 32
22171 high
= (low
& 0x80000000) ? ~0 : 0;
22175 low
= INTVAL (x
) & 0xffffffff;
22176 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
22180 /* TOC entries are always Pmode-sized, but since this
22181 is a bigendian machine then if we're putting smaller
22182 integer constants in the TOC we have to pad them.
22183 (This is still a win over putting the constants in
22184 a separate constant pool, because then we'd have
22185 to have both a TOC entry _and_ the actual constant.)
22187 For a 32-bit target, CONST_INT values are loaded and shifted
22188 entirely within `low' and can be stored in one TOC entry. */
22190 /* It would be easy to make this work, but it doesn't now. */
22191 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
22193 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
22195 #if HOST_BITS_PER_WIDE_INT == 32
22196 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
22197 POINTER_SIZE
, &low
, &high
, 0);
22200 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
22201 high
= (HOST_WIDE_INT
) low
>> 32;
22208 if (TARGET_MINIMAL_TOC
)
22209 fputs (DOUBLE_INT_ASM_OP
, file
);
22211 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
22212 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22213 fprintf (file
, "0x%lx%08lx\n",
22214 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22219 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
22221 if (TARGET_MINIMAL_TOC
)
22222 fputs ("\t.long ", file
);
22224 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
22225 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22226 fprintf (file
, "0x%lx,0x%lx\n",
22227 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
22231 if (TARGET_MINIMAL_TOC
)
22232 fputs ("\t.long ", file
);
22234 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
22235 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
22241 if (GET_CODE (x
) == CONST
)
22243 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
22244 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
);
22246 base
= XEXP (XEXP (x
, 0), 0);
22247 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
22250 switch (GET_CODE (base
))
22253 name
= XSTR (base
, 0);
22257 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
22258 CODE_LABEL_NUMBER (XEXP (base
, 0)));
22262 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
22266 gcc_unreachable ();
22269 if (TARGET_MINIMAL_TOC
)
22270 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
22273 fputs ("\t.tc ", file
);
22274 RS6000_OUTPUT_BASENAME (file
, name
);
22277 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
22279 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
22281 fputs ("[TC],", file
);
22284 /* Currently C++ toc references to vtables can be emitted before it
22285 is decided whether the vtable is public or private. If this is
22286 the case, then the linker will eventually complain that there is
22287 a TOC reference to an unknown section. Thus, for vtables only,
22288 we emit the TOC reference to reference the symbol and not the
22290 if (VTABLE_NAME_P (name
))
22292 RS6000_OUTPUT_BASENAME (file
, name
);
22294 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
22295 else if (offset
> 0)
22296 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
22299 output_addr_const (file
, x
);
22303 /* Output an assembler pseudo-op to write an ASCII string of N characters
22304 starting at P to FILE.
22306 On the RS/6000, we have to do this using the .byte operation and
22307 write out special characters outside the quoted string.
22308 Also, the assembler is broken; very long strings are truncated,
22309 so we must artificially break them up early. */
22312 output_ascii (FILE *file
, const char *p
, int n
)
22315 int i
, count_string
;
22316 const char *for_string
= "\t.byte \"";
22317 const char *for_decimal
= "\t.byte ";
22318 const char *to_close
= NULL
;
22321 for (i
= 0; i
< n
; i
++)
22324 if (c
>= ' ' && c
< 0177)
22327 fputs (for_string
, file
);
22330 /* Write two quotes to get one. */
22338 for_decimal
= "\"\n\t.byte ";
22342 if (count_string
>= 512)
22344 fputs (to_close
, file
);
22346 for_string
= "\t.byte \"";
22347 for_decimal
= "\t.byte ";
22355 fputs (for_decimal
, file
);
22356 fprintf (file
, "%d", c
);
22358 for_string
= "\n\t.byte \"";
22359 for_decimal
= ", ";
22365 /* Now close the string if we have written one. Then end the line. */
22367 fputs (to_close
, file
);
22370 /* Generate a unique section name for FILENAME for a section type
22371 represented by SECTION_DESC. Output goes into BUF.
22373 SECTION_DESC can be any string, as long as it is different for each
22374 possible section type.
22376 We name the section in the same manner as xlc. The name begins with an
22377 underscore followed by the filename (after stripping any leading directory
22378 names) with the last period replaced by the string SECTION_DESC. If
22379 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22383 rs6000_gen_section_name (char **buf
, const char *filename
,
22384 const char *section_desc
)
22386 const char *q
, *after_last_slash
, *last_period
= 0;
22390 after_last_slash
= filename
;
22391 for (q
= filename
; *q
; q
++)
22394 after_last_slash
= q
+ 1;
22395 else if (*q
== '.')
22399 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
22400 *buf
= (char *) xmalloc (len
);
22405 for (q
= after_last_slash
; *q
; q
++)
22407 if (q
== last_period
)
22409 strcpy (p
, section_desc
);
22410 p
+= strlen (section_desc
);
22414 else if (ISALNUM (*q
))
22418 if (last_period
== 0)
22419 strcpy (p
, section_desc
);
22424 /* Emit profile function. */
22427 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
22429 /* Non-standard profiling for kernels, which just saves LR then calls
22430 _mcount without worrying about arg saves. The idea is to change
22431 the function prologue as little as possible as it isn't easy to
22432 account for arg save/restore code added just for _mcount. */
22433 if (TARGET_PROFILE_KERNEL
)
22436 if (DEFAULT_ABI
== ABI_AIX
)
22438 #ifndef NO_PROFILE_COUNTERS
22439 # define NO_PROFILE_COUNTERS 0
22441 if (NO_PROFILE_COUNTERS
)
22442 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
22443 LCT_NORMAL
, VOIDmode
, 0);
22447 const char *label_name
;
22450 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
22451 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
22452 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
22454 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
22455 LCT_NORMAL
, VOIDmode
, 1, fun
, Pmode
);
22458 else if (DEFAULT_ABI
== ABI_DARWIN
)
22460 const char *mcount_name
= RS6000_MCOUNT
;
22461 int caller_addr_regno
= LR_REGNO
;
22463 /* Be conservative and always set this, at least for now. */
22464 crtl
->uses_pic_offset_table
= 1;
22467 /* For PIC code, set up a stub and collect the caller's address
22468 from r0, which is where the prologue puts it. */
22469 if (MACHOPIC_INDIRECT
22470 && crtl
->uses_pic_offset_table
)
22471 caller_addr_regno
= 0;
22473 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
22474 LCT_NORMAL
, VOIDmode
, 1,
22475 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
22479 /* Write function profiler code. */
22482 output_function_profiler (FILE *file
, int labelno
)
22486 switch (DEFAULT_ABI
)
22489 gcc_unreachable ();
22494 warning (0, "no profiling of 64-bit code for this ABI");
22497 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
22498 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
22499 if (NO_PROFILE_COUNTERS
)
22501 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
22502 reg_names
[0], reg_names
[1]);
22504 else if (TARGET_SECURE_PLT
&& flag_pic
)
22506 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22507 reg_names
[0], reg_names
[1]);
22508 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
22509 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
22510 reg_names
[12], reg_names
[12]);
22511 assemble_name (file
, buf
);
22512 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
22513 assemble_name (file
, buf
);
22514 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
22516 else if (flag_pic
== 1)
22518 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
22519 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
22520 reg_names
[0], reg_names
[1]);
22521 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
22522 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
22523 assemble_name (file
, buf
);
22524 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
22526 else if (flag_pic
> 1)
22528 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
22529 reg_names
[0], reg_names
[1]);
22530 /* Now, we need to get the address of the label. */
22531 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
22532 assemble_name (file
, buf
);
22533 fputs ("-.\n1:", file
);
22534 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
22535 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
22536 reg_names
[0], reg_names
[11]);
22537 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
22538 reg_names
[0], reg_names
[0], reg_names
[11]);
22542 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
22543 assemble_name (file
, buf
);
22544 fputs ("@ha\n", file
);
22545 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
22546 reg_names
[0], reg_names
[1]);
22547 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
22548 assemble_name (file
, buf
);
22549 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
22552 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22553 fprintf (file
, "\tbl %s%s\n",
22554 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
22559 if (!TARGET_PROFILE_KERNEL
)
22561 /* Don't do anything, done in output_profile_hook (). */
22565 gcc_assert (!TARGET_32BIT
);
22567 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
22568 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
22570 if (cfun
->static_chain_decl
!= NULL
)
22572 asm_fprintf (file
, "\tstd %s,24(%s)\n",
22573 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
22574 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
22575 asm_fprintf (file
, "\tld %s,24(%s)\n",
22576 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
22579 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
22587 /* The following variable value is the last issued insn. */
22589 static rtx last_scheduled_insn
;
22591 /* The following variable helps to balance issuing of load and
22592 store instructions */
22594 static int load_store_pendulum
;
22596 /* Power4 load update and store update instructions are cracked into a
22597 load or store and an integer insn which are executed in the same cycle.
22598 Branches have their own dispatch slot which does not count against the
22599 GCC issue rate, but it changes the program flow so there are no other
22600 instructions to issue in this cycle. */
22603 rs6000_variable_issue_1 (rtx insn
, int more
)
22605 last_scheduled_insn
= insn
;
22606 if (GET_CODE (PATTERN (insn
)) == USE
22607 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
22609 cached_can_issue_more
= more
;
22610 return cached_can_issue_more
;
22613 if (insn_terminates_group_p (insn
, current_group
))
22615 cached_can_issue_more
= 0;
22616 return cached_can_issue_more
;
22619 /* If no reservation, but reach here */
22620 if (recog_memoized (insn
) < 0)
22623 if (rs6000_sched_groups
)
22625 if (is_microcoded_insn (insn
))
22626 cached_can_issue_more
= 0;
22627 else if (is_cracked_insn (insn
))
22628 cached_can_issue_more
= more
> 2 ? more
- 2 : 0;
22630 cached_can_issue_more
= more
- 1;
22632 return cached_can_issue_more
;
22635 if (rs6000_cpu_attr
== CPU_CELL
&& is_nonpipeline_insn (insn
))
22638 cached_can_issue_more
= more
- 1;
22639 return cached_can_issue_more
;
22643 rs6000_variable_issue (FILE *stream
, int verbose
, rtx insn
, int more
)
22645 int r
= rs6000_variable_issue_1 (insn
, more
);
22647 fprintf (stream
, "// rs6000_variable_issue (more = %d) = %d\n", more
, r
);
22651 /* Adjust the cost of a scheduling dependency. Return the new cost of
22652 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22655 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
22657 enum attr_type attr_type
;
22659 if (! recog_memoized (insn
))
22662 switch (REG_NOTE_KIND (link
))
22666 /* Data dependency; DEP_INSN writes a register that INSN reads
22667 some cycles later. */
22669 /* Separate a load from a narrower, dependent store. */
22670 if (rs6000_sched_groups
22671 && GET_CODE (PATTERN (insn
)) == SET
22672 && GET_CODE (PATTERN (dep_insn
)) == SET
22673 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
22674 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
22675 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
22676 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
22679 attr_type
= get_attr_type (insn
);
22684 /* Tell the first scheduling pass about the latency between
22685 a mtctr and bctr (and mtlr and br/blr). The first
22686 scheduling pass will not know about this latency since
22687 the mtctr instruction, which has the latency associated
22688 to it, will be generated by reload. */
22689 return TARGET_POWER
? 5 : 4;
22691 /* Leave some extra cycles between a compare and its
22692 dependent branch, to inhibit expensive mispredicts. */
22693 if ((rs6000_cpu_attr
== CPU_PPC603
22694 || rs6000_cpu_attr
== CPU_PPC604
22695 || rs6000_cpu_attr
== CPU_PPC604E
22696 || rs6000_cpu_attr
== CPU_PPC620
22697 || rs6000_cpu_attr
== CPU_PPC630
22698 || rs6000_cpu_attr
== CPU_PPC750
22699 || rs6000_cpu_attr
== CPU_PPC7400
22700 || rs6000_cpu_attr
== CPU_PPC7450
22701 || rs6000_cpu_attr
== CPU_POWER4
22702 || rs6000_cpu_attr
== CPU_POWER5
22703 || rs6000_cpu_attr
== CPU_POWER7
22704 || rs6000_cpu_attr
== CPU_CELL
)
22705 && recog_memoized (dep_insn
)
22706 && (INSN_CODE (dep_insn
) >= 0))
22708 switch (get_attr_type (dep_insn
))
22712 case TYPE_DELAYED_COMPARE
:
22713 case TYPE_IMUL_COMPARE
:
22714 case TYPE_LMUL_COMPARE
:
22715 case TYPE_FPCOMPARE
:
22716 case TYPE_CR_LOGICAL
:
22717 case TYPE_DELAYED_CR
:
22726 case TYPE_STORE_UX
:
22728 case TYPE_FPSTORE_U
:
22729 case TYPE_FPSTORE_UX
:
22730 if ((rs6000_cpu
== PROCESSOR_POWER6
)
22731 && recog_memoized (dep_insn
)
22732 && (INSN_CODE (dep_insn
) >= 0))
22735 if (GET_CODE (PATTERN (insn
)) != SET
)
22736 /* If this happens, we have to extend this to schedule
22737 optimally. Return default for now. */
22740 /* Adjust the cost for the case where the value written
22741 by a fixed point operation is used as the address
22742 gen value on a store. */
22743 switch (get_attr_type (dep_insn
))
22750 if (! store_data_bypass_p (dep_insn
, insn
))
22754 case TYPE_LOAD_EXT
:
22755 case TYPE_LOAD_EXT_U
:
22756 case TYPE_LOAD_EXT_UX
:
22757 case TYPE_VAR_SHIFT_ROTATE
:
22758 case TYPE_VAR_DELAYED_COMPARE
:
22760 if (! store_data_bypass_p (dep_insn
, insn
))
22766 case TYPE_FAST_COMPARE
:
22769 case TYPE_INSERT_WORD
:
22770 case TYPE_INSERT_DWORD
:
22771 case TYPE_FPLOAD_U
:
22772 case TYPE_FPLOAD_UX
:
22774 case TYPE_STORE_UX
:
22775 case TYPE_FPSTORE_U
:
22776 case TYPE_FPSTORE_UX
:
22778 if (! store_data_bypass_p (dep_insn
, insn
))
22786 case TYPE_IMUL_COMPARE
:
22787 case TYPE_LMUL_COMPARE
:
22789 if (! store_data_bypass_p (dep_insn
, insn
))
22795 if (! store_data_bypass_p (dep_insn
, insn
))
22801 if (! store_data_bypass_p (dep_insn
, insn
))
22814 case TYPE_LOAD_EXT
:
22815 case TYPE_LOAD_EXT_U
:
22816 case TYPE_LOAD_EXT_UX
:
22817 if ((rs6000_cpu
== PROCESSOR_POWER6
)
22818 && recog_memoized (dep_insn
)
22819 && (INSN_CODE (dep_insn
) >= 0))
22822 /* Adjust the cost for the case where the value written
22823 by a fixed point instruction is used within the address
22824 gen portion of a subsequent load(u)(x) */
22825 switch (get_attr_type (dep_insn
))
22832 if (set_to_load_agen (dep_insn
, insn
))
22836 case TYPE_LOAD_EXT
:
22837 case TYPE_LOAD_EXT_U
:
22838 case TYPE_LOAD_EXT_UX
:
22839 case TYPE_VAR_SHIFT_ROTATE
:
22840 case TYPE_VAR_DELAYED_COMPARE
:
22842 if (set_to_load_agen (dep_insn
, insn
))
22848 case TYPE_FAST_COMPARE
:
22851 case TYPE_INSERT_WORD
:
22852 case TYPE_INSERT_DWORD
:
22853 case TYPE_FPLOAD_U
:
22854 case TYPE_FPLOAD_UX
:
22856 case TYPE_STORE_UX
:
22857 case TYPE_FPSTORE_U
:
22858 case TYPE_FPSTORE_UX
:
22860 if (set_to_load_agen (dep_insn
, insn
))
22868 case TYPE_IMUL_COMPARE
:
22869 case TYPE_LMUL_COMPARE
:
22871 if (set_to_load_agen (dep_insn
, insn
))
22877 if (set_to_load_agen (dep_insn
, insn
))
22883 if (set_to_load_agen (dep_insn
, insn
))
22894 if ((rs6000_cpu
== PROCESSOR_POWER6
)
22895 && recog_memoized (dep_insn
)
22896 && (INSN_CODE (dep_insn
) >= 0)
22897 && (get_attr_type (dep_insn
) == TYPE_MFFGPR
))
22904 /* Fall out to return default cost. */
22908 case REG_DEP_OUTPUT
:
22909 /* Output dependency; DEP_INSN writes a register that INSN writes some
22911 if ((rs6000_cpu
== PROCESSOR_POWER6
)
22912 && recog_memoized (dep_insn
)
22913 && (INSN_CODE (dep_insn
) >= 0))
22915 attr_type
= get_attr_type (insn
);
22920 if (get_attr_type (dep_insn
) == TYPE_FP
)
22924 if (get_attr_type (dep_insn
) == TYPE_MFFGPR
)
22932 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22937 gcc_unreachable ();
22943 /* Debug version of rs6000_adjust_cost. */
22946 rs6000_debug_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
22948 int ret
= rs6000_adjust_cost (insn
, link
, dep_insn
, cost
);
22954 switch (REG_NOTE_KIND (link
))
22956 default: dep
= "unknown depencency"; break;
22957 case REG_DEP_TRUE
: dep
= "data dependency"; break;
22958 case REG_DEP_OUTPUT
: dep
= "output dependency"; break;
22959 case REG_DEP_ANTI
: dep
= "anti depencency"; break;
22963 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22964 "%s, insn:\n", ret
, cost
, dep
);
22972 /* The function returns a true if INSN is microcoded.
22973 Return false otherwise. */
22976 is_microcoded_insn (rtx insn
)
22978 if (!insn
|| !NONDEBUG_INSN_P (insn
)
22979 || GET_CODE (PATTERN (insn
)) == USE
22980 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
22983 if (rs6000_cpu_attr
== CPU_CELL
)
22984 return get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
;
22986 if (rs6000_sched_groups
)
22988 enum attr_type type
= get_attr_type (insn
);
22989 if (type
== TYPE_LOAD_EXT_U
22990 || type
== TYPE_LOAD_EXT_UX
22991 || type
== TYPE_LOAD_UX
22992 || type
== TYPE_STORE_UX
22993 || type
== TYPE_MFCR
)
23000 /* The function returns true if INSN is cracked into 2 instructions
23001 by the processor (and therefore occupies 2 issue slots). */
23004 is_cracked_insn (rtx insn
)
23006 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23007 || GET_CODE (PATTERN (insn
)) == USE
23008 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23011 if (rs6000_sched_groups
)
23013 enum attr_type type
= get_attr_type (insn
);
23014 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
23015 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
23016 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
23017 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
23018 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
23019 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
23020 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
23021 || type
== TYPE_INSERT_WORD
)
23028 /* The function returns true if INSN can be issued only from
23029 the branch slot. */
23032 is_branch_slot_insn (rtx insn
)
23034 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23035 || GET_CODE (PATTERN (insn
)) == USE
23036 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23039 if (rs6000_sched_groups
)
23041 enum attr_type type
= get_attr_type (insn
);
23042 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
23050 /* The function returns true if out_inst sets a value that is
23051 used in the address generation computation of in_insn */
23053 set_to_load_agen (rtx out_insn
, rtx in_insn
)
23055 rtx out_set
, in_set
;
23057 /* For performance reasons, only handle the simple case where
23058 both loads are a single_set. */
23059 out_set
= single_set (out_insn
);
23062 in_set
= single_set (in_insn
);
23064 return reg_mentioned_p (SET_DEST (out_set
), SET_SRC (in_set
));
23070 /* The function returns true if the target storage location of
23071 out_insn is adjacent to the target storage location of in_insn */
23072 /* Return 1 if memory locations are adjacent. */
23075 adjacent_mem_locations (rtx insn1
, rtx insn2
)
23078 rtx a
= get_store_dest (PATTERN (insn1
));
23079 rtx b
= get_store_dest (PATTERN (insn2
));
23081 if ((GET_CODE (XEXP (a
, 0)) == REG
23082 || (GET_CODE (XEXP (a
, 0)) == PLUS
23083 && GET_CODE (XEXP (XEXP (a
, 0), 1)) == CONST_INT
))
23084 && (GET_CODE (XEXP (b
, 0)) == REG
23085 || (GET_CODE (XEXP (b
, 0)) == PLUS
23086 && GET_CODE (XEXP (XEXP (b
, 0), 1)) == CONST_INT
)))
23088 HOST_WIDE_INT val0
= 0, val1
= 0, val_diff
;
23091 if (GET_CODE (XEXP (a
, 0)) == PLUS
)
23093 reg0
= XEXP (XEXP (a
, 0), 0);
23094 val0
= INTVAL (XEXP (XEXP (a
, 0), 1));
23097 reg0
= XEXP (a
, 0);
23099 if (GET_CODE (XEXP (b
, 0)) == PLUS
)
23101 reg1
= XEXP (XEXP (b
, 0), 0);
23102 val1
= INTVAL (XEXP (XEXP (b
, 0), 1));
23105 reg1
= XEXP (b
, 0);
23107 val_diff
= val1
- val0
;
23109 return ((REGNO (reg0
) == REGNO (reg1
))
23110 && ((MEM_SIZE (a
) && val_diff
== INTVAL (MEM_SIZE (a
)))
23111 || (MEM_SIZE (b
) && val_diff
== -INTVAL (MEM_SIZE (b
)))));
23117 /* A C statement (sans semicolon) to update the integer scheduling
23118 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23119 INSN earlier, reduce the priority to execute INSN later. Do not
23120 define this macro if you do not need to adjust the scheduling
23121 priorities of insns. */
23124 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
23126 /* On machines (like the 750) which have asymmetric integer units,
23127 where one integer unit can do multiply and divides and the other
23128 can't, reduce the priority of multiply/divide so it is scheduled
23129 before other integer operations. */
23132 if (! INSN_P (insn
))
23135 if (GET_CODE (PATTERN (insn
)) == USE
)
23138 switch (rs6000_cpu_attr
) {
23140 switch (get_attr_type (insn
))
23147 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
23148 priority
, priority
);
23149 if (priority
>= 0 && priority
< 0x01000000)
23156 if (insn_must_be_first_in_group (insn
)
23157 && reload_completed
23158 && current_sched_info
->sched_max_insns_priority
23159 && rs6000_sched_restricted_insns_priority
)
23162 /* Prioritize insns that can be dispatched only in the first
23164 if (rs6000_sched_restricted_insns_priority
== 1)
23165 /* Attach highest priority to insn. This means that in
23166 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23167 precede 'priority' (critical path) considerations. */
23168 return current_sched_info
->sched_max_insns_priority
;
23169 else if (rs6000_sched_restricted_insns_priority
== 2)
23170 /* Increase priority of insn by a minimal amount. This means that in
23171 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23172 considerations precede dispatch-slot restriction considerations. */
23173 return (priority
+ 1);
23176 if (rs6000_cpu
== PROCESSOR_POWER6
23177 && ((load_store_pendulum
== -2 && is_load_insn (insn
))
23178 || (load_store_pendulum
== 2 && is_store_insn (insn
))))
23179 /* Attach highest priority to insn if the scheduler has just issued two
23180 stores and this instruction is a load, or two loads and this instruction
23181 is a store. Power6 wants loads and stores scheduled alternately
23183 return current_sched_info
->sched_max_insns_priority
;
23188 /* Return true if the instruction is nonpipelined on the Cell. */
23190 is_nonpipeline_insn (rtx insn
)
23192 enum attr_type type
;
23193 if (!insn
|| !NONDEBUG_INSN_P (insn
)
23194 || GET_CODE (PATTERN (insn
)) == USE
23195 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23198 type
= get_attr_type (insn
);
23199 if (type
== TYPE_IMUL
23200 || type
== TYPE_IMUL2
23201 || type
== TYPE_IMUL3
23202 || type
== TYPE_LMUL
23203 || type
== TYPE_IDIV
23204 || type
== TYPE_LDIV
23205 || type
== TYPE_SDIV
23206 || type
== TYPE_DDIV
23207 || type
== TYPE_SSQRT
23208 || type
== TYPE_DSQRT
23209 || type
== TYPE_MFCR
23210 || type
== TYPE_MFCRF
23211 || type
== TYPE_MFJMPR
)
23219 /* Return how many instructions the machine can issue per cycle. */
23222 rs6000_issue_rate (void)
23224 /* Unless scheduling for register pressure, use issue rate of 1 for
23225 first scheduling pass to decrease degradation. */
23226 if (!reload_completed
&& !flag_sched_pressure
)
23229 switch (rs6000_cpu_attr
) {
23230 case CPU_RIOS1
: /* ? */
23232 case CPU_PPC601
: /* ? */
23241 case CPU_PPCE300C2
:
23242 case CPU_PPCE300C3
:
23243 case CPU_PPCE500MC
:
23244 case CPU_PPCE500MC64
:
23264 /* Return how many instructions to look ahead for better insn
23268 rs6000_use_sched_lookahead (void)
23270 if (rs6000_cpu_attr
== CPU_PPC8540
)
23272 if (rs6000_cpu_attr
== CPU_CELL
)
23273 return (reload_completed
? 8 : 0);
23277 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23279 rs6000_use_sched_lookahead_guard (rtx insn
)
23281 if (rs6000_cpu_attr
!= CPU_CELL
)
23284 if (insn
== NULL_RTX
|| !INSN_P (insn
))
23287 if (!reload_completed
23288 || is_nonpipeline_insn (insn
)
23289 || is_microcoded_insn (insn
))
23295 /* Determine is PAT refers to memory. */
23298 is_mem_ref (rtx pat
)
23304 /* stack_tie does not produce any real memory traffic. */
23305 if (GET_CODE (pat
) == UNSPEC
23306 && XINT (pat
, 1) == UNSPEC_TIE
)
23309 if (GET_CODE (pat
) == MEM
)
23312 /* Recursively process the pattern. */
23313 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
23315 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
23318 ret
|= is_mem_ref (XEXP (pat
, i
));
23319 else if (fmt
[i
] == 'E')
23320 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
23321 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
23327 /* Determine if PAT is a PATTERN of a load insn. */
23330 is_load_insn1 (rtx pat
)
23332 if (!pat
|| pat
== NULL_RTX
)
23335 if (GET_CODE (pat
) == SET
)
23336 return is_mem_ref (SET_SRC (pat
));
23338 if (GET_CODE (pat
) == PARALLEL
)
23342 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23343 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
23350 /* Determine if INSN loads from memory. */
23353 is_load_insn (rtx insn
)
23355 if (!insn
|| !INSN_P (insn
))
23358 if (GET_CODE (insn
) == CALL_INSN
)
23361 return is_load_insn1 (PATTERN (insn
));
23364 /* Determine if PAT is a PATTERN of a store insn. */
23367 is_store_insn1 (rtx pat
)
23369 if (!pat
|| pat
== NULL_RTX
)
23372 if (GET_CODE (pat
) == SET
)
23373 return is_mem_ref (SET_DEST (pat
));
23375 if (GET_CODE (pat
) == PARALLEL
)
23379 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23380 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
23387 /* Determine if INSN stores to memory. */
23390 is_store_insn (rtx insn
)
23392 if (!insn
|| !INSN_P (insn
))
23395 return is_store_insn1 (PATTERN (insn
));
23398 /* Return the dest of a store insn. */
23401 get_store_dest (rtx pat
)
23403 gcc_assert (is_store_insn1 (pat
));
23405 if (GET_CODE (pat
) == SET
)
23406 return SET_DEST (pat
);
23407 else if (GET_CODE (pat
) == PARALLEL
)
23411 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
23413 rtx inner_pat
= XVECEXP (pat
, 0, i
);
23414 if (GET_CODE (inner_pat
) == SET
23415 && is_mem_ref (SET_DEST (inner_pat
)))
23419 /* We shouldn't get here, because we should have either a simple
23420 store insn or a store with update which are covered above. */
23424 /* Returns whether the dependence between INSN and NEXT is considered
23425 costly by the given target. */
23428 rs6000_is_costly_dependence (dep_t dep
, int cost
, int distance
)
23433 /* If the flag is not enabled - no dependence is considered costly;
23434 allow all dependent insns in the same group.
23435 This is the most aggressive option. */
23436 if (rs6000_sched_costly_dep
== no_dep_costly
)
23439 /* If the flag is set to 1 - a dependence is always considered costly;
23440 do not allow dependent instructions in the same group.
23441 This is the most conservative option. */
23442 if (rs6000_sched_costly_dep
== all_deps_costly
)
23445 insn
= DEP_PRO (dep
);
23446 next
= DEP_CON (dep
);
23448 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
23449 && is_load_insn (next
)
23450 && is_store_insn (insn
))
23451 /* Prevent load after store in the same group. */
23454 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
23455 && is_load_insn (next
)
23456 && is_store_insn (insn
)
23457 && DEP_TYPE (dep
) == REG_DEP_TRUE
)
23458 /* Prevent load after store in the same group if it is a true
23462 /* The flag is set to X; dependences with latency >= X are considered costly,
23463 and will not be scheduled in the same group. */
23464 if (rs6000_sched_costly_dep
<= max_dep_latency
23465 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
23471 /* Return the next insn after INSN that is found before TAIL is reached,
23472 skipping any "non-active" insns - insns that will not actually occupy
23473 an issue slot. Return NULL_RTX if such an insn is not found. */
23476 get_next_active_insn (rtx insn
, rtx tail
)
23478 if (insn
== NULL_RTX
|| insn
== tail
)
23483 insn
= NEXT_INSN (insn
);
23484 if (insn
== NULL_RTX
|| insn
== tail
)
23489 || (NONJUMP_INSN_P (insn
)
23490 && GET_CODE (PATTERN (insn
)) != USE
23491 && GET_CODE (PATTERN (insn
)) != CLOBBER
23492 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
23498 /* We are about to begin issuing insns for this clock cycle. */
23501 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED
, int sched_verbose
,
23502 rtx
*ready ATTRIBUTE_UNUSED
,
23503 int *pn_ready ATTRIBUTE_UNUSED
,
23504 int clock_var ATTRIBUTE_UNUSED
)
23506 int n_ready
= *pn_ready
;
23509 fprintf (dump
, "// rs6000_sched_reorder :\n");
23511 /* Reorder the ready list, if the second to last ready insn
23512 is a nonepipeline insn. */
23513 if (rs6000_cpu_attr
== CPU_CELL
&& n_ready
> 1)
23515 if (is_nonpipeline_insn (ready
[n_ready
- 1])
23516 && (recog_memoized (ready
[n_ready
- 2]) > 0))
23517 /* Simply swap first two insns. */
23519 rtx tmp
= ready
[n_ready
- 1];
23520 ready
[n_ready
- 1] = ready
[n_ready
- 2];
23521 ready
[n_ready
- 2] = tmp
;
23525 if (rs6000_cpu
== PROCESSOR_POWER6
)
23526 load_store_pendulum
= 0;
23528 return rs6000_issue_rate ();
23531 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23534 rs6000_sched_reorder2 (FILE *dump
, int sched_verbose
, rtx
*ready
,
23535 int *pn_ready
, int clock_var ATTRIBUTE_UNUSED
)
23538 fprintf (dump
, "// rs6000_sched_reorder2 :\n");
23540 /* For Power6, we need to handle some special cases to try and keep the
23541 store queue from overflowing and triggering expensive flushes.
23543 This code monitors how load and store instructions are being issued
23544 and skews the ready list one way or the other to increase the likelihood
23545 that a desired instruction is issued at the proper time.
23547 A couple of things are done. First, we maintain a "load_store_pendulum"
23548 to track the current state of load/store issue.
23550 - If the pendulum is at zero, then no loads or stores have been
23551 issued in the current cycle so we do nothing.
23553 - If the pendulum is 1, then a single load has been issued in this
23554 cycle and we attempt to locate another load in the ready list to
23557 - If the pendulum is -2, then two stores have already been
23558 issued in this cycle, so we increase the priority of the first load
23559 in the ready list to increase it's likelihood of being chosen first
23562 - If the pendulum is -1, then a single store has been issued in this
23563 cycle and we attempt to locate another store in the ready list to
23564 issue with it, preferring a store to an adjacent memory location to
23565 facilitate store pairing in the store queue.
23567 - If the pendulum is 2, then two loads have already been
23568 issued in this cycle, so we increase the priority of the first store
23569 in the ready list to increase it's likelihood of being chosen first
23572 - If the pendulum < -2 or > 2, then do nothing.
23574 Note: This code covers the most common scenarios. There exist non
23575 load/store instructions which make use of the LSU and which
23576 would need to be accounted for to strictly model the behavior
23577 of the machine. Those instructions are currently unaccounted
23578 for to help minimize compile time overhead of this code.
23580 if (rs6000_cpu
== PROCESSOR_POWER6
&& last_scheduled_insn
)
23586 if (is_store_insn (last_scheduled_insn
))
23587 /* Issuing a store, swing the load_store_pendulum to the left */
23588 load_store_pendulum
--;
23589 else if (is_load_insn (last_scheduled_insn
))
23590 /* Issuing a load, swing the load_store_pendulum to the right */
23591 load_store_pendulum
++;
23593 return cached_can_issue_more
;
23595 /* If the pendulum is balanced, or there is only one instruction on
23596 the ready list, then all is well, so return. */
23597 if ((load_store_pendulum
== 0) || (*pn_ready
<= 1))
23598 return cached_can_issue_more
;
23600 if (load_store_pendulum
== 1)
23602 /* A load has been issued in this cycle. Scan the ready list
23603 for another load to issue with it */
23608 if (is_load_insn (ready
[pos
]))
23610 /* Found a load. Move it to the head of the ready list,
23611 and adjust it's priority so that it is more likely to
23614 for (i
=pos
; i
<*pn_ready
-1; i
++)
23615 ready
[i
] = ready
[i
+ 1];
23616 ready
[*pn_ready
-1] = tmp
;
23618 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
23619 INSN_PRIORITY (tmp
)++;
23625 else if (load_store_pendulum
== -2)
23627 /* Two stores have been issued in this cycle. Increase the
23628 priority of the first load in the ready list to favor it for
23629 issuing in the next cycle. */
23634 if (is_load_insn (ready
[pos
])
23636 && INSN_PRIORITY_KNOWN (ready
[pos
]))
23638 INSN_PRIORITY (ready
[pos
])++;
23640 /* Adjust the pendulum to account for the fact that a load
23641 was found and increased in priority. This is to prevent
23642 increasing the priority of multiple loads */
23643 load_store_pendulum
--;
23650 else if (load_store_pendulum
== -1)
23652 /* A store has been issued in this cycle. Scan the ready list for
23653 another store to issue with it, preferring a store to an adjacent
23655 int first_store_pos
= -1;
23661 if (is_store_insn (ready
[pos
]))
23663 /* Maintain the index of the first store found on the
23665 if (first_store_pos
== -1)
23666 first_store_pos
= pos
;
23668 if (is_store_insn (last_scheduled_insn
)
23669 && adjacent_mem_locations (last_scheduled_insn
,ready
[pos
]))
23671 /* Found an adjacent store. Move it to the head of the
23672 ready list, and adjust it's priority so that it is
23673 more likely to stay there */
23675 for (i
=pos
; i
<*pn_ready
-1; i
++)
23676 ready
[i
] = ready
[i
+ 1];
23677 ready
[*pn_ready
-1] = tmp
;
23679 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
23680 INSN_PRIORITY (tmp
)++;
23682 first_store_pos
= -1;
23690 if (first_store_pos
>= 0)
23692 /* An adjacent store wasn't found, but a non-adjacent store was,
23693 so move the non-adjacent store to the front of the ready
23694 list, and adjust its priority so that it is more likely to
23696 tmp
= ready
[first_store_pos
];
23697 for (i
=first_store_pos
; i
<*pn_ready
-1; i
++)
23698 ready
[i
] = ready
[i
+ 1];
23699 ready
[*pn_ready
-1] = tmp
;
23700 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
23701 INSN_PRIORITY (tmp
)++;
23704 else if (load_store_pendulum
== 2)
23706 /* Two loads have been issued in this cycle. Increase the priority
23707 of the first store in the ready list to favor it for issuing in
23713 if (is_store_insn (ready
[pos
])
23715 && INSN_PRIORITY_KNOWN (ready
[pos
]))
23717 INSN_PRIORITY (ready
[pos
])++;
23719 /* Adjust the pendulum to account for the fact that a store
23720 was found and increased in priority. This is to prevent
23721 increasing the priority of multiple stores */
23722 load_store_pendulum
++;
23731 return cached_can_issue_more
;
23734 /* Return whether the presence of INSN causes a dispatch group termination
23735 of group WHICH_GROUP.
23737 If WHICH_GROUP == current_group, this function will return true if INSN
23738 causes the termination of the current group (i.e, the dispatch group to
23739 which INSN belongs). This means that INSN will be the last insn in the
23740 group it belongs to.
23742 If WHICH_GROUP == previous_group, this function will return true if INSN
23743 causes the termination of the previous group (i.e, the dispatch group that
23744 precedes the group to which INSN belongs). This means that INSN will be
23745 the first insn in the group it belongs to). */
23748 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
23755 first
= insn_must_be_first_in_group (insn
);
23756 last
= insn_must_be_last_in_group (insn
);
23761 if (which_group
== current_group
)
23763 else if (which_group
== previous_group
)
23771 insn_must_be_first_in_group (rtx insn
)
23773 enum attr_type type
;
23776 || GET_CODE (insn
) == NOTE
23777 || DEBUG_INSN_P (insn
)
23778 || GET_CODE (PATTERN (insn
)) == USE
23779 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23782 switch (rs6000_cpu
)
23784 case PROCESSOR_POWER5
:
23785 if (is_cracked_insn (insn
))
23787 case PROCESSOR_POWER4
:
23788 if (is_microcoded_insn (insn
))
23791 if (!rs6000_sched_groups
)
23794 type
= get_attr_type (insn
);
23801 case TYPE_DELAYED_CR
:
23802 case TYPE_CR_LOGICAL
:
23816 case PROCESSOR_POWER6
:
23817 type
= get_attr_type (insn
);
23821 case TYPE_INSERT_DWORD
:
23825 case TYPE_VAR_SHIFT_ROTATE
:
23832 case TYPE_INSERT_WORD
:
23833 case TYPE_DELAYED_COMPARE
:
23834 case TYPE_IMUL_COMPARE
:
23835 case TYPE_LMUL_COMPARE
:
23836 case TYPE_FPCOMPARE
:
23847 case TYPE_LOAD_EXT_UX
:
23849 case TYPE_STORE_UX
:
23850 case TYPE_FPLOAD_U
:
23851 case TYPE_FPLOAD_UX
:
23852 case TYPE_FPSTORE_U
:
23853 case TYPE_FPSTORE_UX
:
23859 case PROCESSOR_POWER7
:
23860 type
= get_attr_type (insn
);
23864 case TYPE_CR_LOGICAL
:
23871 case TYPE_DELAYED_COMPARE
:
23872 case TYPE_VAR_DELAYED_COMPARE
:
23878 case TYPE_LOAD_EXT
:
23879 case TYPE_LOAD_EXT_U
:
23880 case TYPE_LOAD_EXT_UX
:
23882 case TYPE_STORE_UX
:
23883 case TYPE_FPLOAD_U
:
23884 case TYPE_FPLOAD_UX
:
23885 case TYPE_FPSTORE_U
:
23886 case TYPE_FPSTORE_UX
:
23902 insn_must_be_last_in_group (rtx insn
)
23904 enum attr_type type
;
23907 || GET_CODE (insn
) == NOTE
23908 || DEBUG_INSN_P (insn
)
23909 || GET_CODE (PATTERN (insn
)) == USE
23910 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
23913 switch (rs6000_cpu
) {
23914 case PROCESSOR_POWER4
:
23915 case PROCESSOR_POWER5
:
23916 if (is_microcoded_insn (insn
))
23919 if (is_branch_slot_insn (insn
))
23923 case PROCESSOR_POWER6
:
23924 type
= get_attr_type (insn
);
23931 case TYPE_VAR_SHIFT_ROTATE
:
23938 case TYPE_DELAYED_COMPARE
:
23939 case TYPE_IMUL_COMPARE
:
23940 case TYPE_LMUL_COMPARE
:
23941 case TYPE_FPCOMPARE
:
23955 case PROCESSOR_POWER7
:
23956 type
= get_attr_type (insn
);
23964 case TYPE_LOAD_EXT_U
:
23965 case TYPE_LOAD_EXT_UX
:
23966 case TYPE_STORE_UX
:
23979 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23980 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23983 is_costly_group (rtx
*group_insns
, rtx next_insn
)
23986 int issue_rate
= rs6000_issue_rate ();
23988 for (i
= 0; i
< issue_rate
; i
++)
23990 sd_iterator_def sd_it
;
23992 rtx insn
= group_insns
[i
];
23997 FOR_EACH_DEP (insn
, SD_LIST_FORW
, sd_it
, dep
)
23999 rtx next
= DEP_CON (dep
);
24001 if (next
== next_insn
24002 && rs6000_is_costly_dependence (dep
, dep_cost (dep
), 0))
24010 /* Utility of the function redefine_groups.
24011 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24012 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24013 to keep it "far" (in a separate group) from GROUP_INSNS, following
24014 one of the following schemes, depending on the value of the flag
24015 -minsert_sched_nops = X:
24016 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24017 in order to force NEXT_INSN into a separate group.
24018 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24019 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24020 insertion (has a group just ended, how many vacant issue slots remain in the
24021 last group, and how many dispatch groups were encountered so far). */
24024 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
24025 rtx next_insn
, bool *group_end
, int can_issue_more
,
24030 int issue_rate
= rs6000_issue_rate ();
24031 bool end
= *group_end
;
24034 if (next_insn
== NULL_RTX
|| DEBUG_INSN_P (next_insn
))
24035 return can_issue_more
;
24037 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
24038 return can_issue_more
;
24040 force
= is_costly_group (group_insns
, next_insn
);
24042 return can_issue_more
;
24044 if (sched_verbose
> 6)
24045 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
24046 *group_count
,can_issue_more
);
24048 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
24051 can_issue_more
= 0;
24053 /* Since only a branch can be issued in the last issue_slot, it is
24054 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24055 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24056 in this case the last nop will start a new group and the branch
24057 will be forced to the new group. */
24058 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
24061 while (can_issue_more
> 0)
24064 emit_insn_before (nop
, next_insn
);
24072 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
24074 int n_nops
= rs6000_sched_insert_nops
;
24076 /* Nops can't be issued from the branch slot, so the effective
24077 issue_rate for nops is 'issue_rate - 1'. */
24078 if (can_issue_more
== 0)
24079 can_issue_more
= issue_rate
;
24081 if (can_issue_more
== 0)
24083 can_issue_more
= issue_rate
- 1;
24086 for (i
= 0; i
< issue_rate
; i
++)
24088 group_insns
[i
] = 0;
24095 emit_insn_before (nop
, next_insn
);
24096 if (can_issue_more
== issue_rate
- 1) /* new group begins */
24099 if (can_issue_more
== 0)
24101 can_issue_more
= issue_rate
- 1;
24104 for (i
= 0; i
< issue_rate
; i
++)
24106 group_insns
[i
] = 0;
24112 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24115 /* Is next_insn going to start a new group? */
24118 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
24119 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
24120 || (can_issue_more
< issue_rate
&&
24121 insn_terminates_group_p (next_insn
, previous_group
)));
24122 if (*group_end
&& end
)
24125 if (sched_verbose
> 6)
24126 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
24127 *group_count
, can_issue_more
);
24128 return can_issue_more
;
24131 return can_issue_more
;
24134 /* This function tries to synch the dispatch groups that the compiler "sees"
24135 with the dispatch groups that the processor dispatcher is expected to
24136 form in practice. It tries to achieve this synchronization by forcing the
24137 estimated processor grouping on the compiler (as opposed to the function
24138 'pad_goups' which tries to force the scheduler's grouping on the processor).
24140 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24141 examines the (estimated) dispatch groups that will be formed by the processor
24142 dispatcher. It marks these group boundaries to reflect the estimated
24143 processor grouping, overriding the grouping that the scheduler had marked.
24144 Depending on the value of the flag '-minsert-sched-nops' this function can
24145 force certain insns into separate groups or force a certain distance between
24146 them by inserting nops, for example, if there exists a "costly dependence"
24149 The function estimates the group boundaries that the processor will form as
24150 follows: It keeps track of how many vacant issue slots are available after
24151 each insn. A subsequent insn will start a new group if one of the following
24153 - no more vacant issue slots remain in the current dispatch group.
24154 - only the last issue slot, which is the branch slot, is vacant, but the next
24155 insn is not a branch.
24156 - only the last 2 or less issue slots, including the branch slot, are vacant,
24157 which means that a cracked insn (which occupies two issue slots) can't be
24158 issued in this group.
24159 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24160 start a new group. */
24163 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
24165 rtx insn
, next_insn
;
24167 int can_issue_more
;
24170 int group_count
= 0;
24174 issue_rate
= rs6000_issue_rate ();
24175 group_insns
= XALLOCAVEC (rtx
, issue_rate
);
24176 for (i
= 0; i
< issue_rate
; i
++)
24178 group_insns
[i
] = 0;
24180 can_issue_more
= issue_rate
;
24182 insn
= get_next_active_insn (prev_head_insn
, tail
);
24185 while (insn
!= NULL_RTX
)
24187 slot
= (issue_rate
- can_issue_more
);
24188 group_insns
[slot
] = insn
;
24190 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
24191 if (insn_terminates_group_p (insn
, current_group
))
24192 can_issue_more
= 0;
24194 next_insn
= get_next_active_insn (insn
, tail
);
24195 if (next_insn
== NULL_RTX
)
24196 return group_count
+ 1;
24198 /* Is next_insn going to start a new group? */
24200 = (can_issue_more
== 0
24201 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
24202 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
24203 || (can_issue_more
< issue_rate
&&
24204 insn_terminates_group_p (next_insn
, previous_group
)));
24206 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
24207 next_insn
, &group_end
, can_issue_more
,
24213 can_issue_more
= 0;
24214 for (i
= 0; i
< issue_rate
; i
++)
24216 group_insns
[i
] = 0;
24220 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
24221 PUT_MODE (next_insn
, VOIDmode
);
24222 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
24223 PUT_MODE (next_insn
, TImode
);
24226 if (can_issue_more
== 0)
24227 can_issue_more
= issue_rate
;
24230 return group_count
;
24233 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24234 dispatch group boundaries that the scheduler had marked. Pad with nops
24235 any dispatch groups which have vacant issue slots, in order to force the
24236 scheduler's grouping on the processor dispatcher. The function
24237 returns the number of dispatch groups found. */
24240 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
24242 rtx insn
, next_insn
;
24245 int can_issue_more
;
24247 int group_count
= 0;
24249 /* Initialize issue_rate. */
24250 issue_rate
= rs6000_issue_rate ();
24251 can_issue_more
= issue_rate
;
24253 insn
= get_next_active_insn (prev_head_insn
, tail
);
24254 next_insn
= get_next_active_insn (insn
, tail
);
24256 while (insn
!= NULL_RTX
)
24259 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
24261 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
24263 if (next_insn
== NULL_RTX
)
24268 /* If the scheduler had marked group termination at this location
24269 (between insn and next_insn), and neither insn nor next_insn will
24270 force group termination, pad the group with nops to force group
24273 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
24274 && !insn_terminates_group_p (insn
, current_group
)
24275 && !insn_terminates_group_p (next_insn
, previous_group
))
24277 if (!is_branch_slot_insn (next_insn
))
24280 while (can_issue_more
)
24283 emit_insn_before (nop
, next_insn
);
24288 can_issue_more
= issue_rate
;
24293 next_insn
= get_next_active_insn (insn
, tail
);
24296 return group_count
;
24299 /* We're beginning a new block. Initialize data structures as necessary. */
24302 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED
,
24303 int sched_verbose ATTRIBUTE_UNUSED
,
24304 int max_ready ATTRIBUTE_UNUSED
)
24306 last_scheduled_insn
= NULL_RTX
;
24307 load_store_pendulum
= 0;
24310 /* The following function is called at the end of scheduling BB.
24311 After reload, it inserts nops at insn group bundling. */
24314 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
24319 fprintf (dump
, "=== Finishing schedule.\n");
24321 if (reload_completed
&& rs6000_sched_groups
)
24323 /* Do not run sched_finish hook when selective scheduling enabled. */
24324 if (sel_sched_p ())
24327 if (rs6000_sched_insert_nops
== sched_finish_none
)
24330 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
24331 n_groups
= pad_groups (dump
, sched_verbose
,
24332 current_sched_info
->prev_head
,
24333 current_sched_info
->next_tail
);
24335 n_groups
= redefine_groups (dump
, sched_verbose
,
24336 current_sched_info
->prev_head
,
24337 current_sched_info
->next_tail
);
24339 if (sched_verbose
>= 6)
24341 fprintf (dump
, "ngroups = %d\n", n_groups
);
24342 print_rtl (dump
, current_sched_info
->prev_head
);
24343 fprintf (dump
, "Done finish_sched\n");
24348 struct _rs6000_sched_context
24350 short cached_can_issue_more
;
24351 rtx last_scheduled_insn
;
24352 int load_store_pendulum
;
24355 typedef struct _rs6000_sched_context rs6000_sched_context_def
;
24356 typedef rs6000_sched_context_def
*rs6000_sched_context_t
;
24358 /* Allocate store for new scheduling context. */
24360 rs6000_alloc_sched_context (void)
24362 return xmalloc (sizeof (rs6000_sched_context_def
));
24365 /* If CLEAN_P is true then initializes _SC with clean data,
24366 and from the global context otherwise. */
24368 rs6000_init_sched_context (void *_sc
, bool clean_p
)
24370 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
24374 sc
->cached_can_issue_more
= 0;
24375 sc
->last_scheduled_insn
= NULL_RTX
;
24376 sc
->load_store_pendulum
= 0;
24380 sc
->cached_can_issue_more
= cached_can_issue_more
;
24381 sc
->last_scheduled_insn
= last_scheduled_insn
;
24382 sc
->load_store_pendulum
= load_store_pendulum
;
24386 /* Sets the global scheduling context to the one pointed to by _SC. */
24388 rs6000_set_sched_context (void *_sc
)
24390 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
24392 gcc_assert (sc
!= NULL
);
24394 cached_can_issue_more
= sc
->cached_can_issue_more
;
24395 last_scheduled_insn
= sc
->last_scheduled_insn
;
24396 load_store_pendulum
= sc
->load_store_pendulum
;
24401 rs6000_free_sched_context (void *_sc
)
24403 gcc_assert (_sc
!= NULL
);
24409 /* Length in units of the trampoline for entering a nested function. */
24412 rs6000_trampoline_size (void)
24416 switch (DEFAULT_ABI
)
24419 gcc_unreachable ();
24422 ret
= (TARGET_32BIT
) ? 12 : 24;
24427 ret
= (TARGET_32BIT
) ? 40 : 48;
24434 /* Emit RTL insns to initialize the variable parts of a trampoline.
24435 FNADDR is an RTX for the address of the function's pure code.
24436 CXT is an RTX for the static chain value for the function. */
24439 rs6000_trampoline_init (rtx m_tramp
, tree fndecl
, rtx cxt
)
24441 int regsize
= (TARGET_32BIT
) ? 4 : 8;
24442 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
24443 rtx ctx_reg
= force_reg (Pmode
, cxt
);
24444 rtx addr
= force_reg (Pmode
, XEXP (m_tramp
, 0));
24446 switch (DEFAULT_ABI
)
24449 gcc_unreachable ();
24451 /* Under AIX, just build the 3 word function descriptor */
24454 rtx fnmem
= gen_const_mem (Pmode
, force_reg (Pmode
, fnaddr
));
24455 rtx fn_reg
= gen_reg_rtx (Pmode
);
24456 rtx toc_reg
= gen_reg_rtx (Pmode
);
24458 /* Macro to shorten the code expansions below. */
24459 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24461 m_tramp
= replace_equiv_address (m_tramp
, addr
);
24463 emit_move_insn (fn_reg
, MEM_PLUS (fnmem
, 0));
24464 emit_move_insn (toc_reg
, MEM_PLUS (fnmem
, regsize
));
24465 emit_move_insn (MEM_PLUS (m_tramp
, 0), fn_reg
);
24466 emit_move_insn (MEM_PLUS (m_tramp
, regsize
), toc_reg
);
24467 emit_move_insn (MEM_PLUS (m_tramp
, 2*regsize
), ctx_reg
);
24473 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24476 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__trampoline_setup"),
24477 LCT_NORMAL
, VOIDmode
, 4,
24479 GEN_INT (rs6000_trampoline_size ()), SImode
,
24487 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24488 identifier as an argument, so the front end shouldn't look it up. */
24491 rs6000_attribute_takes_identifier_p (const_tree attr_id
)
24493 return is_attribute_p ("altivec", attr_id
);
24496 /* Handle the "altivec" attribute. The attribute may have
24497 arguments as follows:
24499 __attribute__((altivec(vector__)))
24500 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24501 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24503 and may appear more than once (e.g., 'vector bool char') in a
24504 given declaration. */
24507 rs6000_handle_altivec_attribute (tree
*node
,
24508 tree name ATTRIBUTE_UNUSED
,
24510 int flags ATTRIBUTE_UNUSED
,
24511 bool *no_add_attrs
)
24513 tree type
= *node
, result
= NULL_TREE
;
24514 enum machine_mode mode
;
24517 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
24518 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
24519 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
24522 while (POINTER_TYPE_P (type
)
24523 || TREE_CODE (type
) == FUNCTION_TYPE
24524 || TREE_CODE (type
) == METHOD_TYPE
24525 || TREE_CODE (type
) == ARRAY_TYPE
)
24526 type
= TREE_TYPE (type
);
24528 mode
= TYPE_MODE (type
);
24530 /* Check for invalid AltiVec type qualifiers. */
24531 if (type
== long_double_type_node
)
24532 error ("use of %<long double%> in AltiVec types is invalid");
24533 else if (type
== boolean_type_node
)
24534 error ("use of boolean types in AltiVec types is invalid");
24535 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
24536 error ("use of %<complex%> in AltiVec types is invalid");
24537 else if (DECIMAL_FLOAT_MODE_P (mode
))
24538 error ("use of decimal floating point types in AltiVec types is invalid");
24539 else if (!TARGET_VSX
)
24541 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
24544 error ("use of %<long%> in AltiVec types is invalid for "
24545 "64-bit code without -mvsx");
24546 else if (rs6000_warn_altivec_long
)
24547 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24550 else if (type
== long_long_unsigned_type_node
24551 || type
== long_long_integer_type_node
)
24552 error ("use of %<long long%> in AltiVec types is invalid without "
24554 else if (type
== double_type_node
)
24555 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24558 switch (altivec_type
)
24561 unsigned_p
= TYPE_UNSIGNED (type
);
24565 result
= (unsigned_p
? unsigned_V2DI_type_node
: V2DI_type_node
);
24568 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
24571 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
24574 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
24576 case SFmode
: result
= V4SF_type_node
; break;
24577 case DFmode
: result
= V2DF_type_node
; break;
24578 /* If the user says 'vector int bool', we may be handed the 'bool'
24579 attribute _before_ the 'vector' attribute, and so select the
24580 proper type in the 'b' case below. */
24581 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
24582 case V2DImode
: case V2DFmode
:
24590 case DImode
: case V2DImode
: result
= bool_V2DI_type_node
; break;
24591 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
24592 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
24593 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
24600 case V8HImode
: result
= pixel_V8HI_type_node
;
24606 /* Propagate qualifiers attached to the element type
24607 onto the vector type. */
24608 if (result
&& result
!= type
&& TYPE_QUALS (type
))
24609 result
= build_qualified_type (result
, TYPE_QUALS (type
));
24611 *no_add_attrs
= true; /* No need to hang on to the attribute. */
24614 *node
= lang_hooks
.types
.reconstruct_complex_type (*node
, result
);
24619 /* AltiVec defines four built-in scalar types that serve as vector
24620 elements; we must teach the compiler how to mangle them. */
24622 static const char *
24623 rs6000_mangle_type (const_tree type
)
24625 type
= TYPE_MAIN_VARIANT (type
);
24627 if (TREE_CODE (type
) != VOID_TYPE
&& TREE_CODE (type
) != BOOLEAN_TYPE
24628 && TREE_CODE (type
) != INTEGER_TYPE
&& TREE_CODE (type
) != REAL_TYPE
)
24631 if (type
== bool_char_type_node
) return "U6__boolc";
24632 if (type
== bool_short_type_node
) return "U6__bools";
24633 if (type
== pixel_type_node
) return "u7__pixel";
24634 if (type
== bool_int_type_node
) return "U6__booli";
24635 if (type
== bool_long_type_node
) return "U6__booll";
24637 /* Mangle IBM extended float long double as `g' (__float128) on
24638 powerpc*-linux where long-double-64 previously was the default. */
24639 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
24641 && TARGET_LONG_DOUBLE_128
24642 && !TARGET_IEEEQUAD
)
24645 /* For all other types, use normal C++ mangling. */
24649 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24650 struct attribute_spec.handler. */
24653 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
24654 tree args ATTRIBUTE_UNUSED
,
24655 int flags ATTRIBUTE_UNUSED
,
24656 bool *no_add_attrs
)
24658 if (TREE_CODE (*node
) != FUNCTION_TYPE
24659 && TREE_CODE (*node
) != FIELD_DECL
24660 && TREE_CODE (*node
) != TYPE_DECL
)
24662 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
24664 *no_add_attrs
= true;
24670 /* Set longcall attributes on all functions declared when
24671 rs6000_default_long_calls is true. */
24673 rs6000_set_default_type_attributes (tree type
)
24675 if (rs6000_default_long_calls
24676 && (TREE_CODE (type
) == FUNCTION_TYPE
24677 || TREE_CODE (type
) == METHOD_TYPE
))
24678 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
24680 TYPE_ATTRIBUTES (type
));
24683 darwin_set_default_type_attributes (type
);
24687 /* Return a reference suitable for calling a function with the
24688 longcall attribute. */
24691 rs6000_longcall_ref (rtx call_ref
)
24693 const char *call_name
;
24696 if (GET_CODE (call_ref
) != SYMBOL_REF
)
24699 /* System V adds '.' to the internal name, so skip them. */
24700 call_name
= XSTR (call_ref
, 0);
24701 if (*call_name
== '.')
24703 while (*call_name
== '.')
24706 node
= get_identifier (call_name
);
24707 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
24710 return force_reg (Pmode
, call_ref
);
24713 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24714 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24717 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24718 struct attribute_spec.handler. */
24720 rs6000_handle_struct_attribute (tree
*node
, tree name
,
24721 tree args ATTRIBUTE_UNUSED
,
24722 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
24725 if (DECL_P (*node
))
24727 if (TREE_CODE (*node
) == TYPE_DECL
)
24728 type
= &TREE_TYPE (*node
);
24733 if (!(type
&& (TREE_CODE (*type
) == RECORD_TYPE
24734 || TREE_CODE (*type
) == UNION_TYPE
)))
24736 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
24737 *no_add_attrs
= true;
24740 else if ((is_attribute_p ("ms_struct", name
)
24741 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type
)))
24742 || ((is_attribute_p ("gcc_struct", name
)
24743 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type
)))))
24745 warning (OPT_Wattributes
, "%qE incompatible attribute ignored",
24747 *no_add_attrs
= true;
24754 rs6000_ms_bitfield_layout_p (const_tree record_type
)
24756 return (TARGET_USE_MS_BITFIELD_LAYOUT
&&
24757 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type
)))
24758 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type
));
24761 #ifdef USING_ELFOS_H
24763 /* A get_unnamed_section callback, used for switching to toc_section. */
24766 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
24768 if (DEFAULT_ABI
== ABI_AIX
24769 && TARGET_MINIMAL_TOC
24770 && !TARGET_RELOCATABLE
)
24772 if (!toc_initialized
)
24774 toc_initialized
= 1;
24775 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
24776 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LCTOC", 0);
24777 fprintf (asm_out_file
, "\t.tc ");
24778 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1[TC],");
24779 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
24780 fprintf (asm_out_file
, "\n");
24782 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
24783 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
24784 fprintf (asm_out_file
, " = .+32768\n");
24787 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
24789 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_RELOCATABLE
)
24790 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
24793 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
24794 if (!toc_initialized
)
24796 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
24797 fprintf (asm_out_file
, " = .+32768\n");
24798 toc_initialized
= 1;
24803 /* Implement TARGET_ASM_INIT_SECTIONS. */
24806 rs6000_elf_asm_init_sections (void)
24809 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op
, NULL
);
24812 = get_unnamed_section (SECTION_WRITE
, output_section_asm_op
,
24813 SDATA2_SECTION_ASM_OP
);
24816 /* Implement TARGET_SELECT_RTX_SECTION. */
24819 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
24820 unsigned HOST_WIDE_INT align
)
24822 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
24823 return toc_section
;
24825 return default_elf_select_rtx_section (mode
, x
, align
);
24828 /* For a SYMBOL_REF, set generic flags and then perform some
24829 target-specific processing.
24831 When the AIX ABI is requested on a non-AIX system, replace the
24832 function name with the real name (with a leading .) rather than the
24833 function descriptor name. This saves a lot of overriding code to
24834 read the prefixes. */
24837 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
24839 default_encode_section_info (decl
, rtl
, first
);
24842 && TREE_CODE (decl
) == FUNCTION_DECL
24844 && DEFAULT_ABI
== ABI_AIX
)
24846 rtx sym_ref
= XEXP (rtl
, 0);
24847 size_t len
= strlen (XSTR (sym_ref
, 0));
24848 char *str
= XALLOCAVEC (char, len
+ 2);
24850 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
24851 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
24856 compare_section_name (const char *section
, const char *templ
)
24860 len
= strlen (templ
);
24861 return (strncmp (section
, templ
, len
) == 0
24862 && (section
[len
] == 0 || section
[len
] == '.'));
24866 rs6000_elf_in_small_data_p (const_tree decl
)
24868 if (rs6000_sdata
== SDATA_NONE
)
24871 /* We want to merge strings, so we never consider them small data. */
24872 if (TREE_CODE (decl
) == STRING_CST
)
24875 /* Functions are never in the small data area. */
24876 if (TREE_CODE (decl
) == FUNCTION_DECL
)
24879 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
24881 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
24882 if (compare_section_name (section
, ".sdata")
24883 || compare_section_name (section
, ".sdata2")
24884 || compare_section_name (section
, ".gnu.linkonce.s")
24885 || compare_section_name (section
, ".sbss")
24886 || compare_section_name (section
, ".sbss2")
24887 || compare_section_name (section
, ".gnu.linkonce.sb")
24888 || strcmp (section
, ".PPC.EMB.sdata0") == 0
24889 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
24894 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
24897 && size
<= g_switch_value
24898 /* If it's not public, and we're not going to reference it there,
24899 there's no need to put it in the small data section. */
24900 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
24907 #endif /* USING_ELFOS_H */
24909 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24912 rs6000_use_blocks_for_constant_p (enum machine_mode mode
, const_rtx x
)
24914 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
);
24917 /* Return a REG that occurs in ADDR with coefficient 1.
24918 ADDR can be effectively incremented by incrementing REG.
24920 r0 is special and we must not select it as an address
24921 register by this routine since our caller will try to
24922 increment the returned register via an "la" instruction. */
24925 find_addr_reg (rtx addr
)
24927 while (GET_CODE (addr
) == PLUS
)
24929 if (GET_CODE (XEXP (addr
, 0)) == REG
24930 && REGNO (XEXP (addr
, 0)) != 0)
24931 addr
= XEXP (addr
, 0);
24932 else if (GET_CODE (XEXP (addr
, 1)) == REG
24933 && REGNO (XEXP (addr
, 1)) != 0)
24934 addr
= XEXP (addr
, 1);
24935 else if (CONSTANT_P (XEXP (addr
, 0)))
24936 addr
= XEXP (addr
, 1);
24937 else if (CONSTANT_P (XEXP (addr
, 1)))
24938 addr
= XEXP (addr
, 0);
24940 gcc_unreachable ();
24942 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
24947 rs6000_fatal_bad_address (rtx op
)
24949 fatal_insn ("bad address", op
);
24954 typedef struct branch_island_d
{
24955 tree function_name
;
24960 DEF_VEC_O(branch_island
);
24961 DEF_VEC_ALLOC_O(branch_island
,gc
);
24963 static VEC(branch_island
,gc
) *branch_islands
;
24965 /* Remember to generate a branch island for far calls to the given
24969 add_compiler_branch_island (tree label_name
, tree function_name
,
24972 branch_island
*bi
= VEC_safe_push (branch_island
, gc
, branch_islands
, NULL
);
24974 bi
->function_name
= function_name
;
24975 bi
->label_name
= label_name
;
24976 bi
->line_number
= line_number
;
24979 /* Generate far-jump branch islands for everything recorded in
24980 branch_islands. Invoked immediately after the last instruction of
24981 the epilogue has been emitted; the branch islands must be appended
24982 to, and contiguous with, the function body. Mach-O stubs are
24983 generated in machopic_output_stub(). */
24986 macho_branch_islands (void)
24990 while (!VEC_empty (branch_island
, branch_islands
))
24992 branch_island
*bi
= VEC_last (branch_island
, branch_islands
);
24993 const char *label
= IDENTIFIER_POINTER (bi
->label_name
);
24994 const char *name
= IDENTIFIER_POINTER (bi
->function_name
);
24995 char name_buf
[512];
24996 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24997 if (name
[0] == '*' || name
[0] == '&')
24998 strcpy (name_buf
, name
+1);
25002 strcpy (name_buf
+1, name
);
25004 strcpy (tmp_buf
, "\n");
25005 strcat (tmp_buf
, label
);
25006 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25007 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
25008 dbxout_stabd (N_SLINE
, bi
->line_number
);
25009 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25012 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
25013 strcat (tmp_buf
, label
);
25014 strcat (tmp_buf
, "_pic\n");
25015 strcat (tmp_buf
, label
);
25016 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
25018 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
25019 strcat (tmp_buf
, name_buf
);
25020 strcat (tmp_buf
, " - ");
25021 strcat (tmp_buf
, label
);
25022 strcat (tmp_buf
, "_pic)\n");
25024 strcat (tmp_buf
, "\tmtlr r0\n");
25026 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
25027 strcat (tmp_buf
, name_buf
);
25028 strcat (tmp_buf
, " - ");
25029 strcat (tmp_buf
, label
);
25030 strcat (tmp_buf
, "_pic)\n");
25032 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
25036 strcat (tmp_buf
, ":\nlis r12,hi16(");
25037 strcat (tmp_buf
, name_buf
);
25038 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
25039 strcat (tmp_buf
, name_buf
);
25040 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
25042 output_asm_insn (tmp_buf
, 0);
25043 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25044 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
25045 dbxout_stabd (N_SLINE
, bi
->line_number
);
25046 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25047 VEC_pop (branch_island
, branch_islands
);
25051 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25052 already there or not. */
25055 no_previous_def (tree function_name
)
25060 FOR_EACH_VEC_ELT (branch_island
, branch_islands
, ix
, bi
)
25061 if (function_name
== bi
->function_name
)
25066 /* GET_PREV_LABEL gets the label name from the previous definition of
25070 get_prev_label (tree function_name
)
25075 FOR_EACH_VEC_ELT (branch_island
, branch_islands
, ix
, bi
)
25076 if (function_name
== bi
->function_name
)
25077 return bi
->label_name
;
25081 /* INSN is either a function call or a millicode call. It may have an
25082 unconditional jump in its delay slot.
25084 CALL_DEST is the routine we are calling. */
25087 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
25088 int cookie_operand_number
)
25090 static char buf
[256];
25091 if (darwin_emit_branch_islands
25092 && GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
25093 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
25096 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
25098 if (no_previous_def (funname
))
25100 rtx label_rtx
= gen_label_rtx ();
25101 char *label_buf
, temp_buf
[256];
25102 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
25103 CODE_LABEL_NUMBER (label_rtx
));
25104 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
25105 labelname
= get_identifier (label_buf
);
25106 add_compiler_branch_island (labelname
, funname
, insn_line (insn
));
25109 labelname
= get_prev_label (funname
);
25111 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25112 instruction will reach 'foo', otherwise link as 'bl L42'".
25113 "L42" should be a 'branch island', that will do a far jump to
25114 'foo'. Branch islands are generated in
25115 macho_branch_islands(). */
25116 sprintf (buf
, "jbsr %%z%d,%.246s",
25117 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
25120 sprintf (buf
, "bl %%z%d", dest_operand_number
);
25124 /* Generate PIC and indirect symbol stubs. */
25127 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
25129 unsigned int length
;
25130 char *symbol_name
, *lazy_ptr_name
;
25131 char *local_label_0
;
25132 static int label
= 0;
25134 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25135 symb
= (*targetm
.strip_name_encoding
) (symb
);
25138 length
= strlen (symb
);
25139 symbol_name
= XALLOCAVEC (char, length
+ 32);
25140 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
25142 lazy_ptr_name
= XALLOCAVEC (char, length
+ 32);
25143 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
25146 switch_to_section (darwin_sections
[machopic_picsymbol_stub1_section
]);
25148 switch_to_section (darwin_sections
[machopic_symbol_stub1_section
]);
25152 fprintf (file
, "\t.align 5\n");
25154 fprintf (file
, "%s:\n", stub
);
25155 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25158 local_label_0
= XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25159 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
25161 fprintf (file
, "\tmflr r0\n");
25162 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
25163 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
25164 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
25165 lazy_ptr_name
, local_label_0
);
25166 fprintf (file
, "\tmtlr r0\n");
25167 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
25168 (TARGET_64BIT
? "ldu" : "lwzu"),
25169 lazy_ptr_name
, local_label_0
);
25170 fprintf (file
, "\tmtctr r12\n");
25171 fprintf (file
, "\tbctr\n");
25175 fprintf (file
, "\t.align 4\n");
25177 fprintf (file
, "%s:\n", stub
);
25178 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25180 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
25181 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
25182 (TARGET_64BIT
? "ldu" : "lwzu"),
25184 fprintf (file
, "\tmtctr r12\n");
25185 fprintf (file
, "\tbctr\n");
25188 switch_to_section (darwin_sections
[machopic_lazy_symbol_ptr_section
]);
25189 fprintf (file
, "%s:\n", lazy_ptr_name
);
25190 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
25191 fprintf (file
, "%sdyld_stub_binding_helper\n",
25192 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
25195 /* Legitimize PIC addresses. If the address is already
25196 position-independent, we return ORIG. Newly generated
25197 position-independent addresses go into a reg. This is REG if non
25198 zero, otherwise we allocate register(s) as necessary. */
25200 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25203 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
25208 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
25209 reg
= gen_reg_rtx (Pmode
);
25211 if (GET_CODE (orig
) == CONST
)
25215 if (GET_CODE (XEXP (orig
, 0)) == PLUS
25216 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
25219 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
25221 /* Use a different reg for the intermediate value, as
25222 it will be marked UNCHANGING. */
25223 reg_temp
= !can_create_pseudo_p () ? reg
: gen_reg_rtx (Pmode
);
25224 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
25227 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
25230 if (GET_CODE (offset
) == CONST_INT
)
25232 if (SMALL_INT (offset
))
25233 return plus_constant (base
, INTVAL (offset
));
25234 else if (! reload_in_progress
&& ! reload_completed
)
25235 offset
= force_reg (Pmode
, offset
);
25238 rtx mem
= force_const_mem (Pmode
, orig
);
25239 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
25242 return gen_rtx_PLUS (Pmode
, base
, offset
);
25245 /* Fall back on generic machopic code. */
25246 return machopic_legitimize_pic_address (orig
, mode
, reg
);
25249 /* Output a .machine directive for the Darwin assembler, and call
25250 the generic start_file routine. */
25253 rs6000_darwin_file_start (void)
25255 static const struct
25261 { "ppc64", "ppc64", MASK_64BIT
},
25262 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
25263 { "power4", "ppc970", 0 },
25264 { "G5", "ppc970", 0 },
25265 { "7450", "ppc7450", 0 },
25266 { "7400", "ppc7400", MASK_ALTIVEC
},
25267 { "G4", "ppc7400", 0 },
25268 { "750", "ppc750", 0 },
25269 { "740", "ppc750", 0 },
25270 { "G3", "ppc750", 0 },
25271 { "604e", "ppc604e", 0 },
25272 { "604", "ppc604", 0 },
25273 { "603e", "ppc603", 0 },
25274 { "603", "ppc603", 0 },
25275 { "601", "ppc601", 0 },
25276 { NULL
, "ppc", 0 } };
25277 const char *cpu_id
= "";
25280 rs6000_file_start ();
25281 darwin_file_start ();
25283 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25284 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
25285 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
25286 && rs6000_select
[i
].string
[0] != '\0')
25287 cpu_id
= rs6000_select
[i
].string
;
25289 /* Look through the mapping array. Pick the first name that either
25290 matches the argument, has a bit set in IF_SET that is also set
25291 in the target flags, or has a NULL name. */
25294 while (mapping
[i
].arg
!= NULL
25295 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
25296 && (mapping
[i
].if_set
& target_flags
) == 0)
25299 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
25302 #endif /* TARGET_MACHO */
25306 rs6000_elf_reloc_rw_mask (void)
25310 else if (DEFAULT_ABI
== ABI_AIX
)
25316 /* Record an element in the table of global constructors. SYMBOL is
25317 a SYMBOL_REF of the function to be called; PRIORITY is a number
25318 between 0 and MAX_INIT_PRIORITY.
25320 This differs from default_named_section_asm_out_constructor in
25321 that we have special handling for -mrelocatable. */
25324 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
25326 const char *section
= ".ctors";
25329 if (priority
!= DEFAULT_INIT_PRIORITY
)
25331 sprintf (buf
, ".ctors.%.5u",
25332 /* Invert the numbering so the linker puts us in the proper
25333 order; constructors are run from right to left, and the
25334 linker sorts in increasing order. */
25335 MAX_INIT_PRIORITY
- priority
);
25339 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
25340 assemble_align (POINTER_SIZE
);
25342 if (TARGET_RELOCATABLE
)
25344 fputs ("\t.long (", asm_out_file
);
25345 output_addr_const (asm_out_file
, symbol
);
25346 fputs (")@fixup\n", asm_out_file
);
25349 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
25353 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
25355 const char *section
= ".dtors";
25358 if (priority
!= DEFAULT_INIT_PRIORITY
)
25360 sprintf (buf
, ".dtors.%.5u",
25361 /* Invert the numbering so the linker puts us in the proper
25362 order; constructors are run from right to left, and the
25363 linker sorts in increasing order. */
25364 MAX_INIT_PRIORITY
- priority
);
25368 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
25369 assemble_align (POINTER_SIZE
);
25371 if (TARGET_RELOCATABLE
)
25373 fputs ("\t.long (", asm_out_file
);
25374 output_addr_const (asm_out_file
, symbol
);
25375 fputs (")@fixup\n", asm_out_file
);
25378 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
25382 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
25386 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
25387 ASM_OUTPUT_LABEL (file
, name
);
25388 fputs (DOUBLE_INT_ASM_OP
, file
);
25389 rs6000_output_function_entry (file
, name
);
25390 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
25393 fputs ("\t.size\t", file
);
25394 assemble_name (file
, name
);
25395 fputs (",24\n\t.type\t.", file
);
25396 assemble_name (file
, name
);
25397 fputs (",@function\n", file
);
25398 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
25400 fputs ("\t.globl\t.", file
);
25401 assemble_name (file
, name
);
25406 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
25407 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
25408 rs6000_output_function_entry (file
, name
);
25409 fputs (":\n", file
);
25413 if (TARGET_RELOCATABLE
25414 && !TARGET_SECURE_PLT
25415 && (get_pool_size () != 0 || crtl
->profile
)
25420 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
25422 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
25423 fprintf (file
, "\t.long ");
25424 assemble_name (file
, buf
);
25426 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
25427 assemble_name (file
, buf
);
25431 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
25432 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
25434 if (DEFAULT_ABI
== ABI_AIX
)
25436 const char *desc_name
, *orig_name
;
25438 orig_name
= (*targetm
.strip_name_encoding
) (name
);
25439 desc_name
= orig_name
;
25440 while (*desc_name
== '.')
25443 if (TREE_PUBLIC (decl
))
25444 fprintf (file
, "\t.globl %s\n", desc_name
);
25446 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
25447 fprintf (file
, "%s:\n", desc_name
);
25448 fprintf (file
, "\t.long %s\n", orig_name
);
25449 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
25450 if (DEFAULT_ABI
== ABI_AIX
)
25451 fputs ("\t.long 0\n", file
);
25452 fprintf (file
, "\t.previous\n");
25454 ASM_OUTPUT_LABEL (file
, name
);
25458 rs6000_elf_end_indicate_exec_stack (void)
25461 file_end_indicate_exec_stack ();
25467 rs6000_xcoff_asm_output_anchor (rtx symbol
)
25471 sprintf (buffer
, "$ + " HOST_WIDE_INT_PRINT_DEC
,
25472 SYMBOL_REF_BLOCK_OFFSET (symbol
));
25473 ASM_OUTPUT_DEF (asm_out_file
, XSTR (symbol
, 0), buffer
);
25477 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
25479 fputs (GLOBAL_ASM_OP
, stream
);
25480 RS6000_OUTPUT_BASENAME (stream
, name
);
25481 putc ('\n', stream
);
25484 /* A get_unnamed_decl callback, used for read-only sections. PTR
25485 points to the section string variable. */
25488 rs6000_xcoff_output_readonly_section_asm_op (const void *directive
)
25490 fprintf (asm_out_file
, "\t.csect %s[RO],%s\n",
25491 *(const char *const *) directive
,
25492 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
25495 /* Likewise for read-write sections. */
25498 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive
)
25500 fprintf (asm_out_file
, "\t.csect %s[RW],%s\n",
25501 *(const char *const *) directive
,
25502 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
25505 /* A get_unnamed_section callback, used for switching to toc_section. */
25508 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
25510 if (TARGET_MINIMAL_TOC
)
25512 /* toc_section is always selected at least once from
25513 rs6000_xcoff_file_start, so this is guaranteed to
25514 always be defined once and only once in each file. */
25515 if (!toc_initialized
)
25517 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file
);
25518 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file
);
25519 toc_initialized
= 1;
25521 fprintf (asm_out_file
, "\t.csect toc_table[RW]%s\n",
25522 (TARGET_32BIT
? "" : ",3"));
25525 fputs ("\t.toc\n", asm_out_file
);
25528 /* Implement TARGET_ASM_INIT_SECTIONS. */
25531 rs6000_xcoff_asm_init_sections (void)
25533 read_only_data_section
25534 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
25535 &xcoff_read_only_section_name
);
25537 private_data_section
25538 = get_unnamed_section (SECTION_WRITE
,
25539 rs6000_xcoff_output_readwrite_section_asm_op
,
25540 &xcoff_private_data_section_name
);
25542 read_only_private_data_section
25543 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
25544 &xcoff_private_data_section_name
);
25547 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op
, NULL
);
25549 readonly_data_section
= read_only_data_section
;
25550 exception_section
= data_section
;
25554 rs6000_xcoff_reloc_rw_mask (void)
25560 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
25561 tree decl ATTRIBUTE_UNUSED
)
25564 static const char * const suffix
[3] = { "PR", "RO", "RW" };
25566 if (flags
& SECTION_CODE
)
25568 else if (flags
& SECTION_WRITE
)
25573 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
25574 (flags
& SECTION_CODE
) ? "." : "",
25575 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
25579 rs6000_xcoff_select_section (tree decl
, int reloc
,
25580 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
25582 if (decl_readonly_section (decl
, reloc
))
25584 if (TREE_PUBLIC (decl
))
25585 return read_only_data_section
;
25587 return read_only_private_data_section
;
25591 if (TREE_PUBLIC (decl
))
25592 return data_section
;
25594 return private_data_section
;
25599 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
25603 /* Use select_section for private and uninitialized data. */
25604 if (!TREE_PUBLIC (decl
)
25605 || DECL_COMMON (decl
)
25606 || DECL_INITIAL (decl
) == NULL_TREE
25607 || DECL_INITIAL (decl
) == error_mark_node
25608 || (flag_zero_initialized_in_bss
25609 && initializer_zerop (DECL_INITIAL (decl
))))
25612 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
25613 name
= (*targetm
.strip_name_encoding
) (name
);
25614 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
25617 /* Select section for constant in constant pool.
25619 On RS/6000, all constants are in the private read-only data area.
25620 However, if this is being placed in the TOC it must be output as a
25624 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
25625 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
25627 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
25628 return toc_section
;
25630 return read_only_private_data_section
;
25633 /* Remove any trailing [DS] or the like from the symbol name. */
25635 static const char *
25636 rs6000_xcoff_strip_name_encoding (const char *name
)
25641 len
= strlen (name
);
25642 if (name
[len
- 1] == ']')
25643 return ggc_alloc_string (name
, len
- 4);
25648 /* Section attributes. AIX is always PIC. */
25650 static unsigned int
25651 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
25653 unsigned int align
;
25654 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
25656 /* Align to at least UNIT size. */
25657 if (flags
& SECTION_CODE
)
25658 align
= MIN_UNITS_PER_WORD
;
25660 /* Increase alignment of large objects if not already stricter. */
25661 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
25662 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
25663 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
25665 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
25668 /* Output at beginning of assembler file.
25670 Initialize the section names for the RS/6000 at this point.
25672 Specify filename, including full path, to assembler.
25674 We want to go into the TOC section so at least one .toc will be emitted.
25675 Also, in order to output proper .bs/.es pairs, we need at least one static
25676 [RW] section emitted.
25678 Finally, declare mcount when profiling to make the assembler happy. */
25681 rs6000_xcoff_file_start (void)
25683 rs6000_gen_section_name (&xcoff_bss_section_name
,
25684 main_input_filename
, ".bss_");
25685 rs6000_gen_section_name (&xcoff_private_data_section_name
,
25686 main_input_filename
, ".rw_");
25687 rs6000_gen_section_name (&xcoff_read_only_section_name
,
25688 main_input_filename
, ".ro_");
25690 fputs ("\t.file\t", asm_out_file
);
25691 output_quoted_string (asm_out_file
, main_input_filename
);
25692 fputc ('\n', asm_out_file
);
25693 if (write_symbols
!= NO_DEBUG
)
25694 switch_to_section (private_data_section
);
25695 switch_to_section (text_section
);
25697 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
25698 rs6000_file_start ();
25701 /* Output at end of assembler file.
25702 On the RS/6000, referencing data should automatically pull in text. */
25705 rs6000_xcoff_file_end (void)
25707 switch_to_section (text_section
);
25708 fputs ("_section_.text:\n", asm_out_file
);
25709 switch_to_section (data_section
);
25710 fputs (TARGET_32BIT
25711 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25714 #endif /* TARGET_XCOFF */
25716 /* Compute a (partial) cost for rtx X. Return true if the complete
25717 cost has been computed, and false if subexpressions should be
25718 scanned. In either case, *TOTAL contains the cost result. */
25721 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
25724 enum machine_mode mode
= GET_MODE (x
);
25728 /* On the RS/6000, if it is valid in the insn, it is free. */
25730 if (((outer_code
== SET
25731 || outer_code
== PLUS
25732 || outer_code
== MINUS
)
25733 && (satisfies_constraint_I (x
)
25734 || satisfies_constraint_L (x
)))
25735 || (outer_code
== AND
25736 && (satisfies_constraint_K (x
)
25738 ? satisfies_constraint_L (x
)
25739 : satisfies_constraint_J (x
))
25740 || mask_operand (x
, mode
)
25742 && mask64_operand (x
, DImode
))))
25743 || ((outer_code
== IOR
|| outer_code
== XOR
)
25744 && (satisfies_constraint_K (x
)
25746 ? satisfies_constraint_L (x
)
25747 : satisfies_constraint_J (x
))))
25748 || outer_code
== ASHIFT
25749 || outer_code
== ASHIFTRT
25750 || outer_code
== LSHIFTRT
25751 || outer_code
== ROTATE
25752 || outer_code
== ROTATERT
25753 || outer_code
== ZERO_EXTRACT
25754 || (outer_code
== MULT
25755 && satisfies_constraint_I (x
))
25756 || ((outer_code
== DIV
|| outer_code
== UDIV
25757 || outer_code
== MOD
|| outer_code
== UMOD
)
25758 && exact_log2 (INTVAL (x
)) >= 0)
25759 || (outer_code
== COMPARE
25760 && (satisfies_constraint_I (x
)
25761 || satisfies_constraint_K (x
)))
25762 || ((outer_code
== EQ
|| outer_code
== NE
)
25763 && (satisfies_constraint_I (x
)
25764 || satisfies_constraint_K (x
)
25766 ? satisfies_constraint_L (x
)
25767 : satisfies_constraint_J (x
))))
25768 || (outer_code
== GTU
25769 && satisfies_constraint_I (x
))
25770 || (outer_code
== LTU
25771 && satisfies_constraint_P (x
)))
25776 else if ((outer_code
== PLUS
25777 && reg_or_add_cint_operand (x
, VOIDmode
))
25778 || (outer_code
== MINUS
25779 && reg_or_sub_cint_operand (x
, VOIDmode
))
25780 || ((outer_code
== SET
25781 || outer_code
== IOR
25782 || outer_code
== XOR
)
25784 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
25786 *total
= COSTS_N_INSNS (1);
25792 if (mode
== DImode
&& code
== CONST_DOUBLE
)
25794 if ((outer_code
== IOR
|| outer_code
== XOR
)
25795 && CONST_DOUBLE_HIGH (x
) == 0
25796 && (CONST_DOUBLE_LOW (x
)
25797 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)
25802 else if ((outer_code
== AND
&& and64_2_operand (x
, DImode
))
25803 || ((outer_code
== SET
25804 || outer_code
== IOR
25805 || outer_code
== XOR
)
25806 && CONST_DOUBLE_HIGH (x
) == 0))
25808 *total
= COSTS_N_INSNS (1);
25818 /* When optimizing for size, MEM should be slightly more expensive
25819 than generating address, e.g., (plus (reg) (const)).
25820 L1 cache latency is about two instructions. */
25821 *total
= !speed
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25829 if (mode
== DFmode
)
25831 if (GET_CODE (XEXP (x
, 0)) == MULT
)
25833 /* FNMA accounted in outer NEG. */
25834 if (outer_code
== NEG
)
25835 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
25837 *total
= rs6000_cost
->dmul
;
25840 *total
= rs6000_cost
->fp
;
25842 else if (mode
== SFmode
)
25844 /* FNMA accounted in outer NEG. */
25845 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
25848 *total
= rs6000_cost
->fp
;
25851 *total
= COSTS_N_INSNS (1);
25855 if (mode
== DFmode
)
25857 if (GET_CODE (XEXP (x
, 0)) == MULT
25858 || GET_CODE (XEXP (x
, 1)) == MULT
)
25860 /* FNMA accounted in outer NEG. */
25861 if (outer_code
== NEG
)
25862 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
25864 *total
= rs6000_cost
->dmul
;
25867 *total
= rs6000_cost
->fp
;
25869 else if (mode
== SFmode
)
25871 /* FNMA accounted in outer NEG. */
25872 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
25875 *total
= rs6000_cost
->fp
;
25878 *total
= COSTS_N_INSNS (1);
25882 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
25883 && satisfies_constraint_I (XEXP (x
, 1)))
25885 if (INTVAL (XEXP (x
, 1)) >= -256
25886 && INTVAL (XEXP (x
, 1)) <= 255)
25887 *total
= rs6000_cost
->mulsi_const9
;
25889 *total
= rs6000_cost
->mulsi_const
;
25891 /* FMA accounted in outer PLUS/MINUS. */
25892 else if ((mode
== DFmode
|| mode
== SFmode
)
25893 && (outer_code
== PLUS
|| outer_code
== MINUS
))
25895 else if (mode
== DFmode
)
25896 *total
= rs6000_cost
->dmul
;
25897 else if (mode
== SFmode
)
25898 *total
= rs6000_cost
->fp
;
25899 else if (mode
== DImode
)
25900 *total
= rs6000_cost
->muldi
;
25902 *total
= rs6000_cost
->mulsi
;
25907 if (FLOAT_MODE_P (mode
))
25909 *total
= mode
== DFmode
? rs6000_cost
->ddiv
25910 : rs6000_cost
->sdiv
;
25917 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
25918 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
25920 if (code
== DIV
|| code
== MOD
)
25922 *total
= COSTS_N_INSNS (2);
25925 *total
= COSTS_N_INSNS (1);
25929 if (GET_MODE (XEXP (x
, 1)) == DImode
)
25930 *total
= rs6000_cost
->divdi
;
25932 *total
= rs6000_cost
->divsi
;
25934 /* Add in shift and subtract for MOD. */
25935 if (code
== MOD
|| code
== UMOD
)
25936 *total
+= COSTS_N_INSNS (2);
25941 *total
= COSTS_N_INSNS (4);
25945 *total
= COSTS_N_INSNS (TARGET_POPCNTD
? 1 : 6);
25949 *total
= COSTS_N_INSNS (TARGET_CMPB
? 2 : 6);
25953 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
25965 *total
= COSTS_N_INSNS (1);
25973 /* Handle mul_highpart. */
25974 if (outer_code
== TRUNCATE
25975 && GET_CODE (XEXP (x
, 0)) == MULT
)
25977 if (mode
== DImode
)
25978 *total
= rs6000_cost
->muldi
;
25980 *total
= rs6000_cost
->mulsi
;
25983 else if (outer_code
== AND
)
25986 *total
= COSTS_N_INSNS (1);
25991 if (GET_CODE (XEXP (x
, 0)) == MEM
)
25994 *total
= COSTS_N_INSNS (1);
26000 if (!FLOAT_MODE_P (mode
))
26002 *total
= COSTS_N_INSNS (1);
26008 case UNSIGNED_FLOAT
:
26011 case FLOAT_TRUNCATE
:
26012 *total
= rs6000_cost
->fp
;
26016 if (mode
== DFmode
)
26019 *total
= rs6000_cost
->fp
;
26023 switch (XINT (x
, 1))
26026 *total
= rs6000_cost
->fp
;
26038 *total
= COSTS_N_INSNS (1);
26041 else if (FLOAT_MODE_P (mode
)
26042 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
26044 *total
= rs6000_cost
->fp
;
26052 /* Carry bit requires mode == Pmode.
26053 NEG or PLUS already counted so only add one. */
26055 && (outer_code
== NEG
|| outer_code
== PLUS
))
26057 *total
= COSTS_N_INSNS (1);
26060 if (outer_code
== SET
)
26062 if (XEXP (x
, 1) == const0_rtx
)
26064 if (TARGET_ISEL
&& !TARGET_MFCRF
)
26065 *total
= COSTS_N_INSNS (8);
26067 *total
= COSTS_N_INSNS (2);
26070 else if (mode
== Pmode
)
26072 *total
= COSTS_N_INSNS (3);
26081 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
26083 if (TARGET_ISEL
&& !TARGET_MFCRF
)
26084 *total
= COSTS_N_INSNS (8);
26086 *total
= COSTS_N_INSNS (2);
26090 if (outer_code
== COMPARE
)
26104 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26107 rs6000_debug_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
26110 bool ret
= rs6000_rtx_costs (x
, code
, outer_code
, total
, speed
);
26113 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26114 "total = %d, speed = %s, x:\n",
26115 ret
? "complete" : "scan inner",
26116 GET_RTX_NAME (code
),
26117 GET_RTX_NAME (outer_code
),
26119 speed
? "true" : "false");
26126 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26129 rs6000_debug_address_cost (rtx x
, bool speed
)
26131 int ret
= TARGET_ADDRESS_COST (x
, speed
);
26133 fprintf (stderr
, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26134 ret
, speed
? "true" : "false");
26141 /* A C expression returning the cost of moving data from a register of class
26142 CLASS1 to one of CLASS2. */
26145 rs6000_register_move_cost (enum machine_mode mode
,
26146 reg_class_t from
, reg_class_t to
)
26150 /* Moves from/to GENERAL_REGS. */
26151 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
26152 || reg_classes_intersect_p (from
, GENERAL_REGS
))
26154 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
26157 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
|| from
== VSX_REGS
)
26158 ret
= (rs6000_memory_move_cost (mode
, from
, false)
26159 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, false));
26161 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26163 else if (from
== CR_REGS
)
26166 /* Power6 has slower LR/CTR moves so make them more expensive than
26167 memory in order to bias spills to memory .*/
26168 else if (rs6000_cpu
== PROCESSOR_POWER6
26169 && reg_classes_intersect_p (from
, LINK_OR_CTR_REGS
))
26170 ret
= 6 * hard_regno_nregs
[0][mode
];
26173 /* A move will cost one instruction per GPR moved. */
26174 ret
= 2 * hard_regno_nregs
[0][mode
];
26177 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26178 else if (VECTOR_UNIT_VSX_P (mode
)
26179 && reg_classes_intersect_p (to
, VSX_REGS
)
26180 && reg_classes_intersect_p (from
, VSX_REGS
))
26181 ret
= 2 * hard_regno_nregs
[32][mode
];
26183 /* Moving between two similar registers is just one instruction. */
26184 else if (reg_classes_intersect_p (to
, from
))
26185 ret
= (mode
== TFmode
|| mode
== TDmode
) ? 4 : 2;
26187 /* Everything else has to go through GENERAL_REGS. */
26189 ret
= (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
26190 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
26192 if (TARGET_DEBUG_COST
)
26194 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26195 ret
, GET_MODE_NAME (mode
), reg_class_names
[from
],
26196 reg_class_names
[to
]);
26201 /* A C expressions returning the cost of moving data of MODE from a register to
26205 rs6000_memory_move_cost (enum machine_mode mode
, reg_class_t rclass
,
26206 bool in ATTRIBUTE_UNUSED
)
26210 if (reg_classes_intersect_p (rclass
, GENERAL_REGS
))
26211 ret
= 4 * hard_regno_nregs
[0][mode
];
26212 else if (reg_classes_intersect_p (rclass
, FLOAT_REGS
))
26213 ret
= 4 * hard_regno_nregs
[32][mode
];
26214 else if (reg_classes_intersect_p (rclass
, ALTIVEC_REGS
))
26215 ret
= 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
26217 ret
= 4 + rs6000_register_move_cost (mode
, rclass
, GENERAL_REGS
);
26219 if (TARGET_DEBUG_COST
)
26221 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26222 ret
, GET_MODE_NAME (mode
), reg_class_names
[rclass
], in
);
26227 /* Returns a code for a target-specific builtin that implements
26228 reciprocal of the function, or NULL_TREE if not available. */
26231 rs6000_builtin_reciprocal (unsigned int fn
, bool md_fn
,
26232 bool sqrt ATTRIBUTE_UNUSED
)
26234 if (optimize_insn_for_size_p ())
26240 case VSX_BUILTIN_XVSQRTDP
:
26241 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode
))
26244 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V2DF
];
26246 case VSX_BUILTIN_XVSQRTSP
:
26247 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode
))
26250 return rs6000_builtin_decls
[VSX_BUILTIN_VEC_RSQRT_V4SF
];
26259 case BUILT_IN_SQRT
:
26260 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode
))
26263 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRT
];
26265 case BUILT_IN_SQRTF
:
26266 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode
))
26269 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRTF
];
26276 /* Load up a constant. If the mode is a vector mode, splat the value across
26277 all of the vector elements. */
26280 rs6000_load_constant_and_splat (enum machine_mode mode
, REAL_VALUE_TYPE dconst
)
26284 if (mode
== SFmode
|| mode
== DFmode
)
26286 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, mode
);
26287 reg
= force_reg (mode
, d
);
26289 else if (mode
== V4SFmode
)
26291 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, SFmode
);
26292 rtvec v
= gen_rtvec (4, d
, d
, d
, d
);
26293 reg
= gen_reg_rtx (mode
);
26294 rs6000_expand_vector_init (reg
, gen_rtx_PARALLEL (mode
, v
));
26296 else if (mode
== V2DFmode
)
26298 rtx d
= CONST_DOUBLE_FROM_REAL_VALUE (dconst
, DFmode
);
26299 rtvec v
= gen_rtvec (2, d
, d
);
26300 reg
= gen_reg_rtx (mode
);
26301 rs6000_expand_vector_init (reg
, gen_rtx_PARALLEL (mode
, v
));
26304 gcc_unreachable ();
26309 /* Generate a FMADD instruction:
26310 dst = (m1 * m2) + a
26312 generating different RTL based on the fused multiply/add switch. */
26315 rs6000_emit_madd (rtx dst
, rtx m1
, rtx m2
, rtx a
)
26317 enum machine_mode mode
= GET_MODE (dst
);
26319 if (!TARGET_FUSED_MADD
)
26321 /* For the simple ops, use the generator function, rather than assuming
26322 that the RTL is standard. */
26323 enum insn_code mcode
= optab_handler (smul_optab
, mode
);
26324 enum insn_code acode
= optab_handler (add_optab
, mode
);
26325 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (mcode
);
26326 gen_2arg_fn_t gen_add
= (gen_2arg_fn_t
) GEN_FCN (acode
);
26327 rtx mreg
= gen_reg_rtx (mode
);
26329 gcc_assert (mcode
!= CODE_FOR_nothing
&& acode
!= CODE_FOR_nothing
);
26330 emit_insn (gen_mul (mreg
, m1
, m2
));
26331 emit_insn (gen_add (dst
, mreg
, a
));
26335 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
26336 gen_rtx_PLUS (mode
,
26337 gen_rtx_MULT (mode
, m1
, m2
),
26341 /* Generate a FMSUB instruction:
26342 dst = (m1 * m2) - a
26344 generating different RTL based on the fused multiply/add switch. */
26347 rs6000_emit_msub (rtx dst
, rtx m1
, rtx m2
, rtx a
)
26349 enum machine_mode mode
= GET_MODE (dst
);
26351 if (!TARGET_FUSED_MADD
26352 || (mode
== V4SFmode
&& VECTOR_UNIT_ALTIVEC_P (V4SFmode
)))
26354 /* For the simple ops, use the generator function, rather than assuming
26355 that the RTL is standard. */
26356 enum insn_code mcode
= optab_handler (smul_optab
, mode
);
26357 enum insn_code scode
= optab_handler (add_optab
, mode
);
26358 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (mcode
);
26359 gen_2arg_fn_t gen_sub
= (gen_2arg_fn_t
) GEN_FCN (scode
);
26360 rtx mreg
= gen_reg_rtx (mode
);
26362 gcc_assert (mcode
!= CODE_FOR_nothing
&& scode
!= CODE_FOR_nothing
);
26363 emit_insn (gen_mul (mreg
, m1
, m2
));
26364 emit_insn (gen_sub (dst
, mreg
, a
));
26368 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
26369 gen_rtx_MINUS (mode
,
26370 gen_rtx_MULT (mode
, m1
, m2
),
26374 /* Generate a FNMSUB instruction:
26375 dst = - ((m1 * m2) - a)
26377 Which is equivalent to (except in the prescence of -0.0):
26378 dst = a - (m1 * m2)
26380 generating different RTL based on the fast-math and fused multiply/add
26384 rs6000_emit_nmsub (rtx dst
, rtx m1
, rtx m2
, rtx a
)
26386 enum machine_mode mode
= GET_MODE (dst
);
26388 if (!TARGET_FUSED_MADD
)
26390 /* For the simple ops, use the generator function, rather than assuming
26391 that the RTL is standard. */
26392 enum insn_code mcode
= optab_handler (smul_optab
, mode
);
26393 enum insn_code scode
= optab_handler (sub_optab
, mode
);
26394 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (mcode
);
26395 gen_2arg_fn_t gen_sub
= (gen_2arg_fn_t
) GEN_FCN (scode
);
26396 rtx mreg
= gen_reg_rtx (mode
);
26398 gcc_assert (mcode
!= CODE_FOR_nothing
&& scode
!= CODE_FOR_nothing
);
26399 emit_insn (gen_mul (mreg
, m1
, m2
));
26400 emit_insn (gen_sub (dst
, a
, mreg
));
26405 rtx m
= gen_rtx_MULT (mode
, m1
, m2
);
26407 if (!HONOR_SIGNED_ZEROS (mode
))
26408 emit_insn (gen_rtx_SET (VOIDmode
, dst
, gen_rtx_MINUS (mode
, a
, m
)));
26411 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
26413 gen_rtx_MINUS (mode
, m
, a
))));
26417 /* Newton-Raphson approximation of floating point divide with just 2 passes
26418 (either single precision floating point, or newer machines with higher
26419 accuracy estimates). Support both scalar and vector divide. Assumes no
26420 trapping math and finite arguments. */
26423 rs6000_emit_swdiv_high_precision (rtx dst
, rtx n
, rtx d
)
26425 enum machine_mode mode
= GET_MODE (dst
);
26426 rtx x0
, e0
, e1
, y1
, u0
, v0
;
26427 enum insn_code code
= optab_handler (smul_optab
, mode
);
26428 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
26429 rtx one
= rs6000_load_constant_and_splat (mode
, dconst1
);
26431 gcc_assert (code
!= CODE_FOR_nothing
);
26433 /* x0 = 1./d estimate */
26434 x0
= gen_reg_rtx (mode
);
26435 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
26436 gen_rtx_UNSPEC (mode
, gen_rtvec (1, d
),
26439 e0
= gen_reg_rtx (mode
);
26440 rs6000_emit_nmsub (e0
, d
, x0
, one
); /* e0 = 1. - (d * x0) */
26442 e1
= gen_reg_rtx (mode
);
26443 rs6000_emit_madd (e1
, e0
, e0
, e0
); /* e1 = (e0 * e0) + e0 */
26445 y1
= gen_reg_rtx (mode
);
26446 rs6000_emit_madd (y1
, e1
, x0
, x0
); /* y1 = (e1 * x0) + x0 */
26448 u0
= gen_reg_rtx (mode
);
26449 emit_insn (gen_mul (u0
, n
, y1
)); /* u0 = n * y1 */
26451 v0
= gen_reg_rtx (mode
);
26452 rs6000_emit_nmsub (v0
, d
, u0
, n
); /* v0 = n - (d * u0) */
26454 rs6000_emit_madd (dst
, v0
, y1
, u0
); /* dst = (v0 * y1) + u0 */
26457 /* Newton-Raphson approximation of floating point divide that has a low
26458 precision estimate. Assumes no trapping math and finite arguments. */
26461 rs6000_emit_swdiv_low_precision (rtx dst
, rtx n
, rtx d
)
26463 enum machine_mode mode
= GET_MODE (dst
);
26464 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
26465 enum insn_code code
= optab_handler (smul_optab
, mode
);
26466 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
26468 gcc_assert (code
!= CODE_FOR_nothing
);
26470 one
= rs6000_load_constant_and_splat (mode
, dconst1
);
26472 /* x0 = 1./d estimate */
26473 x0
= gen_reg_rtx (mode
);
26474 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
26475 gen_rtx_UNSPEC (mode
, gen_rtvec (1, d
),
26478 e0
= gen_reg_rtx (mode
);
26479 rs6000_emit_nmsub (e0
, d
, x0
, one
); /* e0 = 1. - d * x0 */
26481 y1
= gen_reg_rtx (mode
);
26482 rs6000_emit_madd (y1
, e0
, x0
, x0
); /* y1 = x0 + e0 * x0 */
26484 e1
= gen_reg_rtx (mode
);
26485 emit_insn (gen_mul (e1
, e0
, e0
)); /* e1 = e0 * e0 */
26487 y2
= gen_reg_rtx (mode
);
26488 rs6000_emit_madd (y2
, e1
, y1
, y1
); /* y2 = y1 + e1 * y1 */
26490 e2
= gen_reg_rtx (mode
);
26491 emit_insn (gen_mul (e2
, e1
, e1
)); /* e2 = e1 * e1 */
26493 y3
= gen_reg_rtx (mode
);
26494 rs6000_emit_madd (y3
, e2
, y2
, y2
); /* y3 = y2 + e2 * y2 */
26496 u0
= gen_reg_rtx (mode
);
26497 emit_insn (gen_mul (u0
, n
, y3
)); /* u0 = n * y3 */
26499 v0
= gen_reg_rtx (mode
);
26500 rs6000_emit_nmsub (v0
, d
, u0
, n
); /* v0 = n - d * u0 */
26502 rs6000_emit_madd (dst
, v0
, y3
, u0
); /* dst = u0 + v0 * y3 */
26505 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26506 add a reg_note saying that this was a division. Support both scalar and
26507 vector divide. Assumes no trapping math and finite arguments. */
26510 rs6000_emit_swdiv (rtx dst
, rtx n
, rtx d
, bool note_p
)
26512 enum machine_mode mode
= GET_MODE (dst
);
26514 if (RS6000_RECIP_HIGH_PRECISION_P (mode
))
26515 rs6000_emit_swdiv_high_precision (dst
, n
, d
);
26517 rs6000_emit_swdiv_low_precision (dst
, n
, d
);
26520 add_reg_note (get_last_insn (), REG_EQUAL
, gen_rtx_DIV (mode
, n
, d
));
26523 /* Newton-Raphson approximation of single/double-precision floating point
26524 rsqrt. Assumes no trapping math and finite arguments. */
26527 rs6000_emit_swrsqrt (rtx dst
, rtx src
)
26529 enum machine_mode mode
= GET_MODE (src
);
26530 rtx x0
= gen_reg_rtx (mode
);
26531 rtx y
= gen_reg_rtx (mode
);
26532 int passes
= (TARGET_RECIP_PRECISION
) ? 2 : 3;
26533 REAL_VALUE_TYPE dconst3_2
;
26536 enum insn_code code
= optab_handler (smul_optab
, mode
);
26537 gen_2arg_fn_t gen_mul
= (gen_2arg_fn_t
) GEN_FCN (code
);
26539 gcc_assert (code
!= CODE_FOR_nothing
);
26541 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26542 real_from_integer (&dconst3_2
, VOIDmode
, 3, 0, 0);
26543 SET_REAL_EXP (&dconst3_2
, REAL_EXP (&dconst3_2
) - 1);
26545 halfthree
= rs6000_load_constant_and_splat (mode
, dconst3_2
);
26547 /* x0 = rsqrt estimate */
26548 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
26549 gen_rtx_UNSPEC (mode
, gen_rtvec (1, src
),
26552 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26553 rs6000_emit_msub (y
, src
, halfthree
, src
);
26555 for (i
= 0; i
< passes
; i
++)
26557 rtx x1
= gen_reg_rtx (mode
);
26558 rtx u
= gen_reg_rtx (mode
);
26559 rtx v
= gen_reg_rtx (mode
);
26561 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26562 emit_insn (gen_mul (u
, x0
, x0
));
26563 rs6000_emit_nmsub (v
, y
, u
, halfthree
);
26564 emit_insn (gen_mul (x1
, x0
, v
));
26568 emit_move_insn (dst
, x0
);
26572 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26573 (Power7) targets. DST is the target, and SRC is the argument operand. */
26576 rs6000_emit_popcount (rtx dst
, rtx src
)
26578 enum machine_mode mode
= GET_MODE (dst
);
26581 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26582 if (TARGET_POPCNTD
)
26584 if (mode
== SImode
)
26585 emit_insn (gen_popcntdsi2 (dst
, src
));
26587 emit_insn (gen_popcntddi2 (dst
, src
));
26591 tmp1
= gen_reg_rtx (mode
);
26593 if (mode
== SImode
)
26595 emit_insn (gen_popcntbsi2 (tmp1
, src
));
26596 tmp2
= expand_mult (SImode
, tmp1
, GEN_INT (0x01010101),
26598 tmp2
= force_reg (SImode
, tmp2
);
26599 emit_insn (gen_lshrsi3 (dst
, tmp2
, GEN_INT (24)));
26603 emit_insn (gen_popcntbdi2 (tmp1
, src
));
26604 tmp2
= expand_mult (DImode
, tmp1
,
26605 GEN_INT ((HOST_WIDE_INT
)
26606 0x01010101 << 32 | 0x01010101),
26608 tmp2
= force_reg (DImode
, tmp2
);
26609 emit_insn (gen_lshrdi3 (dst
, tmp2
, GEN_INT (56)));
26614 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26615 target, and SRC is the argument operand. */
26618 rs6000_emit_parity (rtx dst
, rtx src
)
26620 enum machine_mode mode
= GET_MODE (dst
);
26623 tmp
= gen_reg_rtx (mode
);
26625 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26628 if (mode
== SImode
)
26630 emit_insn (gen_popcntbsi2 (tmp
, src
));
26631 emit_insn (gen_paritysi2_cmpb (dst
, tmp
));
26635 emit_insn (gen_popcntbdi2 (tmp
, src
));
26636 emit_insn (gen_paritydi2_cmpb (dst
, tmp
));
26641 if (mode
== SImode
)
26643 /* Is mult+shift >= shift+xor+shift+xor? */
26644 if (rs6000_cost
->mulsi_const
>= COSTS_N_INSNS (3))
26646 rtx tmp1
, tmp2
, tmp3
, tmp4
;
26648 tmp1
= gen_reg_rtx (SImode
);
26649 emit_insn (gen_popcntbsi2 (tmp1
, src
));
26651 tmp2
= gen_reg_rtx (SImode
);
26652 emit_insn (gen_lshrsi3 (tmp2
, tmp1
, GEN_INT (16)));
26653 tmp3
= gen_reg_rtx (SImode
);
26654 emit_insn (gen_xorsi3 (tmp3
, tmp1
, tmp2
));
26656 tmp4
= gen_reg_rtx (SImode
);
26657 emit_insn (gen_lshrsi3 (tmp4
, tmp3
, GEN_INT (8)));
26658 emit_insn (gen_xorsi3 (tmp
, tmp3
, tmp4
));
26661 rs6000_emit_popcount (tmp
, src
);
26662 emit_insn (gen_andsi3 (dst
, tmp
, const1_rtx
));
26666 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26667 if (rs6000_cost
->muldi
>= COSTS_N_INSNS (5))
26669 rtx tmp1
, tmp2
, tmp3
, tmp4
, tmp5
, tmp6
;
26671 tmp1
= gen_reg_rtx (DImode
);
26672 emit_insn (gen_popcntbdi2 (tmp1
, src
));
26674 tmp2
= gen_reg_rtx (DImode
);
26675 emit_insn (gen_lshrdi3 (tmp2
, tmp1
, GEN_INT (32)));
26676 tmp3
= gen_reg_rtx (DImode
);
26677 emit_insn (gen_xordi3 (tmp3
, tmp1
, tmp2
));
26679 tmp4
= gen_reg_rtx (DImode
);
26680 emit_insn (gen_lshrdi3 (tmp4
, tmp3
, GEN_INT (16)));
26681 tmp5
= gen_reg_rtx (DImode
);
26682 emit_insn (gen_xordi3 (tmp5
, tmp3
, tmp4
));
26684 tmp6
= gen_reg_rtx (DImode
);
26685 emit_insn (gen_lshrdi3 (tmp6
, tmp5
, GEN_INT (8)));
26686 emit_insn (gen_xordi3 (tmp
, tmp5
, tmp6
));
26689 rs6000_emit_popcount (tmp
, src
);
26690 emit_insn (gen_anddi3 (dst
, tmp
, const1_rtx
));
26694 /* Return an RTX representing where to find the function value of a
26695 function returning MODE. */
26697 rs6000_complex_function_value (enum machine_mode mode
)
26699 unsigned int regno
;
26701 enum machine_mode inner
= GET_MODE_INNER (mode
);
26702 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
26704 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
26705 regno
= FP_ARG_RETURN
;
26708 regno
= GP_ARG_RETURN
;
26710 /* 32-bit is OK since it'll go in r3/r4. */
26711 if (TARGET_32BIT
&& inner_bytes
>= 4)
26712 return gen_rtx_REG (mode
, regno
);
26715 if (inner_bytes
>= 8)
26716 return gen_rtx_REG (mode
, regno
);
26718 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
26720 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
26721 GEN_INT (inner_bytes
));
26722 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
26725 /* Target hook for TARGET_FUNCTION_VALUE.
26727 On the SPE, both FPs and vectors are returned in r3.
26729 On RS/6000 an integer value is in r3 and a floating-point value is in
26730 fp1, unless -msoft-float. */
26733 rs6000_function_value (const_tree valtype
,
26734 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
26735 bool outgoing ATTRIBUTE_UNUSED
)
26737 enum machine_mode mode
;
26738 unsigned int regno
;
26740 /* Special handling for structs in darwin64. */
26742 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype
), valtype
))
26744 CUMULATIVE_ARGS valcum
;
26748 valcum
.fregno
= FP_ARG_MIN_REG
;
26749 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
26750 /* Do a trial code generation as if this were going to be passed as
26751 an argument; if any part goes in memory, we return NULL. */
26752 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, true, true);
26755 /* Otherwise fall through to standard ABI rules. */
26758 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
26760 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26761 return gen_rtx_PARALLEL (DImode
,
26763 gen_rtx_EXPR_LIST (VOIDmode
,
26764 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
26766 gen_rtx_EXPR_LIST (VOIDmode
,
26767 gen_rtx_REG (SImode
,
26768 GP_ARG_RETURN
+ 1),
26771 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
26773 return gen_rtx_PARALLEL (DCmode
,
26775 gen_rtx_EXPR_LIST (VOIDmode
,
26776 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
26778 gen_rtx_EXPR_LIST (VOIDmode
,
26779 gen_rtx_REG (SImode
,
26780 GP_ARG_RETURN
+ 1),
26782 gen_rtx_EXPR_LIST (VOIDmode
,
26783 gen_rtx_REG (SImode
,
26784 GP_ARG_RETURN
+ 2),
26786 gen_rtx_EXPR_LIST (VOIDmode
,
26787 gen_rtx_REG (SImode
,
26788 GP_ARG_RETURN
+ 3),
26792 mode
= TYPE_MODE (valtype
);
26793 if ((INTEGRAL_TYPE_P (valtype
) && GET_MODE_BITSIZE (mode
) < BITS_PER_WORD
)
26794 || POINTER_TYPE_P (valtype
))
26795 mode
= TARGET_32BIT
? SImode
: DImode
;
26797 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
26798 /* _Decimal128 must use an even/odd register pair. */
26799 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
26800 else if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
26801 && ((TARGET_SINGLE_FLOAT
&& (mode
== SFmode
)) || TARGET_DOUBLE_FLOAT
))
26802 regno
= FP_ARG_RETURN
;
26803 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
26804 && targetm
.calls
.split_complex_arg
)
26805 return rs6000_complex_function_value (mode
);
26806 else if (TREE_CODE (valtype
) == VECTOR_TYPE
26807 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
26808 && ALTIVEC_VECTOR_MODE (mode
))
26809 regno
= ALTIVEC_ARG_RETURN
;
26810 else if (TREE_CODE (valtype
) == VECTOR_TYPE
26811 && TARGET_VSX
&& TARGET_ALTIVEC_ABI
26812 && VSX_VECTOR_MODE (mode
))
26813 regno
= ALTIVEC_ARG_RETURN
;
26814 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
26815 && (mode
== DFmode
|| mode
== DCmode
26816 || mode
== TFmode
|| mode
== TCmode
))
26817 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
26819 regno
= GP_ARG_RETURN
;
26821 return gen_rtx_REG (mode
, regno
);
26824 /* Define how to find the value returned by a library function
26825 assuming the value has mode MODE. */
26827 rs6000_libcall_value (enum machine_mode mode
)
26829 unsigned int regno
;
26831 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
26833 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26834 return gen_rtx_PARALLEL (DImode
,
26836 gen_rtx_EXPR_LIST (VOIDmode
,
26837 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
26839 gen_rtx_EXPR_LIST (VOIDmode
,
26840 gen_rtx_REG (SImode
,
26841 GP_ARG_RETURN
+ 1),
26845 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
26846 /* _Decimal128 must use an even/odd register pair. */
26847 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
26848 else if (SCALAR_FLOAT_MODE_P (mode
)
26849 && TARGET_HARD_FLOAT
&& TARGET_FPRS
26850 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
) || TARGET_DOUBLE_FLOAT
))
26851 regno
= FP_ARG_RETURN
;
26852 else if (ALTIVEC_VECTOR_MODE (mode
)
26853 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
26854 regno
= ALTIVEC_ARG_RETURN
;
26855 else if (VSX_VECTOR_MODE (mode
)
26856 && TARGET_VSX
&& TARGET_ALTIVEC_ABI
)
26857 regno
= ALTIVEC_ARG_RETURN
;
26858 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
26859 return rs6000_complex_function_value (mode
);
26860 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
26861 && (mode
== DFmode
|| mode
== DCmode
26862 || mode
== TFmode
|| mode
== TCmode
))
26863 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
26865 regno
= GP_ARG_RETURN
;
26867 return gen_rtx_REG (mode
, regno
);
26871 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26872 Frame pointer elimination is automatically handled.
26874 For the RS/6000, if frame pointer elimination is being done, we would like
26875 to convert ap into fp, not sp.
26877 We need r30 if -mminimal-toc was specified, and there are constant pool
26881 rs6000_can_eliminate (const int from
, const int to
)
26883 return (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
26884 ? ! frame_pointer_needed
26885 : from
== RS6000_PIC_OFFSET_TABLE_REGNUM
26886 ? ! TARGET_MINIMAL_TOC
|| TARGET_NO_TOC
|| get_pool_size () == 0
26890 /* Define the offset between two registers, FROM to be eliminated and its
26891 replacement TO, at the start of a routine. */
26893 rs6000_initial_elimination_offset (int from
, int to
)
26895 rs6000_stack_t
*info
= rs6000_stack_info ();
26896 HOST_WIDE_INT offset
;
26898 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
26899 offset
= info
->push_p
? 0 : -info
->total_size
;
26900 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
26902 offset
= info
->push_p
? 0 : -info
->total_size
;
26903 if (FRAME_GROWS_DOWNWARD
)
26904 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
26906 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
26907 offset
= FRAME_GROWS_DOWNWARD
26908 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
26910 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
26911 offset
= info
->total_size
;
26912 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
26913 offset
= info
->push_p
? info
->total_size
: 0;
26914 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
26917 gcc_unreachable ();
26923 rs6000_dwarf_register_span (rtx reg
)
26927 unsigned regno
= REGNO (reg
);
26928 enum machine_mode mode
= GET_MODE (reg
);
26932 && (SPE_VECTOR_MODE (GET_MODE (reg
))
26933 || (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
)
26934 && mode
!= SFmode
&& mode
!= SDmode
&& mode
!= SCmode
)))
26939 regno
= REGNO (reg
);
26941 /* The duality of the SPE register size wreaks all kinds of havoc.
26942 This is a way of distinguishing r0 in 32-bits from r0 in
26944 words
= (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
26945 gcc_assert (words
<= 4);
26946 for (i
= 0; i
< words
; i
++, regno
++)
26948 if (BYTES_BIG_ENDIAN
)
26950 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
+ 1200);
26951 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
);
26955 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
);
26956 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
+ 1200);
26960 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (words
* 2, parts
));
26963 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26966 rs6000_init_dwarf_reg_sizes_extra (tree address
)
26971 enum machine_mode mode
= TYPE_MODE (char_type_node
);
26972 rtx addr
= expand_expr (address
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
26973 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
26974 rtx value
= gen_int_mode (4, mode
);
26976 for (i
= 1201; i
< 1232; i
++)
26978 int column
= DWARF_REG_TO_UNWIND_COLUMN (i
);
26979 HOST_WIDE_INT offset
26980 = DWARF_FRAME_REGNUM (column
) * GET_MODE_SIZE (mode
);
26982 emit_move_insn (adjust_address (mem
, mode
, offset
), value
);
26987 /* Map internal gcc register numbers to DWARF2 register numbers. */
26990 rs6000_dbx_register_number (unsigned int regno
)
26992 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
26994 if (regno
== MQ_REGNO
)
26996 if (regno
== LR_REGNO
)
26998 if (regno
== CTR_REGNO
)
27000 if (CR_REGNO_P (regno
))
27001 return regno
- CR0_REGNO
+ 86;
27002 if (regno
== CA_REGNO
)
27003 return 101; /* XER */
27004 if (ALTIVEC_REGNO_P (regno
))
27005 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
27006 if (regno
== VRSAVE_REGNO
)
27008 if (regno
== VSCR_REGNO
)
27010 if (regno
== SPE_ACC_REGNO
)
27012 if (regno
== SPEFSCR_REGNO
)
27014 /* SPE high reg number. We get these values of regno from
27015 rs6000_dwarf_register_span. */
27016 gcc_assert (regno
>= 1200 && regno
< 1232);
27020 /* target hook eh_return_filter_mode */
27021 static enum machine_mode
27022 rs6000_eh_return_filter_mode (void)
27024 return TARGET_32BIT
? SImode
: word_mode
;
27027 /* Target hook for scalar_mode_supported_p. */
27029 rs6000_scalar_mode_supported_p (enum machine_mode mode
)
27031 if (DECIMAL_FLOAT_MODE_P (mode
))
27032 return default_decimal_float_supported_p ();
27034 return default_scalar_mode_supported_p (mode
);
27037 /* Target hook for vector_mode_supported_p. */
27039 rs6000_vector_mode_supported_p (enum machine_mode mode
)
27042 if (TARGET_PAIRED_FLOAT
&& PAIRED_VECTOR_MODE (mode
))
27045 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
27048 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
))
27055 /* Target hook for invalid_arg_for_unprototyped_fn. */
27056 static const char *
27057 invalid_arg_for_unprototyped_fn (const_tree typelist
, const_tree funcdecl
, const_tree val
)
27059 return (!rs6000_darwin64_abi
27061 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
27062 && (funcdecl
== NULL_TREE
27063 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
27064 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
27065 ? N_("AltiVec argument passed to unprototyped function")
27069 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27070 setup by using __stack_chk_fail_local hidden function instead of
27071 calling __stack_chk_fail directly. Otherwise it is better to call
27072 __stack_chk_fail directly. */
27075 rs6000_stack_protect_fail (void)
27077 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
27078 ? default_hidden_stack_protect_fail ()
27079 : default_external_stack_protect_fail ();
27083 rs6000_final_prescan_insn (rtx insn
, rtx
*operand ATTRIBUTE_UNUSED
,
27084 int num_operands ATTRIBUTE_UNUSED
)
27086 if (rs6000_warn_cell_microcode
)
27089 int insn_code_number
= recog_memoized (insn
);
27090 location_t location
= locator_location (INSN_LOCATOR (insn
));
27092 /* Punt on insns we cannot recognize. */
27093 if (insn_code_number
< 0)
27096 temp
= get_insn_template (insn_code_number
, insn
);
27098 if (get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
)
27099 warning_at (location
, OPT_mwarn_cell_microcode
,
27100 "emitting microcode insn %s\t[%s] #%d",
27101 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
27102 else if (get_attr_cell_micro (insn
) == CELL_MICRO_CONDITIONAL
)
27103 warning_at (location
, OPT_mwarn_cell_microcode
,
27104 "emitting conditional microcode insn %s\t[%s] #%d",
27105 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
27110 /* Allocate a stack temp and fixup the address so it meets the particular
27111 memory requirements (either offetable or REG+REG addressing). */
27114 rs6000_allocate_stack_temp (enum machine_mode mode
,
27115 bool offsettable_p
,
27118 rtx stack
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
27119 rtx addr
= XEXP (stack
, 0);
27120 int strict_p
= (reload_in_progress
|| reload_completed
);
27122 if (!legitimate_indirect_address_p (addr
, strict_p
))
27125 && !rs6000_legitimate_offset_address_p (mode
, addr
, strict_p
))
27126 stack
= replace_equiv_address (stack
, copy_addr_to_reg (addr
));
27128 else if (reg_reg_p
&& !legitimate_indexed_address_p (addr
, strict_p
))
27129 stack
= replace_equiv_address (stack
, copy_addr_to_reg (addr
));
27135 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27136 to such a form to deal with memory reference instructions like STFIWX that
27137 only take reg+reg addressing. */
27140 rs6000_address_for_fpconvert (rtx x
)
27142 int strict_p
= (reload_in_progress
|| reload_completed
);
27145 gcc_assert (MEM_P (x
));
27146 addr
= XEXP (x
, 0);
27147 if (! legitimate_indirect_address_p (addr
, strict_p
)
27148 && ! legitimate_indexed_address_p (addr
, strict_p
))
27149 x
= replace_equiv_address (x
, copy_addr_to_reg (addr
));
27154 /* Expand 32-bit int -> floating point conversions. Return true if
27158 rs6000_expand_convert_si_to_sfdf (rtx dest
, rtx src
, bool unsigned_p
)
27160 enum machine_mode dmode
= GET_MODE (dest
);
27161 rtx (*func_si
) (rtx
, rtx
, rtx
, rtx
);
27162 rtx (*func_si_mem
) (rtx
, rtx
);
27163 rtx (*func_di
) (rtx
, rtx
);
27166 gcc_assert (GET_MODE (src
) == SImode
);
27168 if (dmode
== SFmode
)
27172 gcc_assert (TARGET_FCFIDUS
&& TARGET_LFIWZX
);
27173 func_si
= gen_floatunssisf2_lfiwzx
;
27174 func_si_mem
= gen_floatunssisf2_lfiwzx_mem
;
27175 func_di
= gen_floatunsdisf2
;
27179 gcc_assert (TARGET_FCFIDS
&& TARGET_LFIWAX
);
27180 func_si
= gen_floatsisf2_lfiwax
;
27181 func_si_mem
= gen_floatsisf2_lfiwax_mem
;
27182 func_di
= gen_floatdisf2
;
27186 else if (dmode
== DFmode
)
27190 gcc_assert (TARGET_FCFIDU
&& TARGET_LFIWZX
);
27191 func_si
= gen_floatunssidf2_lfiwzx
;
27192 func_si_mem
= gen_floatunssidf2_lfiwzx_mem
;
27193 func_di
= gen_floatunsdidf2
;
27197 gcc_assert (TARGET_FCFID
&& TARGET_LFIWAX
);
27198 func_si
= gen_floatsidf2_lfiwax
;
27199 func_si_mem
= gen_floatsidf2_lfiwax_mem
;
27200 func_di
= gen_floatdidf2
;
27205 gcc_unreachable ();
27209 src
= rs6000_address_for_fpconvert (src
);
27210 emit_insn (func_si_mem (dest
, src
));
27212 else if (!TARGET_MFPGPR
)
27214 reg
= gen_reg_rtx (DImode
);
27215 stack
= rs6000_allocate_stack_temp (SImode
, false, true);
27216 emit_insn (func_si (dest
, src
, stack
, reg
));
27221 src
= force_reg (SImode
, src
);
27222 reg
= convert_to_mode (DImode
, src
, unsigned_p
);
27223 emit_insn (func_di (dest
, reg
));
27227 #include "gt-rs6000.h"