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
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"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-attr.h"
43 #include "basic-block.h"
44 #include "integrate.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 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
119 int ra_needs_full_frame
;
120 /* Some local-dynamic symbol. */
121 const char *some_ld_name
;
122 /* Whether the instruction chain has been scanned already. */
123 int insn_chain_scanned_p
;
124 /* Flags if __builtin_return_address (0) was used. */
126 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
127 varargs save area. */
128 HOST_WIDE_INT varargs_save_offset
;
129 /* Temporary stack slot to use for SDmode copies. This slot is
130 64-bits wide and is allocated early enough so that the offset
131 does not overflow the 16-bit load/store offset field. */
132 rtx sdmode_stack_slot
;
135 /* Target cpu type */
137 enum processor_type rs6000_cpu
;
138 struct rs6000_cpu_select rs6000_select
[3] =
140 /* switch name, tune arch */
141 { (const char *)0, "--with-cpu=", 1, 1 },
142 { (const char *)0, "-mcpu=", 1, 1 },
143 { (const char *)0, "-mtune=", 1, 0 },
146 /* Always emit branch hint bits. */
147 static GTY(()) bool rs6000_always_hint
;
149 /* Schedule instructions for group formation. */
150 static GTY(()) bool rs6000_sched_groups
;
152 /* Align branch targets. */
153 static GTY(()) bool rs6000_align_branch_targets
;
155 /* Support for -msched-costly-dep option. */
156 const char *rs6000_sched_costly_dep_str
;
157 enum rs6000_dependence_cost rs6000_sched_costly_dep
;
159 /* Support for -minsert-sched-nops option. */
160 const char *rs6000_sched_insert_nops_str
;
161 enum rs6000_nop_insertion rs6000_sched_insert_nops
;
163 /* Support targetm.vectorize.builtin_mask_for_load. */
164 static GTY(()) tree altivec_builtin_mask_for_load
;
166 /* Size of long double. */
167 int rs6000_long_double_type_size
;
169 /* IEEE quad extended precision long double. */
172 /* Nonzero to use AltiVec ABI. */
173 int rs6000_altivec_abi
;
175 /* Nonzero if we want SPE SIMD instructions. */
178 /* Nonzero if we want SPE ABI extensions. */
181 /* Nonzero if floating point operations are done in the GPRs. */
182 int rs6000_float_gprs
= 0;
184 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
185 int rs6000_darwin64_abi
;
187 /* Set to nonzero once AIX common-mode calls have been defined. */
188 static GTY(()) int common_mode_defined
;
190 /* Label number of label created for -mrelocatable, to call to so we can
191 get the address of the GOT section */
192 int rs6000_pic_labelno
;
195 /* Which abi to adhere to */
196 const char *rs6000_abi_name
;
198 /* Semantics of the small data area */
199 enum rs6000_sdata_type rs6000_sdata
= SDATA_DATA
;
201 /* Which small data model to use */
202 const char *rs6000_sdata_name
= (char *)0;
204 /* Counter for labels which are to be placed in .fixup. */
205 int fixuplabelno
= 0;
208 /* Bit size of immediate TLS offsets and string from which it is decoded. */
209 int rs6000_tls_size
= 32;
210 const char *rs6000_tls_size_string
;
212 /* ABI enumeration available for subtarget to use. */
213 enum rs6000_abi rs6000_current_abi
;
215 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
219 const char *rs6000_debug_name
;
220 int rs6000_debug_stack
; /* debug stack applications */
221 int rs6000_debug_arg
; /* debug argument handling */
222 int rs6000_debug_reg
; /* debug register classes */
223 int rs6000_debug_addr
; /* debug memory addressing */
224 int rs6000_debug_cost
; /* debug rtx_costs */
226 /* Specify the machine mode that pointers have. After generation of rtl, the
227 compiler makes no further distinction between pointers and any other objects
228 of this machine mode. The type is unsigned since not all things that
229 include rs6000.h also include machmode.h. */
230 unsigned rs6000_pmode
;
232 /* Width in bits of a pointer. */
233 unsigned rs6000_pointer_size
;
236 /* Value is TRUE if register/mode pair is acceptable. */
237 bool rs6000_hard_regno_mode_ok_p
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
239 /* Maximum number of registers needed for a given register class and mode. */
240 unsigned char rs6000_class_max_nregs
[NUM_MACHINE_MODES
][LIM_REG_CLASSES
];
242 /* How many registers are needed for a given register and mode. */
243 unsigned char rs6000_hard_regno_nregs
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
245 /* Map register number to register class. */
246 enum reg_class rs6000_regno_regclass
[FIRST_PSEUDO_REGISTER
];
248 /* Reload functions based on the type and the vector unit. */
249 static enum insn_code rs6000_vector_reload
[NUM_MACHINE_MODES
][2];
251 /* Built in types. */
252 tree rs6000_builtin_types
[RS6000_BTI_MAX
];
253 tree rs6000_builtin_decls
[RS6000_BUILTIN_COUNT
];
255 const char *rs6000_traceback_name
;
257 traceback_default
= 0,
263 /* Flag to say the TOC is initialized */
265 char toc_label_name
[10];
267 /* Cached value of rs6000_variable_issue. This is cached in
268 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
269 static short cached_can_issue_more
;
271 static GTY(()) section
*read_only_data_section
;
272 static GTY(()) section
*private_data_section
;
273 static GTY(()) section
*read_only_private_data_section
;
274 static GTY(()) section
*sdata2_section
;
275 static GTY(()) section
*toc_section
;
277 /* Control alignment for fields within structures. */
278 /* String from -malign-XXXXX. */
279 int rs6000_alignment_flags
;
281 /* True for any options that were explicitly set. */
283 bool aix_struct_ret
; /* True if -maix-struct-ret was used. */
284 bool alignment
; /* True if -malign- was used. */
285 bool spe_abi
; /* True if -mabi=spe/no-spe was used. */
286 bool altivec_abi
; /* True if -mabi=altivec/no-altivec used. */
287 bool spe
; /* True if -mspe= was used. */
288 bool float_gprs
; /* True if -mfloat-gprs= was used. */
289 bool long_double
; /* True if -mlong-double- was used. */
290 bool ieee
; /* True if -mabi=ieee/ibmlongdouble used. */
291 bool vrsave
; /* True if -mvrsave was used. */
292 } rs6000_explicit_options
;
294 struct builtin_description
296 /* mask is not const because we're going to alter it below. This
297 nonsense will go away when we rewrite the -march infrastructure
298 to give us more target flag bits. */
300 const enum insn_code icode
;
301 const char *const name
;
302 const enum rs6000_builtins code
;
305 /* Describe the vector unit used for modes. */
306 enum rs6000_vector rs6000_vector_unit
[NUM_MACHINE_MODES
];
307 enum rs6000_vector rs6000_vector_mem
[NUM_MACHINE_MODES
];
309 /* Register classes for various constraints that are based on the target
311 enum reg_class rs6000_constraints
[RS6000_CONSTRAINT_MAX
];
313 /* Describe the alignment of a vector. */
314 int rs6000_vector_align
[NUM_MACHINE_MODES
];
316 /* Map selected modes to types for builtins. */
317 static GTY(()) tree builtin_mode_to_type
[MAX_MACHINE_MODE
][2];
319 /* Target cpu costs. */
321 struct processor_costs
{
322 const int mulsi
; /* cost of SImode multiplication. */
323 const int mulsi_const
; /* cost of SImode multiplication by constant. */
324 const int mulsi_const9
; /* cost of SImode mult by short constant. */
325 const int muldi
; /* cost of DImode multiplication. */
326 const int divsi
; /* cost of SImode division. */
327 const int divdi
; /* cost of DImode division. */
328 const int fp
; /* cost of simple SFmode and DFmode insns. */
329 const int dmul
; /* cost of DFmode multiplication (and fmadd). */
330 const int sdiv
; /* cost of SFmode division (fdivs). */
331 const int ddiv
; /* cost of DFmode division (fdiv). */
332 const int cache_line_size
; /* cache line size in bytes. */
333 const int l1_cache_size
; /* size of l1 cache, in kilobytes. */
334 const int l2_cache_size
; /* size of l2 cache, in kilobytes. */
335 const int simultaneous_prefetches
; /* number of parallel prefetch
339 const struct processor_costs
*rs6000_cost
;
341 /* Processor costs (relative to an add) */
343 /* Instruction size costs on 32bit processors. */
345 struct processor_costs size32_cost
= {
346 COSTS_N_INSNS (1), /* mulsi */
347 COSTS_N_INSNS (1), /* mulsi_const */
348 COSTS_N_INSNS (1), /* mulsi_const9 */
349 COSTS_N_INSNS (1), /* muldi */
350 COSTS_N_INSNS (1), /* divsi */
351 COSTS_N_INSNS (1), /* divdi */
352 COSTS_N_INSNS (1), /* fp */
353 COSTS_N_INSNS (1), /* dmul */
354 COSTS_N_INSNS (1), /* sdiv */
355 COSTS_N_INSNS (1), /* ddiv */
362 /* Instruction size costs on 64bit processors. */
364 struct processor_costs size64_cost
= {
365 COSTS_N_INSNS (1), /* mulsi */
366 COSTS_N_INSNS (1), /* mulsi_const */
367 COSTS_N_INSNS (1), /* mulsi_const9 */
368 COSTS_N_INSNS (1), /* muldi */
369 COSTS_N_INSNS (1), /* divsi */
370 COSTS_N_INSNS (1), /* divdi */
371 COSTS_N_INSNS (1), /* fp */
372 COSTS_N_INSNS (1), /* dmul */
373 COSTS_N_INSNS (1), /* sdiv */
374 COSTS_N_INSNS (1), /* ddiv */
381 /* Instruction costs on RIOS1 processors. */
383 struct processor_costs rios1_cost
= {
384 COSTS_N_INSNS (5), /* mulsi */
385 COSTS_N_INSNS (4), /* mulsi_const */
386 COSTS_N_INSNS (3), /* mulsi_const9 */
387 COSTS_N_INSNS (5), /* muldi */
388 COSTS_N_INSNS (19), /* divsi */
389 COSTS_N_INSNS (19), /* divdi */
390 COSTS_N_INSNS (2), /* fp */
391 COSTS_N_INSNS (2), /* dmul */
392 COSTS_N_INSNS (19), /* sdiv */
393 COSTS_N_INSNS (19), /* ddiv */
394 128, /* cache line size */
400 /* Instruction costs on RIOS2 processors. */
402 struct processor_costs rios2_cost
= {
403 COSTS_N_INSNS (2), /* mulsi */
404 COSTS_N_INSNS (2), /* mulsi_const */
405 COSTS_N_INSNS (2), /* mulsi_const9 */
406 COSTS_N_INSNS (2), /* muldi */
407 COSTS_N_INSNS (13), /* divsi */
408 COSTS_N_INSNS (13), /* divdi */
409 COSTS_N_INSNS (2), /* fp */
410 COSTS_N_INSNS (2), /* dmul */
411 COSTS_N_INSNS (17), /* sdiv */
412 COSTS_N_INSNS (17), /* ddiv */
413 256, /* cache line size */
419 /* Instruction costs on RS64A processors. */
421 struct processor_costs rs64a_cost
= {
422 COSTS_N_INSNS (20), /* mulsi */
423 COSTS_N_INSNS (12), /* mulsi_const */
424 COSTS_N_INSNS (8), /* mulsi_const9 */
425 COSTS_N_INSNS (34), /* muldi */
426 COSTS_N_INSNS (65), /* divsi */
427 COSTS_N_INSNS (67), /* divdi */
428 COSTS_N_INSNS (4), /* fp */
429 COSTS_N_INSNS (4), /* dmul */
430 COSTS_N_INSNS (31), /* sdiv */
431 COSTS_N_INSNS (31), /* ddiv */
432 128, /* cache line size */
438 /* Instruction costs on MPCCORE processors. */
440 struct processor_costs mpccore_cost
= {
441 COSTS_N_INSNS (2), /* mulsi */
442 COSTS_N_INSNS (2), /* mulsi_const */
443 COSTS_N_INSNS (2), /* mulsi_const9 */
444 COSTS_N_INSNS (2), /* muldi */
445 COSTS_N_INSNS (6), /* divsi */
446 COSTS_N_INSNS (6), /* divdi */
447 COSTS_N_INSNS (4), /* fp */
448 COSTS_N_INSNS (5), /* dmul */
449 COSTS_N_INSNS (10), /* sdiv */
450 COSTS_N_INSNS (17), /* ddiv */
451 32, /* cache line size */
457 /* Instruction costs on PPC403 processors. */
459 struct processor_costs ppc403_cost
= {
460 COSTS_N_INSNS (4), /* mulsi */
461 COSTS_N_INSNS (4), /* mulsi_const */
462 COSTS_N_INSNS (4), /* mulsi_const9 */
463 COSTS_N_INSNS (4), /* muldi */
464 COSTS_N_INSNS (33), /* divsi */
465 COSTS_N_INSNS (33), /* divdi */
466 COSTS_N_INSNS (11), /* fp */
467 COSTS_N_INSNS (11), /* dmul */
468 COSTS_N_INSNS (11), /* sdiv */
469 COSTS_N_INSNS (11), /* ddiv */
470 32, /* cache line size */
476 /* Instruction costs on PPC405 processors. */
478 struct processor_costs ppc405_cost
= {
479 COSTS_N_INSNS (5), /* mulsi */
480 COSTS_N_INSNS (4), /* mulsi_const */
481 COSTS_N_INSNS (3), /* mulsi_const9 */
482 COSTS_N_INSNS (5), /* muldi */
483 COSTS_N_INSNS (35), /* divsi */
484 COSTS_N_INSNS (35), /* divdi */
485 COSTS_N_INSNS (11), /* fp */
486 COSTS_N_INSNS (11), /* dmul */
487 COSTS_N_INSNS (11), /* sdiv */
488 COSTS_N_INSNS (11), /* ddiv */
489 32, /* cache line size */
495 /* Instruction costs on PPC440 processors. */
497 struct processor_costs ppc440_cost
= {
498 COSTS_N_INSNS (3), /* mulsi */
499 COSTS_N_INSNS (2), /* mulsi_const */
500 COSTS_N_INSNS (2), /* mulsi_const9 */
501 COSTS_N_INSNS (3), /* muldi */
502 COSTS_N_INSNS (34), /* divsi */
503 COSTS_N_INSNS (34), /* divdi */
504 COSTS_N_INSNS (5), /* fp */
505 COSTS_N_INSNS (5), /* dmul */
506 COSTS_N_INSNS (19), /* sdiv */
507 COSTS_N_INSNS (33), /* ddiv */
508 32, /* cache line size */
514 /* Instruction costs on PPC601 processors. */
516 struct processor_costs ppc601_cost
= {
517 COSTS_N_INSNS (5), /* mulsi */
518 COSTS_N_INSNS (5), /* mulsi_const */
519 COSTS_N_INSNS (5), /* mulsi_const9 */
520 COSTS_N_INSNS (5), /* muldi */
521 COSTS_N_INSNS (36), /* divsi */
522 COSTS_N_INSNS (36), /* divdi */
523 COSTS_N_INSNS (4), /* fp */
524 COSTS_N_INSNS (5), /* dmul */
525 COSTS_N_INSNS (17), /* sdiv */
526 COSTS_N_INSNS (31), /* ddiv */
527 32, /* cache line size */
533 /* Instruction costs on PPC603 processors. */
535 struct processor_costs ppc603_cost
= {
536 COSTS_N_INSNS (5), /* mulsi */
537 COSTS_N_INSNS (3), /* mulsi_const */
538 COSTS_N_INSNS (2), /* mulsi_const9 */
539 COSTS_N_INSNS (5), /* muldi */
540 COSTS_N_INSNS (37), /* divsi */
541 COSTS_N_INSNS (37), /* divdi */
542 COSTS_N_INSNS (3), /* fp */
543 COSTS_N_INSNS (4), /* dmul */
544 COSTS_N_INSNS (18), /* sdiv */
545 COSTS_N_INSNS (33), /* ddiv */
546 32, /* cache line size */
552 /* Instruction costs on PPC604 processors. */
554 struct processor_costs ppc604_cost
= {
555 COSTS_N_INSNS (4), /* mulsi */
556 COSTS_N_INSNS (4), /* mulsi_const */
557 COSTS_N_INSNS (4), /* mulsi_const9 */
558 COSTS_N_INSNS (4), /* muldi */
559 COSTS_N_INSNS (20), /* divsi */
560 COSTS_N_INSNS (20), /* divdi */
561 COSTS_N_INSNS (3), /* fp */
562 COSTS_N_INSNS (3), /* dmul */
563 COSTS_N_INSNS (18), /* sdiv */
564 COSTS_N_INSNS (32), /* ddiv */
565 32, /* cache line size */
571 /* Instruction costs on PPC604e processors. */
573 struct processor_costs ppc604e_cost
= {
574 COSTS_N_INSNS (2), /* mulsi */
575 COSTS_N_INSNS (2), /* mulsi_const */
576 COSTS_N_INSNS (2), /* mulsi_const9 */
577 COSTS_N_INSNS (2), /* muldi */
578 COSTS_N_INSNS (20), /* divsi */
579 COSTS_N_INSNS (20), /* divdi */
580 COSTS_N_INSNS (3), /* fp */
581 COSTS_N_INSNS (3), /* dmul */
582 COSTS_N_INSNS (18), /* sdiv */
583 COSTS_N_INSNS (32), /* ddiv */
584 32, /* cache line size */
590 /* Instruction costs on PPC620 processors. */
592 struct processor_costs ppc620_cost
= {
593 COSTS_N_INSNS (5), /* mulsi */
594 COSTS_N_INSNS (4), /* mulsi_const */
595 COSTS_N_INSNS (3), /* mulsi_const9 */
596 COSTS_N_INSNS (7), /* muldi */
597 COSTS_N_INSNS (21), /* divsi */
598 COSTS_N_INSNS (37), /* divdi */
599 COSTS_N_INSNS (3), /* fp */
600 COSTS_N_INSNS (3), /* dmul */
601 COSTS_N_INSNS (18), /* sdiv */
602 COSTS_N_INSNS (32), /* ddiv */
603 128, /* cache line size */
609 /* Instruction costs on PPC630 processors. */
611 struct processor_costs ppc630_cost
= {
612 COSTS_N_INSNS (5), /* mulsi */
613 COSTS_N_INSNS (4), /* mulsi_const */
614 COSTS_N_INSNS (3), /* mulsi_const9 */
615 COSTS_N_INSNS (7), /* muldi */
616 COSTS_N_INSNS (21), /* divsi */
617 COSTS_N_INSNS (37), /* divdi */
618 COSTS_N_INSNS (3), /* fp */
619 COSTS_N_INSNS (3), /* dmul */
620 COSTS_N_INSNS (17), /* sdiv */
621 COSTS_N_INSNS (21), /* ddiv */
622 128, /* cache line size */
628 /* Instruction costs on Cell processor. */
629 /* COSTS_N_INSNS (1) ~ one add. */
631 struct processor_costs ppccell_cost
= {
632 COSTS_N_INSNS (9/2)+2, /* mulsi */
633 COSTS_N_INSNS (6/2), /* mulsi_const */
634 COSTS_N_INSNS (6/2), /* mulsi_const9 */
635 COSTS_N_INSNS (15/2)+2, /* muldi */
636 COSTS_N_INSNS (38/2), /* divsi */
637 COSTS_N_INSNS (70/2), /* divdi */
638 COSTS_N_INSNS (10/2), /* fp */
639 COSTS_N_INSNS (10/2), /* dmul */
640 COSTS_N_INSNS (74/2), /* sdiv */
641 COSTS_N_INSNS (74/2), /* ddiv */
642 128, /* cache line size */
648 /* Instruction costs on PPC750 and PPC7400 processors. */
650 struct processor_costs ppc750_cost
= {
651 COSTS_N_INSNS (5), /* mulsi */
652 COSTS_N_INSNS (3), /* mulsi_const */
653 COSTS_N_INSNS (2), /* mulsi_const9 */
654 COSTS_N_INSNS (5), /* muldi */
655 COSTS_N_INSNS (17), /* divsi */
656 COSTS_N_INSNS (17), /* divdi */
657 COSTS_N_INSNS (3), /* fp */
658 COSTS_N_INSNS (3), /* dmul */
659 COSTS_N_INSNS (17), /* sdiv */
660 COSTS_N_INSNS (31), /* ddiv */
661 32, /* cache line size */
667 /* Instruction costs on PPC7450 processors. */
669 struct processor_costs ppc7450_cost
= {
670 COSTS_N_INSNS (4), /* mulsi */
671 COSTS_N_INSNS (3), /* mulsi_const */
672 COSTS_N_INSNS (3), /* mulsi_const9 */
673 COSTS_N_INSNS (4), /* muldi */
674 COSTS_N_INSNS (23), /* divsi */
675 COSTS_N_INSNS (23), /* divdi */
676 COSTS_N_INSNS (5), /* fp */
677 COSTS_N_INSNS (5), /* dmul */
678 COSTS_N_INSNS (21), /* sdiv */
679 COSTS_N_INSNS (35), /* ddiv */
680 32, /* cache line size */
686 /* Instruction costs on PPC8540 processors. */
688 struct processor_costs ppc8540_cost
= {
689 COSTS_N_INSNS (4), /* mulsi */
690 COSTS_N_INSNS (4), /* mulsi_const */
691 COSTS_N_INSNS (4), /* mulsi_const9 */
692 COSTS_N_INSNS (4), /* muldi */
693 COSTS_N_INSNS (19), /* divsi */
694 COSTS_N_INSNS (19), /* divdi */
695 COSTS_N_INSNS (4), /* fp */
696 COSTS_N_INSNS (4), /* dmul */
697 COSTS_N_INSNS (29), /* sdiv */
698 COSTS_N_INSNS (29), /* ddiv */
699 32, /* cache line size */
702 1, /* prefetch streams /*/
705 /* Instruction costs on E300C2 and E300C3 cores. */
707 struct processor_costs ppce300c2c3_cost
= {
708 COSTS_N_INSNS (4), /* mulsi */
709 COSTS_N_INSNS (4), /* mulsi_const */
710 COSTS_N_INSNS (4), /* mulsi_const9 */
711 COSTS_N_INSNS (4), /* muldi */
712 COSTS_N_INSNS (19), /* divsi */
713 COSTS_N_INSNS (19), /* divdi */
714 COSTS_N_INSNS (3), /* fp */
715 COSTS_N_INSNS (4), /* dmul */
716 COSTS_N_INSNS (18), /* sdiv */
717 COSTS_N_INSNS (33), /* ddiv */
721 1, /* prefetch streams /*/
724 /* Instruction costs on PPCE500MC processors. */
726 struct processor_costs ppce500mc_cost
= {
727 COSTS_N_INSNS (4), /* mulsi */
728 COSTS_N_INSNS (4), /* mulsi_const */
729 COSTS_N_INSNS (4), /* mulsi_const9 */
730 COSTS_N_INSNS (4), /* muldi */
731 COSTS_N_INSNS (14), /* divsi */
732 COSTS_N_INSNS (14), /* divdi */
733 COSTS_N_INSNS (8), /* fp */
734 COSTS_N_INSNS (10), /* dmul */
735 COSTS_N_INSNS (36), /* sdiv */
736 COSTS_N_INSNS (66), /* ddiv */
737 64, /* cache line size */
740 1, /* prefetch streams /*/
743 /* Instruction costs on POWER4 and POWER5 processors. */
745 struct processor_costs power4_cost
= {
746 COSTS_N_INSNS (3), /* mulsi */
747 COSTS_N_INSNS (2), /* mulsi_const */
748 COSTS_N_INSNS (2), /* mulsi_const9 */
749 COSTS_N_INSNS (4), /* muldi */
750 COSTS_N_INSNS (18), /* divsi */
751 COSTS_N_INSNS (34), /* divdi */
752 COSTS_N_INSNS (3), /* fp */
753 COSTS_N_INSNS (3), /* dmul */
754 COSTS_N_INSNS (17), /* sdiv */
755 COSTS_N_INSNS (17), /* ddiv */
756 128, /* cache line size */
759 8, /* prefetch streams /*/
762 /* Instruction costs on POWER6 processors. */
764 struct processor_costs power6_cost
= {
765 COSTS_N_INSNS (8), /* mulsi */
766 COSTS_N_INSNS (8), /* mulsi_const */
767 COSTS_N_INSNS (8), /* mulsi_const9 */
768 COSTS_N_INSNS (8), /* muldi */
769 COSTS_N_INSNS (22), /* divsi */
770 COSTS_N_INSNS (28), /* divdi */
771 COSTS_N_INSNS (3), /* fp */
772 COSTS_N_INSNS (3), /* dmul */
773 COSTS_N_INSNS (13), /* sdiv */
774 COSTS_N_INSNS (16), /* ddiv */
775 128, /* cache line size */
778 16, /* prefetch streams */
781 /* Instruction costs on POWER7 processors. */
783 struct processor_costs power7_cost
= {
784 COSTS_N_INSNS (2), /* mulsi */
785 COSTS_N_INSNS (2), /* mulsi_const */
786 COSTS_N_INSNS (2), /* mulsi_const9 */
787 COSTS_N_INSNS (2), /* muldi */
788 COSTS_N_INSNS (18), /* divsi */
789 COSTS_N_INSNS (34), /* divdi */
790 COSTS_N_INSNS (3), /* fp */
791 COSTS_N_INSNS (3), /* dmul */
792 COSTS_N_INSNS (13), /* sdiv */
793 COSTS_N_INSNS (16), /* ddiv */
794 128, /* cache line size */
797 12, /* prefetch streams */
801 static bool rs6000_function_ok_for_sibcall (tree
, tree
);
802 static const char *rs6000_invalid_within_doloop (const_rtx
);
803 static bool rs6000_legitimate_address_p (enum machine_mode
, rtx
, bool);
804 static bool rs6000_debug_legitimate_address_p (enum machine_mode
, rtx
, bool);
805 static rtx
rs6000_generate_compare (rtx
, enum machine_mode
);
806 static void rs6000_emit_stack_tie (void);
807 static void rs6000_frame_related (rtx
, rtx
, HOST_WIDE_INT
, rtx
, rtx
);
808 static bool spe_func_has_64bit_regs_p (void);
809 static void emit_frame_save (rtx
, rtx
, enum machine_mode
, unsigned int,
811 static rtx
gen_frame_mem_offset (enum machine_mode
, rtx
, int);
812 static void rs6000_emit_allocate_stack (HOST_WIDE_INT
, int, int);
813 static unsigned rs6000_hash_constant (rtx
);
814 static unsigned toc_hash_function (const void *);
815 static int toc_hash_eq (const void *, const void *);
816 static bool reg_offset_addressing_ok_p (enum machine_mode
);
817 static bool virtual_stack_registers_memory_p (rtx
);
818 static bool constant_pool_expr_p (rtx
);
819 static bool legitimate_small_data_p (enum machine_mode
, rtx
);
820 static bool legitimate_lo_sum_address_p (enum machine_mode
, rtx
, int);
821 static struct machine_function
* rs6000_init_machine_status (void);
822 static bool rs6000_assemble_integer (rtx
, unsigned int, int);
823 static bool no_global_regs_above (int, bool);
824 #ifdef HAVE_GAS_HIDDEN
825 static void rs6000_assemble_visibility (tree
, int);
827 static int rs6000_ra_ever_killed (void);
828 static tree
rs6000_handle_longcall_attribute (tree
*, tree
, tree
, int, bool *);
829 static tree
rs6000_handle_altivec_attribute (tree
*, tree
, tree
, int, bool *);
830 static bool rs6000_ms_bitfield_layout_p (const_tree
);
831 static tree
rs6000_handle_struct_attribute (tree
*, tree
, tree
, int, bool *);
832 static void rs6000_eliminate_indexed_memrefs (rtx operands
[2]);
833 static const char *rs6000_mangle_type (const_tree
);
834 static void rs6000_set_default_type_attributes (tree
);
835 static rtx
rs6000_savres_routine_sym (rs6000_stack_t
*, bool, bool, bool);
836 static rtx
rs6000_emit_stack_reset (rs6000_stack_t
*, rtx
, rtx
, int, bool);
837 static rtx
rs6000_make_savres_rtx (rs6000_stack_t
*, rtx
, int,
838 enum machine_mode
, bool, bool, bool);
839 static bool rs6000_reg_live_or_pic_offset_p (int);
840 static tree
rs6000_builtin_vectorized_function (unsigned int, tree
, tree
);
841 static int rs6000_savres_strategy (rs6000_stack_t
*, bool, int, int);
842 static void rs6000_restore_saved_cr (rtx
, int);
843 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT
);
844 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT
);
845 static void rs6000_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
847 static rtx
rs6000_emit_set_long_const (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
848 static bool rs6000_return_in_memory (const_tree
, const_tree
);
849 static rtx
rs6000_function_value (const_tree
, const_tree
, bool);
850 static void rs6000_file_start (void);
852 static int rs6000_elf_reloc_rw_mask (void);
853 static void rs6000_elf_asm_out_constructor (rtx
, int);
854 static void rs6000_elf_asm_out_destructor (rtx
, int);
855 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED
;
856 static void rs6000_elf_asm_init_sections (void);
857 static section
*rs6000_elf_select_rtx_section (enum machine_mode
, rtx
,
858 unsigned HOST_WIDE_INT
);
859 static void rs6000_elf_encode_section_info (tree
, rtx
, int)
862 static bool rs6000_use_blocks_for_constant_p (enum machine_mode
, const_rtx
);
863 static void rs6000_alloc_sdmode_stack_slot (void);
864 static void rs6000_instantiate_decls (void);
866 static void rs6000_xcoff_asm_output_anchor (rtx
);
867 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
868 static void rs6000_xcoff_asm_init_sections (void);
869 static int rs6000_xcoff_reloc_rw_mask (void);
870 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree
);
871 static section
*rs6000_xcoff_select_section (tree
, int,
872 unsigned HOST_WIDE_INT
);
873 static void rs6000_xcoff_unique_section (tree
, int);
874 static section
*rs6000_xcoff_select_rtx_section
875 (enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
);
876 static const char * rs6000_xcoff_strip_name_encoding (const char *);
877 static unsigned int rs6000_xcoff_section_type_flags (tree
, const char *, int);
878 static void rs6000_xcoff_file_start (void);
879 static void rs6000_xcoff_file_end (void);
881 static int rs6000_variable_issue (FILE *, int, rtx
, int);
882 static bool rs6000_rtx_costs (rtx
, int, int, int *, bool);
883 static bool rs6000_debug_rtx_costs (rtx
, int, int, int *, bool);
884 static int rs6000_debug_address_cost (rtx
, bool);
885 static int rs6000_adjust_cost (rtx
, rtx
, rtx
, int);
886 static int rs6000_debug_adjust_cost (rtx
, rtx
, rtx
, int);
887 static void rs6000_sched_init (FILE *, int, int);
888 static bool is_microcoded_insn (rtx
);
889 static bool is_nonpipeline_insn (rtx
);
890 static bool is_cracked_insn (rtx
);
891 static bool is_branch_slot_insn (rtx
);
892 static bool is_load_insn (rtx
);
893 static rtx
get_store_dest (rtx pat
);
894 static bool is_store_insn (rtx
);
895 static bool set_to_load_agen (rtx
,rtx
);
896 static bool adjacent_mem_locations (rtx
,rtx
);
897 static int rs6000_adjust_priority (rtx
, int);
898 static int rs6000_issue_rate (void);
899 static bool rs6000_is_costly_dependence (dep_t
, int, int);
900 static rtx
get_next_active_insn (rtx
, rtx
);
901 static bool insn_terminates_group_p (rtx
, enum group_termination
);
902 static bool insn_must_be_first_in_group (rtx
);
903 static bool insn_must_be_last_in_group (rtx
);
904 static bool is_costly_group (rtx
*, rtx
);
905 static int force_new_group (int, FILE *, rtx
*, rtx
, bool *, int, int *);
906 static int redefine_groups (FILE *, int, rtx
, rtx
);
907 static int pad_groups (FILE *, int, rtx
, rtx
);
908 static void rs6000_sched_finish (FILE *, int);
909 static int rs6000_sched_reorder (FILE *, int, rtx
*, int *, int);
910 static int rs6000_sched_reorder2 (FILE *, int, rtx
*, int *, int);
911 static int rs6000_use_sched_lookahead (void);
912 static int rs6000_use_sched_lookahead_guard (rtx
);
913 static void * rs6000_alloc_sched_context (void);
914 static void rs6000_init_sched_context (void *, bool);
915 static void rs6000_set_sched_context (void *);
916 static void rs6000_free_sched_context (void *);
917 static tree
rs6000_builtin_reciprocal (unsigned int, bool, bool);
918 static tree
rs6000_builtin_mask_for_load (void);
919 static tree
rs6000_builtin_mul_widen_even (tree
);
920 static tree
rs6000_builtin_mul_widen_odd (tree
);
921 static tree
rs6000_builtin_conversion (unsigned int, tree
);
922 static tree
rs6000_builtin_vec_perm (tree
, tree
*);
923 static bool rs6000_builtin_support_vector_misalignment (enum
928 static void def_builtin (int, const char *, tree
, int);
929 static bool rs6000_vector_alignment_reachable (const_tree
, bool);
930 static void rs6000_init_builtins (void);
931 static rtx
rs6000_expand_unop_builtin (enum insn_code
, tree
, rtx
);
932 static rtx
rs6000_expand_binop_builtin (enum insn_code
, tree
, rtx
);
933 static rtx
rs6000_expand_ternop_builtin (enum insn_code
, tree
, rtx
);
934 static rtx
rs6000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
935 static void altivec_init_builtins (void);
936 static unsigned builtin_hash_function (const void *);
937 static int builtin_hash_eq (const void *, const void *);
938 static tree
builtin_function_type (enum machine_mode
, enum machine_mode
,
939 enum machine_mode
, enum machine_mode
,
940 enum rs6000_builtins
, const char *name
);
941 static void rs6000_common_init_builtins (void);
942 static void rs6000_init_libfuncs (void);
944 static void paired_init_builtins (void);
945 static rtx
paired_expand_builtin (tree
, rtx
, bool *);
946 static rtx
paired_expand_lv_builtin (enum insn_code
, tree
, rtx
);
947 static rtx
paired_expand_stv_builtin (enum insn_code
, tree
);
948 static rtx
paired_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
950 static void enable_mask_for_builtins (struct builtin_description
*, int,
951 enum rs6000_builtins
,
952 enum rs6000_builtins
);
953 static void spe_init_builtins (void);
954 static rtx
spe_expand_builtin (tree
, rtx
, bool *);
955 static rtx
spe_expand_stv_builtin (enum insn_code
, tree
);
956 static rtx
spe_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
957 static rtx
spe_expand_evsel_builtin (enum insn_code
, tree
, rtx
);
958 static int rs6000_emit_int_cmove (rtx
, rtx
, rtx
, rtx
);
959 static rs6000_stack_t
*rs6000_stack_info (void);
960 static void debug_stack_info (rs6000_stack_t
*);
962 static rtx
altivec_expand_builtin (tree
, rtx
, bool *);
963 static rtx
altivec_expand_ld_builtin (tree
, rtx
, bool *);
964 static rtx
altivec_expand_st_builtin (tree
, rtx
, bool *);
965 static rtx
altivec_expand_dst_builtin (tree
, rtx
, bool *);
966 static rtx
altivec_expand_abs_builtin (enum insn_code
, tree
, rtx
);
967 static rtx
altivec_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
968 static rtx
altivec_expand_stv_builtin (enum insn_code
, tree
);
969 static rtx
altivec_expand_vec_init_builtin (tree
, tree
, rtx
);
970 static rtx
altivec_expand_vec_set_builtin (tree
);
971 static rtx
altivec_expand_vec_ext_builtin (tree
, rtx
);
972 static int get_element_number (tree
, tree
);
973 static bool rs6000_handle_option (size_t, const char *, int);
974 static void rs6000_parse_tls_size_option (void);
975 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
976 static int first_altivec_reg_to_save (void);
977 static unsigned int compute_vrsave_mask (void);
978 static void compute_save_world_info (rs6000_stack_t
*info_ptr
);
979 static void is_altivec_return_reg (rtx
, void *);
980 static rtx
generate_set_vrsave (rtx
, rs6000_stack_t
*, int);
981 int easy_vector_constant (rtx
, enum machine_mode
);
982 static rtx
rs6000_dwarf_register_span (rtx
);
983 static void rs6000_init_dwarf_reg_sizes_extra (tree
);
984 static rtx
rs6000_legitimize_address (rtx
, rtx
, enum machine_mode
);
985 static rtx
rs6000_debug_legitimize_address (rtx
, rtx
, enum machine_mode
);
986 static rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
987 static rtx
rs6000_delegitimize_address (rtx
);
988 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
989 static rtx
rs6000_tls_get_addr (void);
990 static rtx
rs6000_got_sym (void);
991 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
992 static const char *rs6000_get_some_local_dynamic_name (void);
993 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
994 static rtx
rs6000_complex_function_value (enum machine_mode
);
995 static rtx
rs6000_spe_function_arg (CUMULATIVE_ARGS
*,
996 enum machine_mode
, tree
);
997 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
999 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
1000 tree
, HOST_WIDE_INT
);
1001 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
1004 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
1005 const_tree
, HOST_WIDE_INT
,
1007 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, const_tree
, int, bool);
1008 static rtx
rs6000_mixed_function_arg (enum machine_mode
, tree
, int);
1009 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
1010 static void setup_incoming_varargs (CUMULATIVE_ARGS
*,
1011 enum machine_mode
, tree
,
1013 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
1015 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
1017 static const char *invalid_arg_for_unprototyped_fn (const_tree
, const_tree
, const_tree
);
1019 static void macho_branch_islands (void);
1020 static int no_previous_def (tree function_name
);
1021 static tree
get_prev_label (tree function_name
);
1022 static void rs6000_darwin_file_start (void);
1025 static tree
rs6000_build_builtin_va_list (void);
1026 static void rs6000_va_start (tree
, rtx
);
1027 static tree
rs6000_gimplify_va_arg (tree
, tree
, gimple_seq
*, gimple_seq
*);
1028 static bool rs6000_must_pass_in_stack (enum machine_mode
, const_tree
);
1029 static bool rs6000_scalar_mode_supported_p (enum machine_mode
);
1030 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
1031 static rtx
rs6000_emit_vector_compare_inner (enum rtx_code
, rtx
, rtx
);
1032 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
1034 static tree
rs6000_stack_protect_fail (void);
1036 static rtx
rs6000_legitimize_reload_address (rtx
, enum machine_mode
, int, int,
1039 static rtx
rs6000_debug_legitimize_reload_address (rtx
, enum machine_mode
, int,
1042 rtx (*rs6000_legitimize_reload_address_ptr
) (rtx
, enum machine_mode
, int, int,
1044 = rs6000_legitimize_reload_address
;
1046 static bool rs6000_mode_dependent_address (rtx
);
1047 static bool rs6000_debug_mode_dependent_address (rtx
);
1048 bool (*rs6000_mode_dependent_address_ptr
) (rtx
)
1049 = rs6000_mode_dependent_address
;
1051 static enum reg_class
rs6000_secondary_reload_class (enum reg_class
,
1052 enum machine_mode
, rtx
);
1053 static enum reg_class
rs6000_debug_secondary_reload_class (enum reg_class
,
1056 enum reg_class (*rs6000_secondary_reload_class_ptr
) (enum reg_class
,
1057 enum machine_mode
, rtx
)
1058 = rs6000_secondary_reload_class
;
1060 static enum reg_class
rs6000_preferred_reload_class (rtx
, enum reg_class
);
1061 static enum reg_class
rs6000_debug_preferred_reload_class (rtx
,
1063 enum reg_class (*rs6000_preferred_reload_class_ptr
) (rtx
, enum reg_class
)
1064 = rs6000_preferred_reload_class
;
1066 static bool rs6000_secondary_memory_needed (enum reg_class
, enum reg_class
,
1069 static bool rs6000_debug_secondary_memory_needed (enum reg_class
,
1073 bool (*rs6000_secondary_memory_needed_ptr
) (enum reg_class
, enum reg_class
,
1075 = rs6000_secondary_memory_needed
;
1077 static bool rs6000_cannot_change_mode_class (enum machine_mode
,
1080 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode
,
1084 bool (*rs6000_cannot_change_mode_class_ptr
) (enum machine_mode
,
1087 = rs6000_cannot_change_mode_class
;
1089 static enum reg_class
rs6000_secondary_reload (bool, rtx
, enum reg_class
,
1091 struct secondary_reload_info
*);
1093 static const enum reg_class
*rs6000_ira_cover_classes (void);
1095 const int INSN_NOT_AVAILABLE
= -1;
1096 static enum machine_mode
rs6000_eh_return_filter_mode (void);
1097 static bool rs6000_can_eliminate (const int, const int);
1098 static void rs6000_trampoline_init (rtx
, tree
, rtx
);
1100 /* Hash table stuff for keeping track of TOC entries. */
1102 struct GTY(()) toc_hash_struct
1104 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1105 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1107 enum machine_mode key_mode
;
1111 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
1113 /* Hash table to keep track of the argument types for builtin functions. */
1115 struct GTY(()) builtin_hash_struct
1118 enum machine_mode mode
[4]; /* return value + 3 arguments. */
1119 unsigned char uns_p
[4]; /* and whether the types are unsigned. */
1122 static GTY ((param_is (struct builtin_hash_struct
))) htab_t builtin_hash_table
;
1124 /* Default register names. */
1125 char rs6000_reg_names
[][8] =
1127 "0", "1", "2", "3", "4", "5", "6", "7",
1128 "8", "9", "10", "11", "12", "13", "14", "15",
1129 "16", "17", "18", "19", "20", "21", "22", "23",
1130 "24", "25", "26", "27", "28", "29", "30", "31",
1131 "0", "1", "2", "3", "4", "5", "6", "7",
1132 "8", "9", "10", "11", "12", "13", "14", "15",
1133 "16", "17", "18", "19", "20", "21", "22", "23",
1134 "24", "25", "26", "27", "28", "29", "30", "31",
1135 "mq", "lr", "ctr","ap",
1136 "0", "1", "2", "3", "4", "5", "6", "7",
1138 /* AltiVec registers. */
1139 "0", "1", "2", "3", "4", "5", "6", "7",
1140 "8", "9", "10", "11", "12", "13", "14", "15",
1141 "16", "17", "18", "19", "20", "21", "22", "23",
1142 "24", "25", "26", "27", "28", "29", "30", "31",
1144 /* SPE registers. */
1145 "spe_acc", "spefscr",
1146 /* Soft frame pointer. */
1150 #ifdef TARGET_REGNAMES
1151 static const char alt_reg_names
[][8] =
1153 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1154 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1155 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1156 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1157 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1158 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1159 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1160 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1161 "mq", "lr", "ctr", "ap",
1162 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1164 /* AltiVec registers. */
1165 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1166 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1167 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1168 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1170 /* SPE registers. */
1171 "spe_acc", "spefscr",
1172 /* Soft frame pointer. */
1177 /* Table of valid machine attributes. */
1179 static const struct attribute_spec rs6000_attribute_table
[] =
1181 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1182 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
},
1183 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
1184 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
1185 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
1186 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
1187 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1188 SUBTARGET_ATTRIBUTE_TABLE
,
1190 { NULL
, 0, 0, false, false, false, NULL
}
1193 #ifndef MASK_STRICT_ALIGN
1194 #define MASK_STRICT_ALIGN 0
1196 #ifndef TARGET_PROFILE_KERNEL
1197 #define TARGET_PROFILE_KERNEL 0
1198 #define SET_PROFILE_KERNEL(N)
1200 #define SET_PROFILE_KERNEL(N) TARGET_PROFILE_KERNEL = (N)
1203 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1204 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1206 /* Initialize the GCC target structure. */
1207 #undef TARGET_ATTRIBUTE_TABLE
1208 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1209 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1210 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1212 #undef TARGET_ASM_ALIGNED_DI_OP
1213 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1215 /* Default unaligned ops are only provided for ELF. Find the ops needed
1216 for non-ELF systems. */
1217 #ifndef OBJECT_FORMAT_ELF
1219 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1221 #undef TARGET_ASM_UNALIGNED_HI_OP
1222 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1223 #undef TARGET_ASM_UNALIGNED_SI_OP
1224 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1225 #undef TARGET_ASM_UNALIGNED_DI_OP
1226 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1229 #undef TARGET_ASM_UNALIGNED_HI_OP
1230 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1231 #undef TARGET_ASM_UNALIGNED_SI_OP
1232 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1233 #undef TARGET_ASM_UNALIGNED_DI_OP
1234 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1235 #undef TARGET_ASM_ALIGNED_DI_OP
1236 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1240 /* This hook deals with fixups for relocatable code and DI-mode objects
1242 #undef TARGET_ASM_INTEGER
1243 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1245 #ifdef HAVE_GAS_HIDDEN
1246 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1247 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1250 #undef TARGET_HAVE_TLS
1251 #define TARGET_HAVE_TLS HAVE_AS_TLS
1253 #undef TARGET_CANNOT_FORCE_CONST_MEM
1254 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1256 #undef TARGET_ASM_FUNCTION_PROLOGUE
1257 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1258 #undef TARGET_ASM_FUNCTION_EPILOGUE
1259 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1261 #undef TARGET_LEGITIMIZE_ADDRESS
1262 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1264 #undef TARGET_SCHED_VARIABLE_ISSUE
1265 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1267 #undef TARGET_SCHED_ISSUE_RATE
1268 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1269 #undef TARGET_SCHED_ADJUST_COST
1270 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1271 #undef TARGET_SCHED_ADJUST_PRIORITY
1272 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1273 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1274 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1275 #undef TARGET_SCHED_INIT
1276 #define TARGET_SCHED_INIT rs6000_sched_init
1277 #undef TARGET_SCHED_FINISH
1278 #define TARGET_SCHED_FINISH rs6000_sched_finish
1279 #undef TARGET_SCHED_REORDER
1280 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1281 #undef TARGET_SCHED_REORDER2
1282 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1284 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1285 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1287 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1288 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1290 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1291 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1292 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1293 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1294 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1295 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1296 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1297 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1299 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1300 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1301 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1302 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1303 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1304 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1305 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1306 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1307 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1308 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1309 #undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
1310 #define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
1311 rs6000_builtin_support_vector_misalignment
1312 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1313 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1315 #undef TARGET_INIT_BUILTINS
1316 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1318 #undef TARGET_EXPAND_BUILTIN
1319 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1321 #undef TARGET_MANGLE_TYPE
1322 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1324 #undef TARGET_INIT_LIBFUNCS
1325 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1328 #undef TARGET_BINDS_LOCAL_P
1329 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1332 #undef TARGET_MS_BITFIELD_LAYOUT_P
1333 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1335 #undef TARGET_ASM_OUTPUT_MI_THUNK
1336 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1338 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1339 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1341 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1342 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1344 #undef TARGET_INVALID_WITHIN_DOLOOP
1345 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1347 #undef TARGET_RTX_COSTS
1348 #define TARGET_RTX_COSTS rs6000_rtx_costs
1349 #undef TARGET_ADDRESS_COST
1350 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1352 #undef TARGET_DWARF_REGISTER_SPAN
1353 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1355 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1356 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1358 /* On rs6000, function arguments are promoted, as are function return
1360 #undef TARGET_PROMOTE_FUNCTION_MODE
1361 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1363 #undef TARGET_RETURN_IN_MEMORY
1364 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1366 #undef TARGET_SETUP_INCOMING_VARARGS
1367 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1369 /* Always strict argument naming on rs6000. */
1370 #undef TARGET_STRICT_ARGUMENT_NAMING
1371 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1372 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1373 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1374 #undef TARGET_SPLIT_COMPLEX_ARG
1375 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1376 #undef TARGET_MUST_PASS_IN_STACK
1377 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1378 #undef TARGET_PASS_BY_REFERENCE
1379 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1380 #undef TARGET_ARG_PARTIAL_BYTES
1381 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1383 #undef TARGET_BUILD_BUILTIN_VA_LIST
1384 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1386 #undef TARGET_EXPAND_BUILTIN_VA_START
1387 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1389 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1390 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1392 #undef TARGET_EH_RETURN_FILTER_MODE
1393 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1395 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1396 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1398 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1399 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1401 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1402 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1404 #undef TARGET_HANDLE_OPTION
1405 #define TARGET_HANDLE_OPTION rs6000_handle_option
1407 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1408 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1409 rs6000_builtin_vectorized_function
1411 #undef TARGET_DEFAULT_TARGET_FLAGS
1412 #define TARGET_DEFAULT_TARGET_FLAGS \
1415 #undef TARGET_STACK_PROTECT_FAIL
1416 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1418 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1419 The PowerPC architecture requires only weak consistency among
1420 processors--that is, memory accesses between processors need not be
1421 sequentially consistent and memory accesses among processors can occur
1422 in any order. The ability to order memory accesses weakly provides
1423 opportunities for more efficient use of the system bus. Unless a
1424 dependency exists, the 604e allows read operations to precede store
1426 #undef TARGET_RELAXED_ORDERING
1427 #define TARGET_RELAXED_ORDERING true
1430 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1431 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1434 /* Use a 32-bit anchor range. This leads to sequences like:
1436 addis tmp,anchor,high
1439 where tmp itself acts as an anchor, and can be shared between
1440 accesses to the same 64k page. */
1441 #undef TARGET_MIN_ANCHOR_OFFSET
1442 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1443 #undef TARGET_MAX_ANCHOR_OFFSET
1444 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1445 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1446 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1448 #undef TARGET_DELEGITIMIZE_ADDRESS
1449 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1451 #undef TARGET_BUILTIN_RECIPROCAL
1452 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1454 #undef TARGET_EXPAND_TO_RTL_HOOK
1455 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1457 #undef TARGET_INSTANTIATE_DECLS
1458 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1460 #undef TARGET_SECONDARY_RELOAD
1461 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1463 #undef TARGET_IRA_COVER_CLASSES
1464 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1466 #undef TARGET_LEGITIMATE_ADDRESS_P
1467 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1469 #undef TARGET_CAN_ELIMINATE
1470 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1472 #undef TARGET_TRAMPOLINE_INIT
1473 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1475 #undef TARGET_FUNCTION_VALUE
1476 #define TARGET_FUNCTION_VALUE rs6000_function_value
1478 struct gcc_target targetm
= TARGET_INITIALIZER
;
1480 /* Return number of consecutive hard regs needed starting at reg REGNO
1481 to hold something of mode MODE.
1482 This is ordinarily the length in words of a value of mode MODE
1483 but can be less for certain modes in special long registers.
1485 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1486 scalar instructions. The upper 32 bits are only available to the
1489 POWER and PowerPC GPRs hold 32 bits worth;
1490 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1493 rs6000_hard_regno_nregs_internal (int regno
, enum machine_mode mode
)
1495 unsigned HOST_WIDE_INT reg_size
;
1497 if (FP_REGNO_P (regno
))
1498 reg_size
= (VECTOR_MEM_VSX_P (mode
)
1499 ? UNITS_PER_VSX_WORD
1500 : UNITS_PER_FP_WORD
);
1502 else if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1503 reg_size
= UNITS_PER_SPE_WORD
;
1505 else if (ALTIVEC_REGNO_P (regno
))
1506 reg_size
= UNITS_PER_ALTIVEC_WORD
;
1508 /* The value returned for SCmode in the E500 double case is 2 for
1509 ABI compatibility; storing an SCmode value in a single register
1510 would require function_arg and rs6000_spe_function_arg to handle
1511 SCmode so as to pass the value correctly in a pair of
1513 else if (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
) && mode
!= SCmode
1514 && !DECIMAL_FLOAT_MODE_P (mode
))
1515 reg_size
= UNITS_PER_FP_WORD
;
1518 reg_size
= UNITS_PER_WORD
;
1520 return (GET_MODE_SIZE (mode
) + reg_size
- 1) / reg_size
;
1523 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1526 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
1528 int last_regno
= regno
+ rs6000_hard_regno_nregs
[mode
][regno
] - 1;
1530 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1531 implementations. Don't allow an item to be split between a FP register
1532 and an Altivec register. */
1533 if (VECTOR_MEM_VSX_P (mode
))
1535 if (FP_REGNO_P (regno
))
1536 return FP_REGNO_P (last_regno
);
1538 if (ALTIVEC_REGNO_P (regno
))
1539 return ALTIVEC_REGNO_P (last_regno
);
1542 /* The GPRs can hold any mode, but values bigger than one register
1543 cannot go past R31. */
1544 if (INT_REGNO_P (regno
))
1545 return INT_REGNO_P (last_regno
);
1547 /* The float registers (except for VSX vector modes) can only hold floating
1548 modes and DImode. This excludes the 32-bit decimal float mode for
1550 if (FP_REGNO_P (regno
))
1552 if (SCALAR_FLOAT_MODE_P (mode
)
1553 && (mode
!= TDmode
|| (regno
% 2) == 0)
1554 && FP_REGNO_P (last_regno
))
1557 if (GET_MODE_CLASS (mode
) == MODE_INT
1558 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
)
1561 if (PAIRED_SIMD_REGNO_P (regno
) && TARGET_PAIRED_FLOAT
1562 && PAIRED_VECTOR_MODE (mode
))
1568 /* The CR register can only hold CC modes. */
1569 if (CR_REGNO_P (regno
))
1570 return GET_MODE_CLASS (mode
) == MODE_CC
;
1572 if (XER_REGNO_P (regno
))
1573 return mode
== PSImode
;
1575 /* AltiVec only in AldyVec registers. */
1576 if (ALTIVEC_REGNO_P (regno
))
1577 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
);
1579 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1580 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1583 /* We cannot put TImode anywhere except general register and it must be able
1584 to fit within the register set. In the future, allow TImode in the
1585 Altivec or VSX registers. */
1587 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1590 /* Print interesting facts about registers. */
1592 rs6000_debug_reg_print (int first_regno
, int last_regno
, const char *reg_name
)
1596 for (r
= first_regno
; r
<= last_regno
; ++r
)
1598 const char *comma
= "";
1601 if (first_regno
== last_regno
)
1602 fprintf (stderr
, "%s:\t", reg_name
);
1604 fprintf (stderr
, "%s%d:\t", reg_name
, r
- first_regno
);
1607 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1608 if (rs6000_hard_regno_mode_ok_p
[m
][r
] && rs6000_hard_regno_nregs
[m
][r
])
1612 fprintf (stderr
, ",\n\t");
1617 if (rs6000_hard_regno_nregs
[m
][r
] > 1)
1618 len
+= fprintf (stderr
, "%s%s/%d", comma
, GET_MODE_NAME (m
),
1619 rs6000_hard_regno_nregs
[m
][r
]);
1621 len
+= fprintf (stderr
, "%s%s", comma
, GET_MODE_NAME (m
));
1626 if (call_used_regs
[r
])
1630 fprintf (stderr
, ",\n\t");
1635 len
+= fprintf (stderr
, "%s%s", comma
, "call-used");
1643 fprintf (stderr
, ",\n\t");
1648 len
+= fprintf (stderr
, "%s%s", comma
, "fixed");
1654 fprintf (stderr
, ",\n\t");
1658 fprintf (stderr
, "%sregno = %d\n", comma
, r
);
1662 /* Print various interesting information with -mdebug=reg. */
1664 rs6000_debug_reg_global (void)
1666 const char *nl
= (const char *)0;
1668 char costly_num
[20];
1670 const char *costly_str
;
1671 const char *nop_str
;
1673 /* Map enum rs6000_vector to string. */
1674 static const char *rs6000_debug_vector_unit
[] = {
1683 fprintf (stderr
, "Register information: (last virtual reg = %d)\n",
1684 LAST_VIRTUAL_REGISTER
);
1685 rs6000_debug_reg_print (0, 31, "gr");
1686 rs6000_debug_reg_print (32, 63, "fp");
1687 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO
,
1690 rs6000_debug_reg_print (LR_REGNO
, LR_REGNO
, "lr");
1691 rs6000_debug_reg_print (CTR_REGNO
, CTR_REGNO
, "ctr");
1692 rs6000_debug_reg_print (CR0_REGNO
, CR7_REGNO
, "cr");
1693 rs6000_debug_reg_print (MQ_REGNO
, MQ_REGNO
, "mq");
1694 rs6000_debug_reg_print (XER_REGNO
, XER_REGNO
, "xer");
1695 rs6000_debug_reg_print (VRSAVE_REGNO
, VRSAVE_REGNO
, "vrsave");
1696 rs6000_debug_reg_print (VSCR_REGNO
, VSCR_REGNO
, "vscr");
1697 rs6000_debug_reg_print (SPE_ACC_REGNO
, SPE_ACC_REGNO
, "spe_a");
1698 rs6000_debug_reg_print (SPEFSCR_REGNO
, SPEFSCR_REGNO
, "spe_f");
1702 "d reg_class = %s\n"
1703 "f reg_class = %s\n"
1704 "v reg_class = %s\n"
1705 "wa reg_class = %s\n"
1706 "wd reg_class = %s\n"
1707 "wf reg_class = %s\n"
1708 "ws reg_class = %s\n\n",
1709 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_d
]],
1710 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_f
]],
1711 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_v
]],
1712 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wa
]],
1713 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wd
]],
1714 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_wf
]],
1715 reg_class_names
[rs6000_constraints
[RS6000_CONSTRAINT_ws
]]);
1717 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1718 if (rs6000_vector_unit
[m
] || rs6000_vector_mem
[m
])
1721 fprintf (stderr
, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1723 rs6000_debug_vector_unit
[ rs6000_vector_unit
[m
] ],
1724 rs6000_debug_vector_unit
[ rs6000_vector_mem
[m
] ]);
1730 switch (rs6000_sched_costly_dep
)
1732 case max_dep_latency
:
1733 costly_str
= "max_dep_latency";
1737 costly_str
= "no_dep_costly";
1740 case all_deps_costly
:
1741 costly_str
= "all_deps_costly";
1744 case true_store_to_load_dep_costly
:
1745 costly_str
= "true_store_to_load_dep_costly";
1748 case store_to_load_dep_costly
:
1749 costly_str
= "store_to_load_dep_costly";
1753 costly_str
= costly_num
;
1754 sprintf (costly_num
, "%d", (int)rs6000_sched_costly_dep
);
1758 switch (rs6000_sched_insert_nops
)
1760 case sched_finish_regroup_exact
:
1761 nop_str
= "sched_finish_regroup_exact";
1764 case sched_finish_pad_groups
:
1765 nop_str
= "sched_finish_pad_groups";
1768 case sched_finish_none
:
1769 nop_str
= "sched_finish_none";
1774 sprintf (nop_num
, "%d", (int)rs6000_sched_insert_nops
);
1779 "always_hint = %s\n"
1780 "align_branch_targets = %s\n"
1781 "sched_restricted_insns_priority = %d\n"
1782 "sched_costly_dep = %s\n"
1783 "sched_insert_nops = %s\n\n",
1784 rs6000_always_hint
? "true" : "false",
1785 rs6000_align_branch_targets
? "true" : "false",
1786 (int)rs6000_sched_restricted_insns_priority
,
1787 costly_str
, nop_str
);
1790 /* Initialize the various global tables that are based on register size. */
1792 rs6000_init_hard_regno_mode_ok (void)
1798 /* Precalculate REGNO_REG_CLASS. */
1799 rs6000_regno_regclass
[0] = GENERAL_REGS
;
1800 for (r
= 1; r
< 32; ++r
)
1801 rs6000_regno_regclass
[r
] = BASE_REGS
;
1803 for (r
= 32; r
< 64; ++r
)
1804 rs6000_regno_regclass
[r
] = FLOAT_REGS
;
1806 for (r
= 64; r
< FIRST_PSEUDO_REGISTER
; ++r
)
1807 rs6000_regno_regclass
[r
] = NO_REGS
;
1809 for (r
= FIRST_ALTIVEC_REGNO
; r
<= LAST_ALTIVEC_REGNO
; ++r
)
1810 rs6000_regno_regclass
[r
] = ALTIVEC_REGS
;
1812 rs6000_regno_regclass
[CR0_REGNO
] = CR0_REGS
;
1813 for (r
= CR1_REGNO
; r
<= CR7_REGNO
; ++r
)
1814 rs6000_regno_regclass
[r
] = CR_REGS
;
1816 rs6000_regno_regclass
[MQ_REGNO
] = MQ_REGS
;
1817 rs6000_regno_regclass
[LR_REGNO
] = LINK_REGS
;
1818 rs6000_regno_regclass
[CTR_REGNO
] = CTR_REGS
;
1819 rs6000_regno_regclass
[XER_REGNO
] = XER_REGS
;
1820 rs6000_regno_regclass
[VRSAVE_REGNO
] = VRSAVE_REGS
;
1821 rs6000_regno_regclass
[VSCR_REGNO
] = VRSAVE_REGS
;
1822 rs6000_regno_regclass
[SPE_ACC_REGNO
] = SPE_ACC_REGS
;
1823 rs6000_regno_regclass
[SPEFSCR_REGNO
] = SPEFSCR_REGS
;
1824 rs6000_regno_regclass
[ARG_POINTER_REGNUM
] = BASE_REGS
;
1825 rs6000_regno_regclass
[FRAME_POINTER_REGNUM
] = BASE_REGS
;
1827 /* Precalculate vector information, this must be set up before the
1828 rs6000_hard_regno_nregs_internal below. */
1829 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1831 rs6000_vector_unit
[m
] = rs6000_vector_mem
[m
] = VECTOR_NONE
;
1832 rs6000_vector_reload
[m
][0] = CODE_FOR_nothing
;
1833 rs6000_vector_reload
[m
][1] = CODE_FOR_nothing
;
1836 for (c
= 0; c
< (int)(int)RS6000_CONSTRAINT_MAX
; c
++)
1837 rs6000_constraints
[c
] = NO_REGS
;
1839 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1840 believes it can use native alignment or still uses 128-bit alignment. */
1841 if (TARGET_VSX
&& !TARGET_VSX_ALIGN_128
)
1852 /* V2DF mode, VSX only. */
1855 rs6000_vector_unit
[V2DFmode
] = VECTOR_VSX
;
1856 rs6000_vector_mem
[V2DFmode
] = VECTOR_VSX
;
1857 rs6000_vector_align
[V2DFmode
] = align64
;
1860 /* V4SF mode, either VSX or Altivec. */
1863 rs6000_vector_unit
[V4SFmode
] = VECTOR_VSX
;
1864 rs6000_vector_mem
[V4SFmode
] = VECTOR_VSX
;
1865 rs6000_vector_align
[V4SFmode
] = align32
;
1867 else if (TARGET_ALTIVEC
)
1869 rs6000_vector_unit
[V4SFmode
] = VECTOR_ALTIVEC
;
1870 rs6000_vector_mem
[V4SFmode
] = VECTOR_ALTIVEC
;
1871 rs6000_vector_align
[V4SFmode
] = align32
;
1874 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
1878 rs6000_vector_unit
[V4SImode
] = VECTOR_ALTIVEC
;
1879 rs6000_vector_unit
[V8HImode
] = VECTOR_ALTIVEC
;
1880 rs6000_vector_unit
[V16QImode
] = VECTOR_ALTIVEC
;
1881 rs6000_vector_align
[V4SImode
] = align32
;
1882 rs6000_vector_align
[V8HImode
] = align32
;
1883 rs6000_vector_align
[V16QImode
] = align32
;
1887 rs6000_vector_mem
[V4SImode
] = VECTOR_VSX
;
1888 rs6000_vector_mem
[V8HImode
] = VECTOR_VSX
;
1889 rs6000_vector_mem
[V16QImode
] = VECTOR_VSX
;
1893 rs6000_vector_mem
[V4SImode
] = VECTOR_ALTIVEC
;
1894 rs6000_vector_mem
[V8HImode
] = VECTOR_ALTIVEC
;
1895 rs6000_vector_mem
[V16QImode
] = VECTOR_ALTIVEC
;
1899 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
1900 Altivec doesn't have 64-bit support. */
1903 rs6000_vector_mem
[V2DImode
] = VECTOR_VSX
;
1904 rs6000_vector_unit
[V2DImode
] = VECTOR_NONE
;
1905 rs6000_vector_align
[V2DImode
] = align64
;
1908 /* DFmode, see if we want to use the VSX unit. */
1909 if (TARGET_VSX
&& TARGET_VSX_SCALAR_DOUBLE
)
1911 rs6000_vector_unit
[DFmode
] = VECTOR_VSX
;
1912 rs6000_vector_mem
[DFmode
]
1913 = (TARGET_VSX_SCALAR_MEMORY
? VECTOR_VSX
: VECTOR_NONE
);
1914 rs6000_vector_align
[DFmode
] = align64
;
1917 /* TODO add SPE and paired floating point vector support. */
1919 /* Register class constaints for the constraints that depend on compile
1921 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
1922 rs6000_constraints
[RS6000_CONSTRAINT_f
] = FLOAT_REGS
;
1924 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
1925 rs6000_constraints
[RS6000_CONSTRAINT_d
] = FLOAT_REGS
;
1929 /* At present, we just use VSX_REGS, but we have different constraints
1930 based on the use, in case we want to fine tune the default register
1931 class used. wa = any VSX register, wf = register class to use for
1932 V4SF, wd = register class to use for V2DF, and ws = register classs to
1933 use for DF scalars. */
1934 rs6000_constraints
[RS6000_CONSTRAINT_wa
] = VSX_REGS
;
1935 rs6000_constraints
[RS6000_CONSTRAINT_wf
] = VSX_REGS
;
1936 rs6000_constraints
[RS6000_CONSTRAINT_wd
] = VSX_REGS
;
1937 if (TARGET_VSX_SCALAR_DOUBLE
)
1938 rs6000_constraints
[RS6000_CONSTRAINT_ws
] = VSX_REGS
;
1942 rs6000_constraints
[RS6000_CONSTRAINT_v
] = ALTIVEC_REGS
;
1944 /* Set up the reload helper functions. */
1945 if (TARGET_VSX
|| TARGET_ALTIVEC
)
1949 rs6000_vector_reload
[V16QImode
][0] = CODE_FOR_reload_v16qi_di_store
;
1950 rs6000_vector_reload
[V16QImode
][1] = CODE_FOR_reload_v16qi_di_load
;
1951 rs6000_vector_reload
[V8HImode
][0] = CODE_FOR_reload_v8hi_di_store
;
1952 rs6000_vector_reload
[V8HImode
][1] = CODE_FOR_reload_v8hi_di_load
;
1953 rs6000_vector_reload
[V4SImode
][0] = CODE_FOR_reload_v4si_di_store
;
1954 rs6000_vector_reload
[V4SImode
][1] = CODE_FOR_reload_v4si_di_load
;
1955 rs6000_vector_reload
[V2DImode
][0] = CODE_FOR_reload_v2di_di_store
;
1956 rs6000_vector_reload
[V2DImode
][1] = CODE_FOR_reload_v2di_di_load
;
1957 rs6000_vector_reload
[V4SFmode
][0] = CODE_FOR_reload_v4sf_di_store
;
1958 rs6000_vector_reload
[V4SFmode
][1] = CODE_FOR_reload_v4sf_di_load
;
1959 rs6000_vector_reload
[V2DFmode
][0] = CODE_FOR_reload_v2df_di_store
;
1960 rs6000_vector_reload
[V2DFmode
][1] = CODE_FOR_reload_v2df_di_load
;
1964 rs6000_vector_reload
[V16QImode
][0] = CODE_FOR_reload_v16qi_si_store
;
1965 rs6000_vector_reload
[V16QImode
][1] = CODE_FOR_reload_v16qi_si_load
;
1966 rs6000_vector_reload
[V8HImode
][0] = CODE_FOR_reload_v8hi_si_store
;
1967 rs6000_vector_reload
[V8HImode
][1] = CODE_FOR_reload_v8hi_si_load
;
1968 rs6000_vector_reload
[V4SImode
][0] = CODE_FOR_reload_v4si_si_store
;
1969 rs6000_vector_reload
[V4SImode
][1] = CODE_FOR_reload_v4si_si_load
;
1970 rs6000_vector_reload
[V2DImode
][0] = CODE_FOR_reload_v2di_si_store
;
1971 rs6000_vector_reload
[V2DImode
][1] = CODE_FOR_reload_v2di_si_load
;
1972 rs6000_vector_reload
[V4SFmode
][0] = CODE_FOR_reload_v4sf_si_store
;
1973 rs6000_vector_reload
[V4SFmode
][1] = CODE_FOR_reload_v4sf_si_load
;
1974 rs6000_vector_reload
[V2DFmode
][0] = CODE_FOR_reload_v2df_si_store
;
1975 rs6000_vector_reload
[V2DFmode
][1] = CODE_FOR_reload_v2df_si_load
;
1979 /* Precalculate HARD_REGNO_NREGS. */
1980 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
1981 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1982 rs6000_hard_regno_nregs
[m
][r
]
1983 = rs6000_hard_regno_nregs_internal (r
, (enum machine_mode
)m
);
1985 /* Precalculate HARD_REGNO_MODE_OK. */
1986 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
1987 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1988 if (rs6000_hard_regno_mode_ok (r
, (enum machine_mode
)m
))
1989 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
1991 /* Precalculate CLASS_MAX_NREGS sizes. */
1992 for (c
= 0; c
< LIM_REG_CLASSES
; ++c
)
1996 if (TARGET_VSX
&& VSX_REG_CLASS_P (c
))
1997 reg_size
= UNITS_PER_VSX_WORD
;
1999 else if (c
== ALTIVEC_REGS
)
2000 reg_size
= UNITS_PER_ALTIVEC_WORD
;
2002 else if (c
== FLOAT_REGS
)
2003 reg_size
= UNITS_PER_FP_WORD
;
2006 reg_size
= UNITS_PER_WORD
;
2008 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
2009 rs6000_class_max_nregs
[m
][c
]
2010 = (GET_MODE_SIZE (m
) + reg_size
- 1) / reg_size
;
2013 if (TARGET_E500_DOUBLE
)
2014 rs6000_class_max_nregs
[DFmode
][GENERAL_REGS
] = 1;
2016 if (TARGET_DEBUG_REG
)
2017 rs6000_debug_reg_global ();
2021 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2024 darwin_rs6000_override_options (void)
2026 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2028 rs6000_altivec_abi
= 1;
2029 TARGET_ALTIVEC_VRSAVE
= 1;
2030 if (DEFAULT_ABI
== ABI_DARWIN
)
2032 if (MACHO_DYNAMIC_NO_PIC_P
)
2035 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2038 else if (flag_pic
== 1)
2043 if (TARGET_64BIT
&& ! TARGET_POWERPC64
)
2045 target_flags
|= MASK_POWERPC64
;
2046 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2050 rs6000_default_long_calls
= 1;
2051 target_flags
|= MASK_SOFT_FLOAT
;
2054 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2056 if (!flag_mkernel
&& !flag_apple_kext
2058 && ! (target_flags_explicit
& MASK_ALTIVEC
))
2059 target_flags
|= MASK_ALTIVEC
;
2061 /* Unless the user (not the configurer) has explicitly overridden
2062 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2063 G4 unless targetting the kernel. */
2066 && strverscmp (darwin_macosx_version_min
, "10.5") >= 0
2067 && ! (target_flags_explicit
& MASK_ALTIVEC
)
2068 && ! rs6000_select
[1].string
)
2070 target_flags
|= MASK_ALTIVEC
;
2075 /* If not otherwise specified by a target, make 'long double' equivalent to
2078 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2079 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2082 /* Override command line options. Mostly we process the processor
2083 type and sometimes adjust other TARGET_ options. */
2086 rs6000_override_options (const char *default_cpu
)
2089 struct rs6000_cpu_select
*ptr
;
2092 /* Simplifications for entries below. */
2095 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
2096 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
2099 /* This table occasionally claims that a processor does not support
2100 a particular feature even though it does, but the feature is slower
2101 than the alternative. Thus, it shouldn't be relied on as a
2102 complete description of the processor's support.
2104 Please keep this list in order, and don't forget to update the
2105 documentation in invoke.texi when adding a new processor or
2109 const char *const name
; /* Canonical processor name. */
2110 const enum processor_type processor
; /* Processor type enum value. */
2111 const int target_enable
; /* Target flags to enable. */
2112 } const processor_target_table
[]
2113 = {{"401", PROCESSOR_PPC403
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2114 {"403", PROCESSOR_PPC403
,
2115 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_STRICT_ALIGN
},
2116 {"405", PROCESSOR_PPC405
,
2117 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
2118 {"405fp", PROCESSOR_PPC405
,
2119 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
2120 {"440", PROCESSOR_PPC440
,
2121 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
2122 {"440fp", PROCESSOR_PPC440
,
2123 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
2124 {"464", PROCESSOR_PPC440
,
2125 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
2126 {"464fp", PROCESSOR_PPC440
,
2127 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
2128 {"505", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
},
2129 {"601", PROCESSOR_PPC601
,
2130 MASK_POWER
| POWERPC_BASE_MASK
| MASK_MULTIPLE
| MASK_STRING
},
2131 {"602", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2132 {"603", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2133 {"603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2134 {"604", PROCESSOR_PPC604
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2135 {"604e", PROCESSOR_PPC604e
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2136 {"620", PROCESSOR_PPC620
,
2137 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
2138 {"630", PROCESSOR_PPC630
,
2139 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
2140 {"740", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2141 {"7400", PROCESSOR_PPC7400
, POWERPC_7400_MASK
},
2142 {"7450", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
2143 {"750", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2144 {"801", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2145 {"821", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2146 {"823", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2147 {"8540", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
2149 /* 8548 has a dummy entry for now. */
2150 {"8548", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
2152 {"e300c2", PROCESSOR_PPCE300C2
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2153 {"e300c3", PROCESSOR_PPCE300C3
, POWERPC_BASE_MASK
},
2154 {"e500mc", PROCESSOR_PPCE500MC
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
2156 {"860", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2157 {"970", PROCESSOR_POWER4
,
2158 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
2159 {"cell", PROCESSOR_CELL
,
2160 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
2161 {"common", PROCESSOR_COMMON
, MASK_NEW_MNEMONICS
},
2162 {"ec603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
2163 {"G3", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
2164 {"G4", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
2165 {"G5", PROCESSOR_POWER4
,
2166 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
2167 {"power", PROCESSOR_POWER
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
2168 {"power2", PROCESSOR_POWER
,
2169 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
2170 {"power3", PROCESSOR_PPC630
,
2171 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
2172 {"power4", PROCESSOR_POWER4
,
2173 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
2175 {"power5", PROCESSOR_POWER5
,
2176 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
2177 | MASK_MFCRF
| MASK_POPCNTB
},
2178 {"power5+", PROCESSOR_POWER5
,
2179 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
2180 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
},
2181 {"power6", PROCESSOR_POWER6
,
2182 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
2183 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
},
2184 {"power6x", PROCESSOR_POWER6
,
2185 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
2186 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
2188 {"power7", PROCESSOR_POWER7
,
2189 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_MFCRF
2190 | MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
| MASK_POPCNTD
2191 | MASK_VSX
}, /* Don't add MASK_ISEL by default */
2192 {"powerpc", PROCESSOR_POWERPC
, POWERPC_BASE_MASK
},
2193 {"powerpc64", PROCESSOR_POWERPC64
,
2194 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
2195 {"rios", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
2196 {"rios1", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
2197 {"rios2", PROCESSOR_RIOS2
,
2198 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
2199 {"rsc", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
2200 {"rsc1", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
2201 {"rs64", PROCESSOR_RS64A
,
2202 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
}
2205 const size_t ptt_size
= ARRAY_SIZE (processor_target_table
);
2207 /* Some OSs don't support saving the high part of 64-bit registers on
2208 context switch. Other OSs don't support saving Altivec registers.
2209 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2210 settings; if the user wants either, the user must explicitly specify
2211 them and we won't interfere with the user's specification. */
2214 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
2215 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
| MASK_STRICT_ALIGN
2216 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
2217 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_MULHW
2218 | MASK_DLMZB
| MASK_CMPB
| MASK_MFPGPR
| MASK_DFP
2219 | MASK_POPCNTD
| MASK_VSX
| MASK_ISEL
)
2222 /* Set the pointer size. */
2225 rs6000_pmode
= (int)DImode
;
2226 rs6000_pointer_size
= 64;
2230 rs6000_pmode
= (int)SImode
;
2231 rs6000_pointer_size
= 32;
2234 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
2235 #ifdef OS_MISSING_POWERPC64
2236 if (OS_MISSING_POWERPC64
)
2237 set_masks
&= ~MASK_POWERPC64
;
2239 #ifdef OS_MISSING_ALTIVEC
2240 if (OS_MISSING_ALTIVEC
)
2241 set_masks
&= ~MASK_ALTIVEC
;
2244 /* Don't override by the processor default if given explicitly. */
2245 set_masks
&= ~target_flags_explicit
;
2247 /* Identify the processor type. */
2248 rs6000_select
[0].string
= default_cpu
;
2249 rs6000_cpu
= TARGET_POWERPC64
? PROCESSOR_DEFAULT64
: PROCESSOR_DEFAULT
;
2251 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
2253 ptr
= &rs6000_select
[i
];
2254 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
2256 for (j
= 0; j
< ptt_size
; j
++)
2257 if (! strcmp (ptr
->string
, processor_target_table
[j
].name
))
2259 if (ptr
->set_tune_p
)
2260 rs6000_cpu
= processor_target_table
[j
].processor
;
2262 if (ptr
->set_arch_p
)
2264 target_flags
&= ~set_masks
;
2265 target_flags
|= (processor_target_table
[j
].target_enable
2272 error ("bad value (%s) for %s switch", ptr
->string
, ptr
->name
);
2276 if (rs6000_cpu
== PROCESSOR_PPCE300C2
|| rs6000_cpu
== PROCESSOR_PPCE300C3
2277 || rs6000_cpu
== PROCESSOR_PPCE500MC
)
2280 error ("AltiVec not supported in this target");
2282 error ("Spe not supported in this target");
2285 /* Disable Cell microcode if we are optimizing for the Cell
2286 and not optimizing for size. */
2287 if (rs6000_gen_cell_microcode
== -1)
2288 rs6000_gen_cell_microcode
= !(rs6000_cpu
== PROCESSOR_CELL
2291 /* If we are optimizing big endian systems for space, use the load/store
2292 multiple and string instructions unless we are not generating
2294 if (BYTES_BIG_ENDIAN
&& optimize_size
&& !rs6000_gen_cell_microcode
)
2295 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
2297 /* Don't allow -mmultiple or -mstring on little endian systems
2298 unless the cpu is a 750, because the hardware doesn't support the
2299 instructions used in little endian mode, and causes an alignment
2300 trap. The 750 does not cause an alignment trap (except when the
2301 target is unaligned). */
2303 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
2305 if (TARGET_MULTIPLE
)
2307 target_flags
&= ~MASK_MULTIPLE
;
2308 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
2309 warning (0, "-mmultiple is not supported on little endian systems");
2314 target_flags
&= ~MASK_STRING
;
2315 if ((target_flags_explicit
& MASK_STRING
) != 0)
2316 warning (0, "-mstring is not supported on little endian systems");
2320 /* Add some warnings for VSX. Enable -maltivec unless the user explicitly
2321 used -mno-altivec */
2324 const char *msg
= NULL
;
2325 if (!TARGET_HARD_FLOAT
|| !TARGET_FPRS
2326 || !TARGET_SINGLE_FLOAT
|| !TARGET_DOUBLE_FLOAT
)
2328 if (target_flags_explicit
& MASK_VSX
)
2329 msg
= N_("-mvsx requires hardware floating point");
2331 target_flags
&= ~ MASK_VSX
;
2333 else if (TARGET_PAIRED_FLOAT
)
2334 msg
= N_("-mvsx and -mpaired are incompatible");
2335 /* The hardware will allow VSX and little endian, but until we make sure
2336 things like vector select, etc. work don't allow VSX on little endian
2337 systems at this point. */
2338 else if (!BYTES_BIG_ENDIAN
)
2339 msg
= N_("-mvsx used with little endian code");
2340 else if (TARGET_AVOID_XFORM
> 0)
2341 msg
= N_("-mvsx needs indexed addressing");
2346 target_flags
&= ~ MASK_VSX
;
2348 else if (TARGET_VSX
&& !TARGET_ALTIVEC
2349 && (target_flags_explicit
& MASK_ALTIVEC
) == 0)
2350 target_flags
|= MASK_ALTIVEC
;
2353 /* Set debug flags */
2354 if (rs6000_debug_name
)
2356 if (! strcmp (rs6000_debug_name
, "all"))
2357 rs6000_debug_stack
= rs6000_debug_arg
= rs6000_debug_reg
2358 = rs6000_debug_addr
= rs6000_debug_cost
= 1;
2359 else if (! strcmp (rs6000_debug_name
, "stack"))
2360 rs6000_debug_stack
= 1;
2361 else if (! strcmp (rs6000_debug_name
, "arg"))
2362 rs6000_debug_arg
= 1;
2363 else if (! strcmp (rs6000_debug_name
, "reg"))
2364 rs6000_debug_reg
= 1;
2365 else if (! strcmp (rs6000_debug_name
, "addr"))
2366 rs6000_debug_addr
= 1;
2367 else if (! strcmp (rs6000_debug_name
, "cost"))
2368 rs6000_debug_cost
= 1;
2370 error ("unknown -mdebug-%s switch", rs6000_debug_name
);
2372 /* If the appropriate debug option is enabled, replace the target hooks
2373 with debug versions that call the real version and then prints
2374 debugging information. */
2375 if (TARGET_DEBUG_COST
)
2377 targetm
.rtx_costs
= rs6000_debug_rtx_costs
;
2378 targetm
.address_cost
= rs6000_debug_address_cost
;
2379 targetm
.sched
.adjust_cost
= rs6000_debug_adjust_cost
;
2382 if (TARGET_DEBUG_ADDR
)
2384 targetm
.legitimate_address_p
= rs6000_debug_legitimate_address_p
;
2385 targetm
.legitimize_address
= rs6000_debug_legitimize_address
;
2386 rs6000_secondary_reload_class_ptr
2387 = rs6000_debug_secondary_reload_class
;
2388 rs6000_secondary_memory_needed_ptr
2389 = rs6000_debug_secondary_memory_needed
;
2390 rs6000_cannot_change_mode_class_ptr
2391 = rs6000_debug_cannot_change_mode_class
;
2392 rs6000_preferred_reload_class_ptr
2393 = rs6000_debug_preferred_reload_class
;
2394 rs6000_legitimize_reload_address_ptr
2395 = rs6000_debug_legitimize_reload_address
;
2396 rs6000_mode_dependent_address_ptr
2397 = rs6000_debug_mode_dependent_address
;
2401 if (rs6000_traceback_name
)
2403 if (! strncmp (rs6000_traceback_name
, "full", 4))
2404 rs6000_traceback
= traceback_full
;
2405 else if (! strncmp (rs6000_traceback_name
, "part", 4))
2406 rs6000_traceback
= traceback_part
;
2407 else if (! strncmp (rs6000_traceback_name
, "no", 2))
2408 rs6000_traceback
= traceback_none
;
2410 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2411 rs6000_traceback_name
);
2414 if (!rs6000_explicit_options
.long_double
)
2415 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2417 #ifndef POWERPC_LINUX
2418 if (!rs6000_explicit_options
.ieee
)
2419 rs6000_ieeequad
= 1;
2422 /* Enable Altivec ABI for AIX -maltivec. */
2423 if (TARGET_XCOFF
&& (TARGET_ALTIVEC
|| TARGET_VSX
))
2424 rs6000_altivec_abi
= 1;
2426 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2427 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2428 be explicitly overridden in either case. */
2431 if (!rs6000_explicit_options
.altivec_abi
2432 && (TARGET_64BIT
|| TARGET_ALTIVEC
|| TARGET_VSX
))
2433 rs6000_altivec_abi
= 1;
2435 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2436 if (!rs6000_explicit_options
.vrsave
)
2437 TARGET_ALTIVEC_VRSAVE
= rs6000_altivec_abi
;
2440 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2441 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
2443 rs6000_darwin64_abi
= 1;
2445 darwin_one_byte_bool
= 1;
2447 /* Default to natural alignment, for better performance. */
2448 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
2451 /* Place FP constants in the constant pool instead of TOC
2452 if section anchors enabled. */
2453 if (flag_section_anchors
)
2454 TARGET_NO_FP_IN_TOC
= 1;
2456 /* Handle -mtls-size option. */
2457 rs6000_parse_tls_size_option ();
2459 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2460 SUBTARGET_OVERRIDE_OPTIONS
;
2462 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2463 SUBSUBTARGET_OVERRIDE_OPTIONS
;
2465 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2466 SUB3TARGET_OVERRIDE_OPTIONS
;
2469 if (TARGET_E500
|| rs6000_cpu
== PROCESSOR_PPCE500MC
)
2471 /* The e500 and e500mc do not have string instructions, and we set
2472 MASK_STRING above when optimizing for size. */
2473 if ((target_flags
& MASK_STRING
) != 0)
2474 target_flags
= target_flags
& ~MASK_STRING
;
2476 else if (rs6000_select
[1].string
!= NULL
)
2478 /* For the powerpc-eabispe configuration, we set all these by
2479 default, so let's unset them if we manually set another
2480 CPU that is not the E500. */
2481 if (!rs6000_explicit_options
.spe_abi
)
2483 if (!rs6000_explicit_options
.spe
)
2485 if (!rs6000_explicit_options
.float_gprs
)
2486 rs6000_float_gprs
= 0;
2487 if (!(target_flags_explicit
& MASK_ISEL
))
2488 target_flags
&= ~MASK_ISEL
;
2491 /* Detect invalid option combinations with E500. */
2494 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
2495 && rs6000_cpu
!= PROCESSOR_POWER5
2496 && rs6000_cpu
!= PROCESSOR_POWER6
2497 && rs6000_cpu
!= PROCESSOR_POWER7
2498 && rs6000_cpu
!= PROCESSOR_CELL
);
2499 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
2500 || rs6000_cpu
== PROCESSOR_POWER5
2501 || rs6000_cpu
== PROCESSOR_POWER7
);
2502 rs6000_align_branch_targets
= (rs6000_cpu
== PROCESSOR_POWER4
2503 || rs6000_cpu
== PROCESSOR_POWER5
2504 || rs6000_cpu
== PROCESSOR_POWER6
2505 || rs6000_cpu
== PROCESSOR_POWER7
);
2507 /* Allow debug switches to override the above settings. */
2508 if (TARGET_ALWAYS_HINT
> 0)
2509 rs6000_always_hint
= TARGET_ALWAYS_HINT
;
2511 if (TARGET_SCHED_GROUPS
> 0)
2512 rs6000_sched_groups
= TARGET_SCHED_GROUPS
;
2514 if (TARGET_ALIGN_BRANCH_TARGETS
> 0)
2515 rs6000_align_branch_targets
= TARGET_ALIGN_BRANCH_TARGETS
;
2517 rs6000_sched_restricted_insns_priority
2518 = (rs6000_sched_groups
? 1 : 0);
2520 /* Handle -msched-costly-dep option. */
2521 rs6000_sched_costly_dep
2522 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
2524 if (rs6000_sched_costly_dep_str
)
2526 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
2527 rs6000_sched_costly_dep
= no_dep_costly
;
2528 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
2529 rs6000_sched_costly_dep
= all_deps_costly
;
2530 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
2531 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
2532 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
2533 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
2535 rs6000_sched_costly_dep
= ((enum rs6000_dependence_cost
)
2536 atoi (rs6000_sched_costly_dep_str
));
2539 /* Handle -minsert-sched-nops option. */
2540 rs6000_sched_insert_nops
2541 = (rs6000_sched_groups
? sched_finish_regroup_exact
: sched_finish_none
);
2543 if (rs6000_sched_insert_nops_str
)
2545 if (! strcmp (rs6000_sched_insert_nops_str
, "no"))
2546 rs6000_sched_insert_nops
= sched_finish_none
;
2547 else if (! strcmp (rs6000_sched_insert_nops_str
, "pad"))
2548 rs6000_sched_insert_nops
= sched_finish_pad_groups
;
2549 else if (! strcmp (rs6000_sched_insert_nops_str
, "regroup_exact"))
2550 rs6000_sched_insert_nops
= sched_finish_regroup_exact
;
2552 rs6000_sched_insert_nops
= ((enum rs6000_nop_insertion
)
2553 atoi (rs6000_sched_insert_nops_str
));
2556 #ifdef TARGET_REGNAMES
2557 /* If the user desires alternate register names, copy in the
2558 alternate names now. */
2559 if (TARGET_REGNAMES
)
2560 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
2563 /* Set aix_struct_return last, after the ABI is determined.
2564 If -maix-struct-return or -msvr4-struct-return was explicitly
2565 used, don't override with the ABI default. */
2566 if (!rs6000_explicit_options
.aix_struct_ret
)
2567 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
2569 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
2570 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
2573 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
2575 /* We can only guarantee the availability of DI pseudo-ops when
2576 assembling for 64-bit targets. */
2579 targetm
.asm_out
.aligned_op
.di
= NULL
;
2580 targetm
.asm_out
.unaligned_op
.di
= NULL
;
2583 /* Set branch target alignment, if not optimizing for size. */
2586 /* Cell wants to be aligned 8byte for dual issue. */
2587 if (rs6000_cpu
== PROCESSOR_CELL
)
2589 if (align_functions
<= 0)
2590 align_functions
= 8;
2591 if (align_jumps
<= 0)
2593 if (align_loops
<= 0)
2596 if (rs6000_align_branch_targets
)
2598 if (align_functions
<= 0)
2599 align_functions
= 16;
2600 if (align_jumps
<= 0)
2602 if (align_loops
<= 0)
2605 if (align_jumps_max_skip
<= 0)
2606 align_jumps_max_skip
= 15;
2607 if (align_loops_max_skip
<= 0)
2608 align_loops_max_skip
= 15;
2611 /* Arrange to save and restore machine status around nested functions. */
2612 init_machine_status
= rs6000_init_machine_status
;
2614 /* We should always be splitting complex arguments, but we can't break
2615 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2616 if (DEFAULT_ABI
!= ABI_AIX
)
2617 targetm
.calls
.split_complex_arg
= NULL
;
2619 /* Initialize rs6000_cost with the appropriate target costs. */
2621 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
2625 case PROCESSOR_RIOS1
:
2626 rs6000_cost
= &rios1_cost
;
2629 case PROCESSOR_RIOS2
:
2630 rs6000_cost
= &rios2_cost
;
2633 case PROCESSOR_RS64A
:
2634 rs6000_cost
= &rs64a_cost
;
2637 case PROCESSOR_MPCCORE
:
2638 rs6000_cost
= &mpccore_cost
;
2641 case PROCESSOR_PPC403
:
2642 rs6000_cost
= &ppc403_cost
;
2645 case PROCESSOR_PPC405
:
2646 rs6000_cost
= &ppc405_cost
;
2649 case PROCESSOR_PPC440
:
2650 rs6000_cost
= &ppc440_cost
;
2653 case PROCESSOR_PPC601
:
2654 rs6000_cost
= &ppc601_cost
;
2657 case PROCESSOR_PPC603
:
2658 rs6000_cost
= &ppc603_cost
;
2661 case PROCESSOR_PPC604
:
2662 rs6000_cost
= &ppc604_cost
;
2665 case PROCESSOR_PPC604e
:
2666 rs6000_cost
= &ppc604e_cost
;
2669 case PROCESSOR_PPC620
:
2670 rs6000_cost
= &ppc620_cost
;
2673 case PROCESSOR_PPC630
:
2674 rs6000_cost
= &ppc630_cost
;
2677 case PROCESSOR_CELL
:
2678 rs6000_cost
= &ppccell_cost
;
2681 case PROCESSOR_PPC750
:
2682 case PROCESSOR_PPC7400
:
2683 rs6000_cost
= &ppc750_cost
;
2686 case PROCESSOR_PPC7450
:
2687 rs6000_cost
= &ppc7450_cost
;
2690 case PROCESSOR_PPC8540
:
2691 rs6000_cost
= &ppc8540_cost
;
2694 case PROCESSOR_PPCE300C2
:
2695 case PROCESSOR_PPCE300C3
:
2696 rs6000_cost
= &ppce300c2c3_cost
;
2699 case PROCESSOR_PPCE500MC
:
2700 rs6000_cost
= &ppce500mc_cost
;
2703 case PROCESSOR_POWER4
:
2704 case PROCESSOR_POWER5
:
2705 rs6000_cost
= &power4_cost
;
2708 case PROCESSOR_POWER6
:
2709 rs6000_cost
= &power6_cost
;
2712 case PROCESSOR_POWER7
:
2713 rs6000_cost
= &power7_cost
;
2720 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES
))
2721 set_param_value ("simultaneous-prefetches",
2722 rs6000_cost
->simultaneous_prefetches
);
2723 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE
))
2724 set_param_value ("l1-cache-size", rs6000_cost
->l1_cache_size
);
2725 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE
))
2726 set_param_value ("l1-cache-line-size", rs6000_cost
->cache_line_size
);
2727 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE
))
2728 set_param_value ("l2-cache-size", rs6000_cost
->l2_cache_size
);
2730 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2731 can be optimized to ap = __builtin_next_arg (0). */
2732 if (DEFAULT_ABI
!= ABI_V4
)
2733 targetm
.expand_builtin_va_start
= NULL
;
2735 /* Set up single/double float flags.
2736 If TARGET_HARD_FLOAT is set, but neither single or double is set,
2737 then set both flags. */
2738 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
2739 && rs6000_single_float
== 0 && rs6000_double_float
== 0)
2740 rs6000_single_float
= rs6000_double_float
= 1;
2742 /* Reset single and double FP flags if target is E500. */
2745 rs6000_single_float
= rs6000_double_float
= 0;
2746 if (TARGET_E500_SINGLE
)
2747 rs6000_single_float
= 1;
2748 if (TARGET_E500_DOUBLE
)
2749 rs6000_single_float
= rs6000_double_float
= 1;
2752 /* If not explicitly specified via option, decide whether to generate indexed
2753 load/store instructions. */
2754 if (TARGET_AVOID_XFORM
== -1)
2755 /* Avoid indexed addressing when targeting Power6 in order to avoid
2756 the DERAT mispredict penalty. */
2757 TARGET_AVOID_XFORM
= (rs6000_cpu
== PROCESSOR_POWER6
&& TARGET_CMPB
);
2759 rs6000_init_hard_regno_mode_ok ();
2762 /* Implement targetm.vectorize.builtin_mask_for_load. */
2764 rs6000_builtin_mask_for_load (void)
2766 if (TARGET_ALTIVEC
|| TARGET_VSX
)
2767 return altivec_builtin_mask_for_load
;
2772 /* Implement targetm.vectorize.builtin_conversion.
2773 Returns a decl of a function that implements conversion of an integer vector
2774 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2775 side of the conversion.
2776 Return NULL_TREE if it is not available. */
2778 rs6000_builtin_conversion (unsigned int tcode
, tree type
)
2780 enum tree_code code
= (enum tree_code
) tcode
;
2784 case FIX_TRUNC_EXPR
:
2785 switch (TYPE_MODE (type
))
2788 if (!VECTOR_UNIT_VSX_P (V2DFmode
))
2791 return TYPE_UNSIGNED (type
)
2792 ? rs6000_builtin_decls
[VSX_BUILTIN_XVCVDPUXDS_UNS
]
2793 : rs6000_builtin_decls
[VSX_BUILTIN_XVCVDPSXDS
];
2796 if (VECTOR_UNIT_NONE_P (V4SImode
) || VECTOR_UNIT_NONE_P (V4SFmode
))
2799 return TYPE_UNSIGNED (type
)
2800 ? rs6000_builtin_decls
[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
]
2801 : rs6000_builtin_decls
[VECTOR_BUILTIN_FIX_V4SF_V4SI
];
2808 switch (TYPE_MODE (type
))
2811 if (!VECTOR_UNIT_VSX_P (V2DFmode
))
2814 return TYPE_UNSIGNED (type
)
2815 ? rs6000_builtin_decls
[VSX_BUILTIN_XVCVUXDDP
]
2816 : rs6000_builtin_decls
[VSX_BUILTIN_XVCVSXDDP
];
2819 if (VECTOR_UNIT_NONE_P (V4SImode
) || VECTOR_UNIT_NONE_P (V4SFmode
))
2822 return TYPE_UNSIGNED (type
)
2823 ? rs6000_builtin_decls
[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
]
2824 : rs6000_builtin_decls
[VECTOR_BUILTIN_FLOAT_V4SI_V4SF
];
2835 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2837 rs6000_builtin_mul_widen_even (tree type
)
2839 if (!TARGET_ALTIVEC
)
2842 switch (TYPE_MODE (type
))
2845 return TYPE_UNSIGNED (type
)
2846 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUH_UNS
]
2847 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESH
];
2850 return TYPE_UNSIGNED (type
)
2851 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUB_UNS
]
2852 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESB
];
2858 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2860 rs6000_builtin_mul_widen_odd (tree type
)
2862 if (!TARGET_ALTIVEC
)
2865 switch (TYPE_MODE (type
))
2868 return TYPE_UNSIGNED (type
)
2869 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUH_UNS
]
2870 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSH
];
2873 return TYPE_UNSIGNED (type
)
2874 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUB_UNS
]
2875 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSB
];
2882 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2883 after applying N number of iterations. This routine does not determine
2884 how may iterations are required to reach desired alignment. */
2887 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED
, bool is_packed
)
2894 if (rs6000_alignment_flags
== MASK_ALIGN_NATURAL
)
2897 if (rs6000_alignment_flags
== MASK_ALIGN_POWER
)
2907 /* Assuming that all other types are naturally aligned. CHECKME! */
2912 /* Return true if the vector misalignment factor is supported by the
2915 rs6000_builtin_support_vector_misalignment (enum machine_mode mode
,
2922 /* Return if movmisalign pattern is not supported for this mode. */
2923 if (optab_handler (movmisalign_optab
, mode
)->insn_code
==
2927 if (misalignment
== -1)
2929 /* misalignment factor is unknown at compile time but we know
2930 it's word aligned. */
2931 if (rs6000_vector_alignment_reachable (type
, is_packed
))
2935 /* VSX supports word-aligned vector. */
2936 if (misalignment
% 4 == 0)
2942 /* Implement targetm.vectorize.builtin_vec_perm. */
2944 rs6000_builtin_vec_perm (tree type
, tree
*mask_element_type
)
2946 tree inner_type
= TREE_TYPE (type
);
2947 bool uns_p
= TYPE_UNSIGNED (inner_type
);
2950 *mask_element_type
= unsigned_char_type_node
;
2952 switch (TYPE_MODE (type
))
2956 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_16QI_UNS
]
2957 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_16QI
]);
2962 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_8HI_UNS
]
2963 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_8HI
]);
2968 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SI_UNS
]
2969 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SI
]);
2973 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SF
];
2977 if (!TARGET_ALLOW_DF_PERMUTE
)
2980 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_2DF
];
2984 if (!TARGET_ALLOW_DF_PERMUTE
)
2988 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_2DI_UNS
]
2989 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_2DI
]);
3000 /* Handle generic options of the form -mfoo=yes/no.
3001 NAME is the option name.
3002 VALUE is the option value.
3003 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3004 whether the option value is 'yes' or 'no' respectively. */
3006 rs6000_parse_yes_no_option (const char *name
, const char *value
, int *flag
)
3010 else if (!strcmp (value
, "yes"))
3012 else if (!strcmp (value
, "no"))
3015 error ("unknown -m%s= option specified: '%s'", name
, value
);
3018 /* Validate and record the size specified with the -mtls-size option. */
3021 rs6000_parse_tls_size_option (void)
3023 if (rs6000_tls_size_string
== 0)
3025 else if (strcmp (rs6000_tls_size_string
, "16") == 0)
3026 rs6000_tls_size
= 16;
3027 else if (strcmp (rs6000_tls_size_string
, "32") == 0)
3028 rs6000_tls_size
= 32;
3029 else if (strcmp (rs6000_tls_size_string
, "64") == 0)
3030 rs6000_tls_size
= 64;
3032 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string
);
3036 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
3038 if (DEFAULT_ABI
== ABI_DARWIN
)
3039 /* The Darwin libraries never set errno, so we might as well
3040 avoid calling them when that's the only reason we would. */
3041 flag_errno_math
= 0;
3043 /* Double growth factor to counter reduced min jump length. */
3044 set_param_value ("max-grow-copy-bb-insns", 16);
3046 /* Enable section anchors by default.
3047 Skip section anchors for Objective C and Objective C++
3048 until front-ends fixed. */
3049 if (!TARGET_MACHO
&& lang_hooks
.name
[4] != 'O')
3050 flag_section_anchors
= 2;
3053 static enum fpu_type_t
3054 rs6000_parse_fpu_option (const char *option
)
3056 if (!strcmp("none", option
)) return FPU_NONE
;
3057 if (!strcmp("sp_lite", option
)) return FPU_SF_LITE
;
3058 if (!strcmp("dp_lite", option
)) return FPU_DF_LITE
;
3059 if (!strcmp("sp_full", option
)) return FPU_SF_FULL
;
3060 if (!strcmp("dp_full", option
)) return FPU_DF_FULL
;
3061 error("unknown value %s for -mfpu", option
);
3065 /* Returns a function decl for a vectorized version of the builtin function
3066 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3067 if it is not available. */
3070 rs6000_builtin_vectorized_function (unsigned int fn
, tree type_out
,
3073 enum machine_mode in_mode
, out_mode
;
3076 if (TREE_CODE (type_out
) != VECTOR_TYPE
3077 || TREE_CODE (type_in
) != VECTOR_TYPE
3078 || !TARGET_VECTORIZE_BUILTINS
)
3081 out_mode
= TYPE_MODE (TREE_TYPE (type_out
));
3082 out_n
= TYPE_VECTOR_SUBPARTS (type_out
);
3083 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
3084 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
3088 case BUILT_IN_COPYSIGN
:
3089 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3090 && out_mode
== DFmode
&& out_n
== 2
3091 && in_mode
== DFmode
&& in_n
== 2)
3092 return rs6000_builtin_decls
[VSX_BUILTIN_CPSGNDP
];
3094 case BUILT_IN_COPYSIGNF
:
3095 if (out_mode
!= SFmode
|| out_n
!= 4
3096 || in_mode
!= SFmode
|| in_n
!= 4)
3098 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3099 return rs6000_builtin_decls
[VSX_BUILTIN_CPSGNSP
];
3100 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3101 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_COPYSIGN_V4SF
];
3104 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3105 && out_mode
== DFmode
&& out_n
== 2
3106 && in_mode
== DFmode
&& in_n
== 2)
3107 return rs6000_builtin_decls
[VSX_BUILTIN_XVSQRTDP
];
3109 case BUILT_IN_SQRTF
:
3110 if (VECTOR_UNIT_VSX_P (V4SFmode
)
3111 && out_mode
== SFmode
&& out_n
== 4
3112 && in_mode
== SFmode
&& in_n
== 4)
3113 return rs6000_builtin_decls
[VSX_BUILTIN_XVSQRTSP
];
3116 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3117 && out_mode
== DFmode
&& out_n
== 2
3118 && in_mode
== DFmode
&& in_n
== 2)
3119 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIP
];
3121 case BUILT_IN_CEILF
:
3122 if (out_mode
!= SFmode
|| out_n
!= 4
3123 || in_mode
!= SFmode
|| in_n
!= 4)
3125 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3126 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIP
];
3127 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3128 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIP
];
3130 case BUILT_IN_FLOOR
:
3131 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3132 && out_mode
== DFmode
&& out_n
== 2
3133 && in_mode
== DFmode
&& in_n
== 2)
3134 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIM
];
3136 case BUILT_IN_FLOORF
:
3137 if (out_mode
!= SFmode
|| out_n
!= 4
3138 || in_mode
!= SFmode
|| in_n
!= 4)
3140 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3141 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIM
];
3142 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3143 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIM
];
3145 case BUILT_IN_TRUNC
:
3146 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3147 && out_mode
== DFmode
&& out_n
== 2
3148 && in_mode
== DFmode
&& in_n
== 2)
3149 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIZ
];
3151 case BUILT_IN_TRUNCF
:
3152 if (out_mode
!= SFmode
|| out_n
!= 4
3153 || in_mode
!= SFmode
|| in_n
!= 4)
3155 if (VECTOR_UNIT_VSX_P (V4SFmode
))
3156 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIZ
];
3157 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode
))
3158 return rs6000_builtin_decls
[ALTIVEC_BUILTIN_VRFIZ
];
3160 case BUILT_IN_NEARBYINT
:
3161 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3162 && flag_unsafe_math_optimizations
3163 && out_mode
== DFmode
&& out_n
== 2
3164 && in_mode
== DFmode
&& in_n
== 2)
3165 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPI
];
3167 case BUILT_IN_NEARBYINTF
:
3168 if (VECTOR_UNIT_VSX_P (V4SFmode
)
3169 && flag_unsafe_math_optimizations
3170 && out_mode
== SFmode
&& out_n
== 4
3171 && in_mode
== SFmode
&& in_n
== 4)
3172 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPI
];
3175 if (VECTOR_UNIT_VSX_P (V2DFmode
)
3176 && !flag_trapping_math
3177 && out_mode
== DFmode
&& out_n
== 2
3178 && in_mode
== DFmode
&& in_n
== 2)
3179 return rs6000_builtin_decls
[VSX_BUILTIN_XVRDPIC
];
3181 case BUILT_IN_RINTF
:
3182 if (VECTOR_UNIT_VSX_P (V4SFmode
)
3183 && !flag_trapping_math
3184 && out_mode
== SFmode
&& out_n
== 4
3185 && in_mode
== SFmode
&& in_n
== 4)
3186 return rs6000_builtin_decls
[VSX_BUILTIN_XVRSPIC
];
3195 /* Implement TARGET_HANDLE_OPTION. */
3198 rs6000_handle_option (size_t code
, const char *arg
, int value
)
3200 enum fpu_type_t fpu_type
= FPU_NONE
;
3206 target_flags
&= ~(MASK_POWER
| MASK_POWER2
3207 | MASK_MULTIPLE
| MASK_STRING
);
3208 target_flags_explicit
|= (MASK_POWER
| MASK_POWER2
3209 | MASK_MULTIPLE
| MASK_STRING
);
3211 case OPT_mno_powerpc
:
3212 target_flags
&= ~(MASK_POWERPC
| MASK_PPC_GPOPT
3213 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
3214 target_flags_explicit
|= (MASK_POWERPC
| MASK_PPC_GPOPT
3215 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
3218 target_flags
&= ~MASK_MINIMAL_TOC
;
3219 TARGET_NO_FP_IN_TOC
= 0;
3220 TARGET_NO_SUM_IN_TOC
= 0;
3221 target_flags_explicit
|= MASK_MINIMAL_TOC
;
3222 #ifdef TARGET_USES_SYSV4_OPT
3223 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3224 just the same as -mminimal-toc. */
3225 target_flags
|= MASK_MINIMAL_TOC
;
3226 target_flags_explicit
|= MASK_MINIMAL_TOC
;
3230 #ifdef TARGET_USES_SYSV4_OPT
3232 /* Make -mtoc behave like -mminimal-toc. */
3233 target_flags
|= MASK_MINIMAL_TOC
;
3234 target_flags_explicit
|= MASK_MINIMAL_TOC
;
3238 #ifdef TARGET_USES_AIX64_OPT
3243 target_flags
|= MASK_POWERPC64
| MASK_POWERPC
;
3244 target_flags
|= ~target_flags_explicit
& MASK_PPC_GFXOPT
;
3245 target_flags_explicit
|= MASK_POWERPC64
| MASK_POWERPC
;
3248 #ifdef TARGET_USES_AIX64_OPT
3253 target_flags
&= ~MASK_POWERPC64
;
3254 target_flags_explicit
|= MASK_POWERPC64
;
3257 case OPT_minsert_sched_nops_
:
3258 rs6000_sched_insert_nops_str
= arg
;
3261 case OPT_mminimal_toc
:
3264 TARGET_NO_FP_IN_TOC
= 0;
3265 TARGET_NO_SUM_IN_TOC
= 0;
3272 target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
3273 target_flags_explicit
|= (MASK_MULTIPLE
| MASK_STRING
);
3280 target_flags
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
3281 target_flags_explicit
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
3285 case OPT_mpowerpc_gpopt
:
3286 case OPT_mpowerpc_gfxopt
:
3289 target_flags
|= MASK_POWERPC
;
3290 target_flags_explicit
|= MASK_POWERPC
;
3294 case OPT_maix_struct_return
:
3295 case OPT_msvr4_struct_return
:
3296 rs6000_explicit_options
.aix_struct_ret
= true;
3300 rs6000_explicit_options
.vrsave
= true;
3301 TARGET_ALTIVEC_VRSAVE
= value
;
3305 rs6000_explicit_options
.vrsave
= true;
3306 rs6000_parse_yes_no_option ("vrsave", arg
, &(TARGET_ALTIVEC_VRSAVE
));
3310 target_flags_explicit
|= MASK_ISEL
;
3312 rs6000_parse_yes_no_option ("isel", arg
, &isel
);
3314 target_flags
|= MASK_ISEL
;
3316 target_flags
&= ~MASK_ISEL
;
3320 rs6000_explicit_options
.spe
= true;
3325 rs6000_explicit_options
.spe
= true;
3326 rs6000_parse_yes_no_option ("spe", arg
, &(rs6000_spe
));
3330 rs6000_debug_name
= arg
;
3333 #ifdef TARGET_USES_SYSV4_OPT
3335 rs6000_abi_name
= arg
;
3339 rs6000_sdata_name
= arg
;
3342 case OPT_mtls_size_
:
3343 rs6000_tls_size_string
= arg
;
3346 case OPT_mrelocatable
:
3349 target_flags
|= MASK_MINIMAL_TOC
;
3350 target_flags_explicit
|= MASK_MINIMAL_TOC
;
3351 TARGET_NO_FP_IN_TOC
= 1;
3355 case OPT_mrelocatable_lib
:
3358 target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
3359 target_flags_explicit
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
3360 TARGET_NO_FP_IN_TOC
= 1;
3364 target_flags
&= ~MASK_RELOCATABLE
;
3365 target_flags_explicit
|= MASK_RELOCATABLE
;
3371 if (!strcmp (arg
, "altivec"))
3373 rs6000_explicit_options
.altivec_abi
= true;
3374 rs6000_altivec_abi
= 1;
3376 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3379 else if (! strcmp (arg
, "no-altivec"))
3381 rs6000_explicit_options
.altivec_abi
= true;
3382 rs6000_altivec_abi
= 0;
3384 else if (! strcmp (arg
, "spe"))
3386 rs6000_explicit_options
.spe_abi
= true;
3388 rs6000_altivec_abi
= 0;
3389 if (!TARGET_SPE_ABI
)
3390 error ("not configured for ABI: '%s'", arg
);
3392 else if (! strcmp (arg
, "no-spe"))
3394 rs6000_explicit_options
.spe_abi
= true;
3398 /* These are here for testing during development only, do not
3399 document in the manual please. */
3400 else if (! strcmp (arg
, "d64"))
3402 rs6000_darwin64_abi
= 1;
3403 warning (0, "Using darwin64 ABI");
3405 else if (! strcmp (arg
, "d32"))
3407 rs6000_darwin64_abi
= 0;
3408 warning (0, "Using old darwin ABI");
3411 else if (! strcmp (arg
, "ibmlongdouble"))
3413 rs6000_explicit_options
.ieee
= true;
3414 rs6000_ieeequad
= 0;
3415 warning (0, "Using IBM extended precision long double");
3417 else if (! strcmp (arg
, "ieeelongdouble"))
3419 rs6000_explicit_options
.ieee
= true;
3420 rs6000_ieeequad
= 1;
3421 warning (0, "Using IEEE extended precision long double");
3426 error ("unknown ABI specified: '%s'", arg
);
3432 rs6000_select
[1].string
= arg
;
3436 rs6000_select
[2].string
= arg
;
3439 case OPT_mtraceback_
:
3440 rs6000_traceback_name
= arg
;
3443 case OPT_mfloat_gprs_
:
3444 rs6000_explicit_options
.float_gprs
= true;
3445 if (! strcmp (arg
, "yes") || ! strcmp (arg
, "single"))
3446 rs6000_float_gprs
= 1;
3447 else if (! strcmp (arg
, "double"))
3448 rs6000_float_gprs
= 2;
3449 else if (! strcmp (arg
, "no"))
3450 rs6000_float_gprs
= 0;
3453 error ("invalid option for -mfloat-gprs: '%s'", arg
);
3458 case OPT_mlong_double_
:
3459 rs6000_explicit_options
.long_double
= true;
3460 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
3461 if (value
!= 64 && value
!= 128)
3463 error ("Unknown switch -mlong-double-%s", arg
);
3464 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
3468 rs6000_long_double_type_size
= value
;
3471 case OPT_msched_costly_dep_
:
3472 rs6000_sched_costly_dep_str
= arg
;
3476 rs6000_explicit_options
.alignment
= true;
3477 if (! strcmp (arg
, "power"))
3479 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3480 some C library functions, so warn about it. The flag may be
3481 useful for performance studies from time to time though, so
3482 don't disable it entirely. */
3483 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
3484 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3485 " it is incompatible with the installed C and C++ libraries");
3486 rs6000_alignment_flags
= MASK_ALIGN_POWER
;
3488 else if (! strcmp (arg
, "natural"))
3489 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
3492 error ("unknown -malign-XXXXX option specified: '%s'", arg
);
3497 case OPT_msingle_float
:
3498 if (!TARGET_SINGLE_FPU
)
3499 warning (0, "-msingle-float option equivalent to -mhard-float");
3500 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3501 rs6000_double_float
= 0;
3502 target_flags
&= ~MASK_SOFT_FLOAT
;
3503 target_flags_explicit
|= MASK_SOFT_FLOAT
;
3506 case OPT_mdouble_float
:
3507 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3508 rs6000_single_float
= 1;
3509 target_flags
&= ~MASK_SOFT_FLOAT
;
3510 target_flags_explicit
|= MASK_SOFT_FLOAT
;
3513 case OPT_msimple_fpu
:
3514 if (!TARGET_SINGLE_FPU
)
3515 warning (0, "-msimple-fpu option ignored");
3518 case OPT_mhard_float
:
3519 /* -mhard_float implies -msingle-float and -mdouble-float. */
3520 rs6000_single_float
= rs6000_double_float
= 1;
3523 case OPT_msoft_float
:
3524 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3525 rs6000_single_float
= rs6000_double_float
= 0;
3529 fpu_type
= rs6000_parse_fpu_option(arg
);
3530 if (fpu_type
!= FPU_NONE
)
3531 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3533 target_flags
&= ~MASK_SOFT_FLOAT
;
3534 target_flags_explicit
|= MASK_SOFT_FLOAT
;
3535 rs6000_xilinx_fpu
= 1;
3536 if (fpu_type
== FPU_SF_LITE
|| fpu_type
== FPU_SF_FULL
)
3537 rs6000_single_float
= 1;
3538 if (fpu_type
== FPU_DF_LITE
|| fpu_type
== FPU_DF_FULL
)
3539 rs6000_single_float
= rs6000_double_float
= 1;
3540 if (fpu_type
== FPU_SF_LITE
|| fpu_type
== FPU_DF_LITE
)
3541 rs6000_simple_fpu
= 1;
3545 /* -mfpu=none is equivalent to -msoft-float */
3546 target_flags
|= MASK_SOFT_FLOAT
;
3547 target_flags_explicit
|= MASK_SOFT_FLOAT
;
3548 rs6000_single_float
= rs6000_double_float
= 0;
3555 /* Do anything needed at the start of the asm file. */
3558 rs6000_file_start (void)
3562 const char *start
= buffer
;
3563 struct rs6000_cpu_select
*ptr
;
3564 const char *default_cpu
= TARGET_CPU_DEFAULT
;
3565 FILE *file
= asm_out_file
;
3567 default_file_start ();
3569 #ifdef TARGET_BI_ARCH
3570 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
3574 if (flag_verbose_asm
)
3576 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
3577 rs6000_select
[0].string
= default_cpu
;
3579 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
3581 ptr
= &rs6000_select
[i
];
3582 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
3584 fprintf (file
, "%s %s%s", start
, ptr
->name
, ptr
->string
);
3589 if (PPC405_ERRATUM77
)
3591 fprintf (file
, "%s PPC405CR_ERRATUM77", start
);
3595 #ifdef USING_ELFOS_H
3596 switch (rs6000_sdata
)
3598 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
3599 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
3600 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
3601 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
3604 if (rs6000_sdata
&& g_switch_value
)
3606 fprintf (file
, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED
, start
,
3616 #ifdef HAVE_AS_GNU_ATTRIBUTE
3617 if (TARGET_32BIT
&& DEFAULT_ABI
== ABI_V4
)
3619 fprintf (file
, "\t.gnu_attribute 4, %d\n",
3620 ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
) ? 1
3621 : (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_SINGLE_FLOAT
) ? 3
3623 fprintf (file
, "\t.gnu_attribute 8, %d\n",
3624 (TARGET_ALTIVEC_ABI
? 2
3625 : TARGET_SPE_ABI
? 3
3627 fprintf (file
, "\t.gnu_attribute 12, %d\n",
3628 aix_struct_return
? 2 : 1);
3633 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
3635 switch_to_section (toc_section
);
3636 switch_to_section (text_section
);
3641 /* Return nonzero if this function is known to have a null epilogue. */
3644 direct_return (void)
3646 if (reload_completed
)
3648 rs6000_stack_t
*info
= rs6000_stack_info ();
3650 if (info
->first_gp_reg_save
== 32
3651 && info
->first_fp_reg_save
== 64
3652 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
3653 && ! info
->lr_save_p
3654 && ! info
->cr_save_p
3655 && info
->vrsave_mask
== 0
3663 /* Return the number of instructions it takes to form a constant in an
3664 integer register. */
3667 num_insns_constant_wide (HOST_WIDE_INT value
)
3669 /* signed constant loadable with {cal|addi} */
3670 if ((unsigned HOST_WIDE_INT
) (value
+ 0x8000) < 0x10000)
3673 /* constant loadable with {cau|addis} */
3674 else if ((value
& 0xffff) == 0
3675 && (value
>> 31 == -1 || value
>> 31 == 0))
3678 #if HOST_BITS_PER_WIDE_INT == 64
3679 else if (TARGET_POWERPC64
)
3681 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
3682 HOST_WIDE_INT high
= value
>> 31;
3684 if (high
== 0 || high
== -1)
3690 return num_insns_constant_wide (high
) + 1;
3692 return (num_insns_constant_wide (high
)
3693 + num_insns_constant_wide (low
) + 1);
3702 num_insns_constant (rtx op
, enum machine_mode mode
)
3704 HOST_WIDE_INT low
, high
;
3706 switch (GET_CODE (op
))
3709 #if HOST_BITS_PER_WIDE_INT == 64
3710 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
3711 && mask64_operand (op
, mode
))
3715 return num_insns_constant_wide (INTVAL (op
));
3718 if (mode
== SFmode
|| mode
== SDmode
)
3723 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
3724 if (DECIMAL_FLOAT_MODE_P (mode
))
3725 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
3727 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
3728 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
3731 if (mode
== VOIDmode
|| mode
== DImode
)
3733 high
= CONST_DOUBLE_HIGH (op
);
3734 low
= CONST_DOUBLE_LOW (op
);
3741 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
3742 if (DECIMAL_FLOAT_MODE_P (mode
))
3743 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, l
);
3745 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
3746 high
= l
[WORDS_BIG_ENDIAN
== 0];
3747 low
= l
[WORDS_BIG_ENDIAN
!= 0];
3751 return (num_insns_constant_wide (low
)
3752 + num_insns_constant_wide (high
));
3755 if ((high
== 0 && low
>= 0)
3756 || (high
== -1 && low
< 0))
3757 return num_insns_constant_wide (low
);
3759 else if (mask64_operand (op
, mode
))
3763 return num_insns_constant_wide (high
) + 1;
3766 return (num_insns_constant_wide (high
)
3767 + num_insns_constant_wide (low
) + 1);
3775 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
3776 If the mode of OP is MODE_VECTOR_INT, this simply returns the
3777 corresponding element of the vector, but for V4SFmode and V2SFmode,
3778 the corresponding "float" is interpreted as an SImode integer. */
3781 const_vector_elt_as_int (rtx op
, unsigned int elt
)
3783 rtx tmp
= CONST_VECTOR_ELT (op
, elt
);
3784 if (GET_MODE (op
) == V4SFmode
3785 || GET_MODE (op
) == V2SFmode
)
3786 tmp
= gen_lowpart (SImode
, tmp
);
3787 return INTVAL (tmp
);
3790 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
3791 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
3792 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
3793 all items are set to the same value and contain COPIES replicas of the
3794 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
3795 operand and the others are set to the value of the operand's msb. */
3798 vspltis_constant (rtx op
, unsigned step
, unsigned copies
)
3800 enum machine_mode mode
= GET_MODE (op
);
3801 enum machine_mode inner
= GET_MODE_INNER (mode
);
3804 unsigned nunits
= GET_MODE_NUNITS (mode
);
3805 unsigned bitsize
= GET_MODE_BITSIZE (inner
);
3806 unsigned mask
= GET_MODE_MASK (inner
);
3808 HOST_WIDE_INT val
= const_vector_elt_as_int (op
, nunits
- 1);
3809 HOST_WIDE_INT splat_val
= val
;
3810 HOST_WIDE_INT msb_val
= val
> 0 ? 0 : -1;
3812 /* Construct the value to be splatted, if possible. If not, return 0. */
3813 for (i
= 2; i
<= copies
; i
*= 2)
3815 HOST_WIDE_INT small_val
;
3817 small_val
= splat_val
>> bitsize
;
3819 if (splat_val
!= ((small_val
<< bitsize
) | (small_val
& mask
)))
3821 splat_val
= small_val
;
3824 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
3825 if (EASY_VECTOR_15 (splat_val
))
3828 /* Also check if we can splat, and then add the result to itself. Do so if
3829 the value is positive, of if the splat instruction is using OP's mode;
3830 for splat_val < 0, the splat and the add should use the same mode. */
3831 else if (EASY_VECTOR_15_ADD_SELF (splat_val
)
3832 && (splat_val
>= 0 || (step
== 1 && copies
== 1)))
3835 /* Also check if are loading up the most significant bit which can be done by
3836 loading up -1 and shifting the value left by -1. */
3837 else if (EASY_VECTOR_MSB (splat_val
, inner
))
3843 /* Check if VAL is present in every STEP-th element, and the
3844 other elements are filled with its most significant bit. */
3845 for (i
= 0; i
< nunits
- 1; ++i
)
3847 HOST_WIDE_INT desired_val
;
3848 if (((i
+ 1) & (step
- 1)) == 0)
3851 desired_val
= msb_val
;
3853 if (desired_val
!= const_vector_elt_as_int (op
, i
))
3861 /* Return true if OP is of the given MODE and can be synthesized
3862 with a vspltisb, vspltish or vspltisw. */
3865 easy_altivec_constant (rtx op
, enum machine_mode mode
)
3867 unsigned step
, copies
;
3869 if (mode
== VOIDmode
)
3870 mode
= GET_MODE (op
);
3871 else if (mode
!= GET_MODE (op
))
3874 /* Start with a vspltisw. */
3875 step
= GET_MODE_NUNITS (mode
) / 4;
3878 if (vspltis_constant (op
, step
, copies
))
3881 /* Then try with a vspltish. */
3887 if (vspltis_constant (op
, step
, copies
))
3890 /* And finally a vspltisb. */
3896 if (vspltis_constant (op
, step
, copies
))
3902 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
3903 result is OP. Abort if it is not possible. */
3906 gen_easy_altivec_constant (rtx op
)
3908 enum machine_mode mode
= GET_MODE (op
);
3909 int nunits
= GET_MODE_NUNITS (mode
);
3910 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
3911 unsigned step
= nunits
/ 4;
3912 unsigned copies
= 1;
3914 /* Start with a vspltisw. */
3915 if (vspltis_constant (op
, step
, copies
))
3916 return gen_rtx_VEC_DUPLICATE (V4SImode
, gen_lowpart (SImode
, last
));
3918 /* Then try with a vspltish. */
3924 if (vspltis_constant (op
, step
, copies
))
3925 return gen_rtx_VEC_DUPLICATE (V8HImode
, gen_lowpart (HImode
, last
));
3927 /* And finally a vspltisb. */
3933 if (vspltis_constant (op
, step
, copies
))
3934 return gen_rtx_VEC_DUPLICATE (V16QImode
, gen_lowpart (QImode
, last
));
3940 output_vec_const_move (rtx
*operands
)
3943 enum machine_mode mode
;
3948 mode
= GET_MODE (dest
);
3950 if (TARGET_VSX
&& zero_constant (vec
, mode
))
3951 return "xxlxor %x0,%x0,%x0";
3956 if (zero_constant (vec
, mode
))
3957 return "vxor %0,%0,%0";
3959 splat_vec
= gen_easy_altivec_constant (vec
);
3960 gcc_assert (GET_CODE (splat_vec
) == VEC_DUPLICATE
);
3961 operands
[1] = XEXP (splat_vec
, 0);
3962 if (!EASY_VECTOR_15 (INTVAL (operands
[1])))
3965 switch (GET_MODE (splat_vec
))
3968 return "vspltisw %0,%1";
3971 return "vspltish %0,%1";
3974 return "vspltisb %0,%1";
3981 gcc_assert (TARGET_SPE
);
3983 /* Vector constant 0 is handled as a splitter of V2SI, and in the
3984 pattern of V1DI, V4HI, and V2SF.
3986 FIXME: We should probably return # and add post reload
3987 splitters for these, but this way is so easy ;-). */
3988 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
3989 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
3990 operands
[1] = CONST_VECTOR_ELT (vec
, 0);
3991 operands
[2] = CONST_VECTOR_ELT (vec
, 1);
3993 return "li %0,%1\n\tevmergelo %0,%0,%0";
3995 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
3998 /* Initialize TARGET of vector PAIRED to VALS. */
4001 paired_expand_vector_init (rtx target
, rtx vals
)
4003 enum machine_mode mode
= GET_MODE (target
);
4004 int n_elts
= GET_MODE_NUNITS (mode
);
4006 rtx x
, new_rtx
, tmp
, constant_op
, op1
, op2
;
4009 for (i
= 0; i
< n_elts
; ++i
)
4011 x
= XVECEXP (vals
, 0, i
);
4012 if (!CONSTANT_P (x
))
4017 /* Load from constant pool. */
4018 emit_move_insn (target
, gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0)));
4024 /* The vector is initialized only with non-constants. */
4025 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, XVECEXP (vals
, 0, 0),
4026 XVECEXP (vals
, 0, 1));
4028 emit_move_insn (target
, new_rtx
);
4032 /* One field is non-constant and the other one is a constant. Load the
4033 constant from the constant pool and use ps_merge instruction to
4034 construct the whole vector. */
4035 op1
= XVECEXP (vals
, 0, 0);
4036 op2
= XVECEXP (vals
, 0, 1);
4038 constant_op
= (CONSTANT_P (op1
)) ? op1
: op2
;
4040 tmp
= gen_reg_rtx (GET_MODE (constant_op
));
4041 emit_move_insn (tmp
, constant_op
);
4043 if (CONSTANT_P (op1
))
4044 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, tmp
, op2
);
4046 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, op1
, tmp
);
4048 emit_move_insn (target
, new_rtx
);
4052 paired_expand_vector_move (rtx operands
[])
4054 rtx op0
= operands
[0], op1
= operands
[1];
4056 emit_move_insn (op0
, op1
);
4059 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4060 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4061 operands for the relation operation COND. This is a recursive
4065 paired_emit_vector_compare (enum rtx_code rcode
,
4066 rtx dest
, rtx op0
, rtx op1
,
4067 rtx cc_op0
, rtx cc_op1
)
4069 rtx tmp
= gen_reg_rtx (V2SFmode
);
4070 rtx tmp1
, max
, min
, equal_zero
;
4072 gcc_assert (TARGET_PAIRED_FLOAT
);
4073 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
4079 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4083 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
4084 emit_insn (gen_selv2sf4 (dest
, tmp
, op0
, op1
, CONST0_RTX (SFmode
)));
4088 paired_emit_vector_compare (GE
, dest
, op0
, op1
, cc_op1
, cc_op0
);
4091 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4094 tmp1
= gen_reg_rtx (V2SFmode
);
4095 max
= gen_reg_rtx (V2SFmode
);
4096 min
= gen_reg_rtx (V2SFmode
);
4097 equal_zero
= gen_reg_rtx (V2SFmode
);
4099 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
4100 emit_insn (gen_selv2sf4
4101 (max
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
4102 emit_insn (gen_subv2sf3 (tmp
, cc_op1
, cc_op0
));
4103 emit_insn (gen_selv2sf4
4104 (min
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
4105 emit_insn (gen_subv2sf3 (tmp1
, min
, max
));
4106 emit_insn (gen_selv2sf4 (dest
, tmp1
, op0
, op1
, CONST0_RTX (SFmode
)));
4109 paired_emit_vector_compare (EQ
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4112 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4115 paired_emit_vector_compare (LT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4118 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4121 paired_emit_vector_compare (GT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
4130 /* Emit vector conditional expression.
4131 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4132 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4135 paired_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
4136 rtx cond
, rtx cc_op0
, rtx cc_op1
)
4138 enum rtx_code rcode
= GET_CODE (cond
);
4140 if (!TARGET_PAIRED_FLOAT
)
4143 paired_emit_vector_compare (rcode
, dest
, op1
, op2
, cc_op0
, cc_op1
);
4148 /* Initialize vector TARGET to VALS. */
4151 rs6000_expand_vector_init (rtx target
, rtx vals
)
4153 enum machine_mode mode
= GET_MODE (target
);
4154 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
4155 int n_elts
= GET_MODE_NUNITS (mode
);
4156 int n_var
= 0, one_var
= -1;
4157 bool all_same
= true, all_const_zero
= true;
4161 for (i
= 0; i
< n_elts
; ++i
)
4163 x
= XVECEXP (vals
, 0, i
);
4164 if (!CONSTANT_P (x
))
4165 ++n_var
, one_var
= i
;
4166 else if (x
!= CONST0_RTX (inner_mode
))
4167 all_const_zero
= false;
4169 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
4175 rtx const_vec
= gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0));
4176 bool int_vector_p
= (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
);
4177 if ((int_vector_p
|| TARGET_VSX
) && all_const_zero
)
4179 /* Zero register. */
4180 emit_insn (gen_rtx_SET (VOIDmode
, target
,
4181 gen_rtx_XOR (mode
, target
, target
)));
4184 else if (int_vector_p
&& easy_vector_constant (const_vec
, mode
))
4186 /* Splat immediate. */
4187 emit_insn (gen_rtx_SET (VOIDmode
, target
, const_vec
));
4192 /* Load from constant pool. */
4193 emit_move_insn (target
, const_vec
);
4198 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4199 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
4203 rtx element
= XVECEXP (vals
, 0, 0);
4204 if (mode
== V2DFmode
)
4205 emit_insn (gen_vsx_splat_v2df (target
, element
));
4207 emit_insn (gen_vsx_splat_v2di (target
, element
));
4211 rtx op0
= copy_to_reg (XVECEXP (vals
, 0, 0));
4212 rtx op1
= copy_to_reg (XVECEXP (vals
, 0, 1));
4213 if (mode
== V2DFmode
)
4214 emit_insn (gen_vsx_concat_v2df (target
, op0
, op1
));
4216 emit_insn (gen_vsx_concat_v2di (target
, op0
, op1
));
4221 /* With single precision floating point on VSX, know that internally single
4222 precision is actually represented as a double, and either make 2 V2DF
4223 vectors, and convert these vectors to single precision, or do one
4224 conversion, and splat the result to the other elements. */
4225 if (mode
== V4SFmode
&& VECTOR_MEM_VSX_P (mode
))
4229 rtx freg
= gen_reg_rtx (V4SFmode
);
4230 rtx sreg
= copy_to_reg (XVECEXP (vals
, 0, 0));
4232 emit_insn (gen_vsx_xscvdpsp_scalar (freg
, sreg
));
4233 emit_insn (gen_vsx_xxspltw_v4sf (target
, freg
, const0_rtx
));
4237 rtx dbl_even
= gen_reg_rtx (V2DFmode
);
4238 rtx dbl_odd
= gen_reg_rtx (V2DFmode
);
4239 rtx flt_even
= gen_reg_rtx (V4SFmode
);
4240 rtx flt_odd
= gen_reg_rtx (V4SFmode
);
4242 emit_insn (gen_vsx_concat_v2sf (dbl_even
,
4243 copy_to_reg (XVECEXP (vals
, 0, 0)),
4244 copy_to_reg (XVECEXP (vals
, 0, 1))));
4245 emit_insn (gen_vsx_concat_v2sf (dbl_odd
,
4246 copy_to_reg (XVECEXP (vals
, 0, 2)),
4247 copy_to_reg (XVECEXP (vals
, 0, 3))));
4248 emit_insn (gen_vsx_xvcvdpsp (flt_even
, dbl_even
));
4249 emit_insn (gen_vsx_xvcvdpsp (flt_odd
, dbl_odd
));
4250 emit_insn (gen_vec_extract_evenv4sf (target
, flt_even
, flt_odd
));
4255 /* Store value to stack temp. Load vector element. Splat. However, splat
4256 of 64-bit items is not supported on Altivec. */
4257 if (all_same
&& GET_MODE_SIZE (mode
) <= 4)
4259 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
4260 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0),
4261 XVECEXP (vals
, 0, 0));
4262 x
= gen_rtx_UNSPEC (VOIDmode
,
4263 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
4264 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
4266 gen_rtx_SET (VOIDmode
,
4269 x
= gen_rtx_VEC_SELECT (inner_mode
, target
,
4270 gen_rtx_PARALLEL (VOIDmode
,
4271 gen_rtvec (1, const0_rtx
)));
4272 emit_insn (gen_rtx_SET (VOIDmode
, target
,
4273 gen_rtx_VEC_DUPLICATE (mode
, x
)));
4277 /* One field is non-constant. Load constant then overwrite
4281 rtx copy
= copy_rtx (vals
);
4283 /* Load constant part of vector, substitute neighboring value for
4285 XVECEXP (copy
, 0, one_var
) = XVECEXP (vals
, 0, (one_var
+ 1) % n_elts
);
4286 rs6000_expand_vector_init (target
, copy
);
4288 /* Insert variable. */
4289 rs6000_expand_vector_set (target
, XVECEXP (vals
, 0, one_var
), one_var
);
4293 /* Construct the vector in memory one field at a time
4294 and load the whole vector. */
4295 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
4296 for (i
= 0; i
< n_elts
; i
++)
4297 emit_move_insn (adjust_address_nv (mem
, inner_mode
,
4298 i
* GET_MODE_SIZE (inner_mode
)),
4299 XVECEXP (vals
, 0, i
));
4300 emit_move_insn (target
, mem
);
4303 /* Set field ELT of TARGET to VAL. */
4306 rs6000_expand_vector_set (rtx target
, rtx val
, int elt
)
4308 enum machine_mode mode
= GET_MODE (target
);
4309 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
4310 rtx reg
= gen_reg_rtx (mode
);
4312 int width
= GET_MODE_SIZE (inner_mode
);
4315 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
4317 rtx (*set_func
) (rtx
, rtx
, rtx
, rtx
)
4318 = ((mode
== V2DFmode
) ? gen_vsx_set_v2df
: gen_vsx_set_v2di
);
4319 emit_insn (set_func (target
, target
, val
, GEN_INT (elt
)));
4323 /* Load single variable value. */
4324 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
4325 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0), val
);
4326 x
= gen_rtx_UNSPEC (VOIDmode
,
4327 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
4328 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
4330 gen_rtx_SET (VOIDmode
,
4334 /* Linear sequence. */
4335 mask
= gen_rtx_PARALLEL (V16QImode
, rtvec_alloc (16));
4336 for (i
= 0; i
< 16; ++i
)
4337 XVECEXP (mask
, 0, i
) = GEN_INT (i
);
4339 /* Set permute mask to insert element into target. */
4340 for (i
= 0; i
< width
; ++i
)
4341 XVECEXP (mask
, 0, elt
*width
+ i
)
4342 = GEN_INT (i
+ 0x10);
4343 x
= gen_rtx_CONST_VECTOR (V16QImode
, XVEC (mask
, 0));
4344 x
= gen_rtx_UNSPEC (mode
,
4345 gen_rtvec (3, target
, reg
,
4346 force_reg (V16QImode
, x
)),
4348 emit_insn (gen_rtx_SET (VOIDmode
, target
, x
));
4351 /* Extract field ELT from VEC into TARGET. */
4354 rs6000_expand_vector_extract (rtx target
, rtx vec
, int elt
)
4356 enum machine_mode mode
= GET_MODE (vec
);
4357 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
4360 if (VECTOR_MEM_VSX_P (mode
) && (mode
== V2DFmode
|| mode
== V2DImode
))
4362 rtx (*extract_func
) (rtx
, rtx
, rtx
)
4363 = ((mode
== V2DFmode
) ? gen_vsx_extract_v2df
: gen_vsx_extract_v2di
);
4364 emit_insn (extract_func (target
, vec
, GEN_INT (elt
)));
4368 /* Allocate mode-sized buffer. */
4369 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
4371 /* Add offset to field within buffer matching vector element. */
4372 mem
= adjust_address_nv (mem
, mode
, elt
* GET_MODE_SIZE (inner_mode
));
4374 /* Store single field into mode-sized buffer. */
4375 x
= gen_rtx_UNSPEC (VOIDmode
,
4376 gen_rtvec (1, const0_rtx
), UNSPEC_STVE
);
4377 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
4379 gen_rtx_SET (VOIDmode
,
4382 emit_move_insn (target
, adjust_address_nv (mem
, inner_mode
, 0));
4385 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4386 implement ANDing by the mask IN. */
4388 build_mask64_2_operands (rtx in
, rtx
*out
)
4390 #if HOST_BITS_PER_WIDE_INT >= 64
4391 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
4394 gcc_assert (GET_CODE (in
) == CONST_INT
);
4399 /* Assume c initially something like 0x00fff000000fffff. The idea
4400 is to rotate the word so that the middle ^^^^^^ group of zeros
4401 is at the MS end and can be cleared with an rldicl mask. We then
4402 rotate back and clear off the MS ^^ group of zeros with a
4404 c
= ~c
; /* c == 0xff000ffffff00000 */
4405 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
4406 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
4407 c
= ~c
; /* c == 0x00fff000000fffff */
4408 c
&= -lsb
; /* c == 0x00fff00000000000 */
4409 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
4410 c
= ~c
; /* c == 0xff000fffffffffff */
4411 c
&= -lsb
; /* c == 0xff00000000000000 */
4413 while ((lsb
>>= 1) != 0)
4414 shift
++; /* shift == 44 on exit from loop */
4415 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
4416 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
4417 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
4421 /* Assume c initially something like 0xff000f0000000000. The idea
4422 is to rotate the word so that the ^^^ middle group of zeros
4423 is at the LS end and can be cleared with an rldicr mask. We then
4424 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4426 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
4427 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
4428 c
= ~c
; /* c == 0x00fff0ffffffffff */
4429 c
&= -lsb
; /* c == 0x00fff00000000000 */
4430 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
4431 c
= ~c
; /* c == 0xff000fffffffffff */
4432 c
&= -lsb
; /* c == 0xff00000000000000 */
4434 while ((lsb
>>= 1) != 0)
4435 shift
++; /* shift == 44 on exit from loop */
4436 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
4437 m1
>>= shift
; /* m1 == 0x0000000000000fff */
4438 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
4441 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4442 masks will be all 1's. We are guaranteed more than one transition. */
4443 out
[0] = GEN_INT (64 - shift
);
4444 out
[1] = GEN_INT (m1
);
4445 out
[2] = GEN_INT (shift
);
4446 out
[3] = GEN_INT (m2
);
4454 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4457 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
4459 if (TARGET_E500_DOUBLE
)
4461 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4462 subreg:TI and reg:TF. Decimal float modes are like integer
4463 modes (only low part of each register used) for this
4465 if (GET_CODE (op
) == SUBREG
4466 && (mode
== SImode
|| mode
== DImode
|| mode
== TImode
4467 || mode
== DDmode
|| mode
== TDmode
)
4468 && REG_P (SUBREG_REG (op
))
4469 && (GET_MODE (SUBREG_REG (op
)) == DFmode
4470 || GET_MODE (SUBREG_REG (op
)) == TFmode
))
4473 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4475 if (GET_CODE (op
) == SUBREG
4476 && (mode
== DFmode
|| mode
== TFmode
)
4477 && REG_P (SUBREG_REG (op
))
4478 && (GET_MODE (SUBREG_REG (op
)) == DImode
4479 || GET_MODE (SUBREG_REG (op
)) == TImode
4480 || GET_MODE (SUBREG_REG (op
)) == DDmode
4481 || GET_MODE (SUBREG_REG (op
)) == TDmode
))
4486 && GET_CODE (op
) == SUBREG
4488 && REG_P (SUBREG_REG (op
))
4489 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op
))))
4495 /* AIX increases natural record alignment to doubleword if the first
4496 field is an FP double while the FP fields remain word aligned. */
4499 rs6000_special_round_type_align (tree type
, unsigned int computed
,
4500 unsigned int specified
)
4502 unsigned int align
= MAX (computed
, specified
);
4503 tree field
= TYPE_FIELDS (type
);
4505 /* Skip all non field decls */
4506 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
4507 field
= TREE_CHAIN (field
);
4509 if (field
!= NULL
&& field
!= type
)
4511 type
= TREE_TYPE (field
);
4512 while (TREE_CODE (type
) == ARRAY_TYPE
)
4513 type
= TREE_TYPE (type
);
4515 if (type
!= error_mark_node
&& TYPE_MODE (type
) == DFmode
)
4516 align
= MAX (align
, 64);
4522 /* Darwin increases record alignment to the natural alignment of
4526 darwin_rs6000_special_round_type_align (tree type
, unsigned int computed
,
4527 unsigned int specified
)
4529 unsigned int align
= MAX (computed
, specified
);
4531 if (TYPE_PACKED (type
))
4534 /* Find the first field, looking down into aggregates. */
4536 tree field
= TYPE_FIELDS (type
);
4537 /* Skip all non field decls */
4538 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
4539 field
= TREE_CHAIN (field
);
4542 type
= TREE_TYPE (field
);
4543 while (TREE_CODE (type
) == ARRAY_TYPE
)
4544 type
= TREE_TYPE (type
);
4545 } while (AGGREGATE_TYPE_P (type
));
4547 if (! AGGREGATE_TYPE_P (type
) && type
!= error_mark_node
)
4548 align
= MAX (align
, TYPE_ALIGN (type
));
4553 /* Return 1 for an operand in small memory on V.4/eabi. */
4556 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
4557 enum machine_mode mode ATTRIBUTE_UNUSED
)
4562 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
4565 if (DEFAULT_ABI
!= ABI_V4
)
4568 /* Vector and float memory instructions have a limited offset on the
4569 SPE, so using a vector or float variable directly as an operand is
4572 && (SPE_VECTOR_MODE (mode
) || FLOAT_MODE_P (mode
)))
4575 if (GET_CODE (op
) == SYMBOL_REF
)
4578 else if (GET_CODE (op
) != CONST
4579 || GET_CODE (XEXP (op
, 0)) != PLUS
4580 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
4581 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
4586 rtx sum
= XEXP (op
, 0);
4587 HOST_WIDE_INT summand
;
4589 /* We have to be careful here, because it is the referenced address
4590 that must be 32k from _SDA_BASE_, not just the symbol. */
4591 summand
= INTVAL (XEXP (sum
, 1));
4592 if (summand
< 0 || (unsigned HOST_WIDE_INT
) summand
> g_switch_value
)
4595 sym_ref
= XEXP (sum
, 0);
4598 return SYMBOL_REF_SMALL_P (sym_ref
);
4604 /* Return true if either operand is a general purpose register. */
4607 gpr_or_gpr_p (rtx op0
, rtx op1
)
4609 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
4610 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
4614 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
4617 reg_offset_addressing_ok_p (enum machine_mode mode
)
4627 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
4628 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
))
4636 /* Paired vector modes. Only reg+reg addressing is valid. */
4637 if (TARGET_PAIRED_FLOAT
)
4649 virtual_stack_registers_memory_p (rtx op
)
4653 if (GET_CODE (op
) == REG
)
4654 regnum
= REGNO (op
);
4656 else if (GET_CODE (op
) == PLUS
4657 && GET_CODE (XEXP (op
, 0)) == REG
4658 && GET_CODE (XEXP (op
, 1)) == CONST_INT
)
4659 regnum
= REGNO (XEXP (op
, 0));
4664 return (regnum
>= FIRST_VIRTUAL_REGISTER
4665 && regnum
<= LAST_VIRTUAL_REGISTER
);
4669 constant_pool_expr_p (rtx op
)
4673 split_const (op
, &base
, &offset
);
4674 return (GET_CODE (base
) == SYMBOL_REF
4675 && CONSTANT_POOL_ADDRESS_P (base
)
4676 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base
), Pmode
));
4680 toc_relative_expr_p (rtx op
)
4684 if (GET_CODE (op
) != CONST
)
4687 split_const (op
, &base
, &offset
);
4688 return (GET_CODE (base
) == UNSPEC
4689 && XINT (base
, 1) == UNSPEC_TOCREL
);
4693 legitimate_constant_pool_address_p (rtx x
)
4696 && GET_CODE (x
) == PLUS
4697 && GET_CODE (XEXP (x
, 0)) == REG
4698 && (TARGET_MINIMAL_TOC
|| REGNO (XEXP (x
, 0)) == TOC_REGISTER
)
4699 && toc_relative_expr_p (XEXP (x
, 1)));
4703 legitimate_small_data_p (enum machine_mode mode
, rtx x
)
4705 return (DEFAULT_ABI
== ABI_V4
4706 && !flag_pic
&& !TARGET_TOC
4707 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
4708 && small_data_operand (x
, mode
));
4711 /* SPE offset addressing is limited to 5-bits worth of double words. */
4712 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
4715 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
4717 unsigned HOST_WIDE_INT offset
, extra
;
4719 if (GET_CODE (x
) != PLUS
)
4721 if (GET_CODE (XEXP (x
, 0)) != REG
)
4723 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
4725 if (!reg_offset_addressing_ok_p (mode
))
4726 return virtual_stack_registers_memory_p (x
);
4727 if (legitimate_constant_pool_address_p (x
))
4729 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
4732 offset
= INTVAL (XEXP (x
, 1));
4740 /* SPE vector modes. */
4741 return SPE_CONST_OFFSET_OK (offset
);
4744 if (TARGET_E500_DOUBLE
)
4745 return SPE_CONST_OFFSET_OK (offset
);
4747 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
4749 if (VECTOR_MEM_VSX_P (DFmode
))
4754 /* On e500v2, we may have:
4756 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
4758 Which gets addressed with evldd instructions. */
4759 if (TARGET_E500_DOUBLE
)
4760 return SPE_CONST_OFFSET_OK (offset
);
4762 if (mode
== DFmode
|| mode
== DDmode
|| !TARGET_POWERPC64
)
4764 else if (offset
& 3)
4769 if (TARGET_E500_DOUBLE
)
4770 return (SPE_CONST_OFFSET_OK (offset
)
4771 && SPE_CONST_OFFSET_OK (offset
+ 8));
4775 if (mode
== TFmode
|| mode
== TDmode
|| !TARGET_POWERPC64
)
4777 else if (offset
& 3)
4788 return (offset
< 0x10000) && (offset
+ extra
< 0x10000);
4792 legitimate_indexed_address_p (rtx x
, int strict
)
4796 if (GET_CODE (x
) != PLUS
)
4802 /* Recognize the rtl generated by reload which we know will later be
4803 replaced with proper base and index regs. */
4805 && reload_in_progress
4806 && (REG_P (op0
) || GET_CODE (op0
) == PLUS
)
4810 return (REG_P (op0
) && REG_P (op1
)
4811 && ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
4812 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
4813 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
4814 && INT_REG_OK_FOR_INDEX_P (op0
, strict
))));
4818 avoiding_indexed_address_p (enum machine_mode mode
)
4820 /* Avoid indexed addressing for modes that have non-indexed
4821 load/store instruction forms. */
4822 return (TARGET_AVOID_XFORM
&& VECTOR_MEM_NONE_P (mode
));
4826 legitimate_indirect_address_p (rtx x
, int strict
)
4828 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
4832 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
4834 if (!TARGET_MACHO
|| !flag_pic
4835 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
4839 if (GET_CODE (x
) != LO_SUM
)
4841 if (GET_CODE (XEXP (x
, 0)) != REG
)
4843 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
4847 return CONSTANT_P (x
);
4851 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
4853 if (GET_CODE (x
) != LO_SUM
)
4855 if (GET_CODE (XEXP (x
, 0)) != REG
)
4857 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
4859 /* Restrict addressing for DI because of our SUBREG hackery. */
4860 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
4861 || mode
== DDmode
|| mode
== TDmode
4866 if (TARGET_ELF
|| TARGET_MACHO
)
4868 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
4872 if (GET_MODE_NUNITS (mode
) != 1)
4874 if (GET_MODE_BITSIZE (mode
) > 64
4875 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
4876 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
4877 && (mode
== DFmode
|| mode
== DDmode
))))
4880 return CONSTANT_P (x
);
4887 /* Try machine-dependent ways of modifying an illegitimate address
4888 to be legitimate. If we find one, return the new, valid address.
4889 This is used from only one place: `memory_address' in explow.c.
4891 OLDX is the address as it was before break_out_memory_refs was
4892 called. In some cases it is useful to look at this to decide what
4895 It is always safe for this function to do nothing. It exists to
4896 recognize opportunities to optimize the output.
4898 On RS/6000, first check for the sum of a register with a constant
4899 integer that is out of range. If so, generate code to add the
4900 constant with the low-order 16 bits masked to the register and force
4901 this result into another register (this can be done with `cau').
4902 Then generate an address of REG+(CONST&0xffff), allowing for the
4903 possibility of bit 16 being a one.
4905 Then check for the sum of a register and something not constant, try to
4906 load the other things into a register and return the sum. */
4909 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
4910 enum machine_mode mode
)
4912 unsigned int extra
= 0;
4914 if (!reg_offset_addressing_ok_p (mode
))
4916 if (virtual_stack_registers_memory_p (x
))
4919 /* In theory we should not be seeing addresses of the form reg+0,
4920 but just in case it is generated, optimize it away. */
4921 if (GET_CODE (x
) == PLUS
&& XEXP (x
, 1) == const0_rtx
)
4922 return force_reg (Pmode
, XEXP (x
, 0));
4924 /* Make sure both operands are registers. */
4925 else if (GET_CODE (x
) == PLUS
)
4926 return gen_rtx_PLUS (Pmode
,
4927 force_reg (Pmode
, XEXP (x
, 0)),
4928 force_reg (Pmode
, XEXP (x
, 1)));
4930 return force_reg (Pmode
, x
);
4932 if (GET_CODE (x
) == SYMBOL_REF
)
4934 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
4936 return rs6000_legitimize_tls_address (x
, model
);
4946 if (!TARGET_POWERPC64
)
4954 extra
= TARGET_POWERPC64
? 8 : 12;
4960 if (GET_CODE (x
) == PLUS
4961 && GET_CODE (XEXP (x
, 0)) == REG
4962 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4963 && ((unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000)
4965 && !((TARGET_POWERPC64
4966 && (mode
== DImode
|| mode
== TImode
)
4967 && (INTVAL (XEXP (x
, 1)) & 3) != 0)
4968 || SPE_VECTOR_MODE (mode
)
4969 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
4970 || mode
== DImode
|| mode
== DDmode
4971 || mode
== TDmode
))))
4973 HOST_WIDE_INT high_int
, low_int
;
4975 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
4976 if (low_int
>= 0x8000 - extra
)
4978 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
4979 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
4980 GEN_INT (high_int
)), 0);
4981 return plus_constant (sum
, low_int
);
4983 else if (GET_CODE (x
) == PLUS
4984 && GET_CODE (XEXP (x
, 0)) == REG
4985 && GET_CODE (XEXP (x
, 1)) != CONST_INT
4986 && GET_MODE_NUNITS (mode
) == 1
4987 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
4989 || ((mode
!= DImode
&& mode
!= DFmode
&& mode
!= DDmode
)
4990 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
)))
4991 && (TARGET_POWERPC64
|| mode
!= DImode
)
4992 && !avoiding_indexed_address_p (mode
)
4997 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
4998 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
5000 else if (SPE_VECTOR_MODE (mode
)
5001 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5002 || mode
== DDmode
|| mode
== TDmode
5003 || mode
== DImode
)))
5007 /* We accept [reg + reg] and [reg + OFFSET]. */
5009 if (GET_CODE (x
) == PLUS
)
5011 rtx op1
= XEXP (x
, 0);
5012 rtx op2
= XEXP (x
, 1);
5015 op1
= force_reg (Pmode
, op1
);
5017 if (GET_CODE (op2
) != REG
5018 && (GET_CODE (op2
) != CONST_INT
5019 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))
5020 || (GET_MODE_SIZE (mode
) > 8
5021 && !SPE_CONST_OFFSET_OK (INTVAL (op2
) + 8))))
5022 op2
= force_reg (Pmode
, op2
);
5024 /* We can't always do [reg + reg] for these, because [reg +
5025 reg + offset] is not a legitimate addressing mode. */
5026 y
= gen_rtx_PLUS (Pmode
, op1
, op2
);
5028 if ((GET_MODE_SIZE (mode
) > 8 || mode
== DDmode
) && REG_P (op2
))
5029 return force_reg (Pmode
, y
);
5034 return force_reg (Pmode
, x
);
5040 && GET_CODE (x
) != CONST_INT
5041 && GET_CODE (x
) != CONST_DOUBLE
5043 && GET_MODE_NUNITS (mode
) == 1
5044 && (GET_MODE_BITSIZE (mode
) <= 32
5045 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
5046 && (mode
== DFmode
|| mode
== DDmode
))))
5048 rtx reg
= gen_reg_rtx (Pmode
);
5049 emit_insn (gen_elf_high (reg
, x
));
5050 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
5052 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
5055 && ! MACHO_DYNAMIC_NO_PIC_P
5057 && GET_CODE (x
) != CONST_INT
5058 && GET_CODE (x
) != CONST_DOUBLE
5060 && GET_MODE_NUNITS (mode
) == 1
5061 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
5062 || (mode
!= DFmode
&& mode
!= DDmode
))
5066 rtx reg
= gen_reg_rtx (Pmode
);
5067 emit_insn (gen_macho_high (reg
, x
));
5068 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
5071 && GET_CODE (x
) == SYMBOL_REF
5072 && constant_pool_expr_p (x
)
5073 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
5075 return create_TOC_reference (x
);
5081 /* Debug version of rs6000_legitimize_address. */
5083 rs6000_debug_legitimize_address (rtx x
, rtx oldx
, enum machine_mode mode
)
5089 ret
= rs6000_legitimize_address (x
, oldx
, mode
);
5090 insns
= get_insns ();
5096 "\nrs6000_legitimize_address: mode %s, old code %s, "
5097 "new code %s, modified\n",
5098 GET_MODE_NAME (mode
), GET_RTX_NAME (GET_CODE (x
)),
5099 GET_RTX_NAME (GET_CODE (ret
)));
5101 fprintf (stderr
, "Original address:\n");
5104 fprintf (stderr
, "oldx:\n");
5107 fprintf (stderr
, "New address:\n");
5112 fprintf (stderr
, "Insns added:\n");
5113 debug_rtx_list (insns
, 20);
5119 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5120 GET_MODE_NAME (mode
), GET_RTX_NAME (GET_CODE (x
)));
5131 /* If ORIG_X is a constant pool reference, return its known value,
5132 otherwise ORIG_X. */
5135 rs6000_delegitimize_address (rtx x
)
5137 rtx orig_x
= delegitimize_mem_from_attrs (x
);
5146 if (legitimate_constant_pool_address_p (x
)
5147 && GET_CODE (XEXP (x
, 1)) == CONST
5148 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == MINUS
5149 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 0)) == SYMBOL_REF
5150 && constant_pool_expr_p (XEXP (XEXP (XEXP (x
, 1), 0), 0))
5151 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 1)) == SYMBOL_REF
5152 && toc_relative_expr_p (XEXP (XEXP (XEXP (x
, 1), 0), 1)))
5153 return get_pool_constant (XEXP (XEXP (XEXP (x
, 1), 0), 0));
5158 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5159 We need to emit DTP-relative relocations. */
5162 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
5167 fputs ("\t.long\t", file
);
5170 fputs (DOUBLE_INT_ASM_OP
, file
);
5175 output_addr_const (file
, x
);
5176 fputs ("@dtprel+0x8000", file
);
5179 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5181 static GTY(()) rtx rs6000_tls_symbol
;
5183 rs6000_tls_get_addr (void)
5185 if (!rs6000_tls_symbol
)
5186 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
5188 return rs6000_tls_symbol
;
5191 /* Construct the SYMBOL_REF for TLS GOT references. */
5193 static GTY(()) rtx rs6000_got_symbol
;
5195 rs6000_got_sym (void)
5197 if (!rs6000_got_symbol
)
5199 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
5200 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
5201 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
5204 return rs6000_got_symbol
;
5207 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5208 this (thread-local) address. */
5211 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
5215 dest
= gen_reg_rtx (Pmode
);
5216 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
5222 tlsreg
= gen_rtx_REG (Pmode
, 13);
5223 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
5227 tlsreg
= gen_rtx_REG (Pmode
, 2);
5228 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
5232 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
5236 tmp
= gen_reg_rtx (Pmode
);
5239 tlsreg
= gen_rtx_REG (Pmode
, 13);
5240 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
5244 tlsreg
= gen_rtx_REG (Pmode
, 2);
5245 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
5249 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
5251 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
5256 rtx r3
, got
, tga
, tmp1
, tmp2
, eqv
;
5258 /* We currently use relocations like @got@tlsgd for tls, which
5259 means the linker will handle allocation of tls entries, placing
5260 them in the .got section. So use a pointer to the .got section,
5261 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5262 or to secondary GOT sections used by 32-bit -fPIC. */
5264 got
= gen_rtx_REG (Pmode
, 2);
5268 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
5271 rtx gsym
= rs6000_got_sym ();
5272 got
= gen_reg_rtx (Pmode
);
5274 rs6000_emit_move (got
, gsym
, Pmode
);
5280 tmp1
= gen_reg_rtx (Pmode
);
5281 tmp2
= gen_reg_rtx (Pmode
);
5282 tmp3
= gen_reg_rtx (Pmode
);
5283 mem
= gen_const_mem (Pmode
, tmp1
);
5285 first
= emit_insn (gen_load_toc_v4_PIC_1b (gsym
));
5286 emit_move_insn (tmp1
,
5287 gen_rtx_REG (Pmode
, LR_REGNO
));
5288 emit_move_insn (tmp2
, mem
);
5289 emit_insn (gen_addsi3 (tmp3
, tmp1
, tmp2
));
5290 last
= emit_move_insn (got
, tmp3
);
5291 set_unique_reg_note (last
, REG_EQUAL
, gsym
);
5296 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
5298 r3
= gen_rtx_REG (Pmode
, 3);
5299 tga
= rs6000_tls_get_addr ();
5301 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
5302 insn
= gen_tls_gd_aix64 (r3
, got
, addr
, tga
, const0_rtx
);
5303 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
5304 insn
= gen_tls_gd_aix32 (r3
, got
, addr
, tga
, const0_rtx
);
5305 else if (DEFAULT_ABI
== ABI_V4
)
5306 insn
= gen_tls_gd_sysvsi (r3
, got
, addr
, tga
, const0_rtx
);
5311 insn
= emit_call_insn (insn
);
5312 RTL_CONST_CALL_P (insn
) = 1;
5313 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
5314 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
5315 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
5316 insn
= get_insns ();
5318 emit_libcall_block (insn
, dest
, r3
, addr
);
5320 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
5322 r3
= gen_rtx_REG (Pmode
, 3);
5323 tga
= rs6000_tls_get_addr ();
5325 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
5326 insn
= gen_tls_ld_aix64 (r3
, got
, tga
, const0_rtx
);
5327 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
5328 insn
= gen_tls_ld_aix32 (r3
, got
, tga
, const0_rtx
);
5329 else if (DEFAULT_ABI
== ABI_V4
)
5330 insn
= gen_tls_ld_sysvsi (r3
, got
, tga
, const0_rtx
);
5335 insn
= emit_call_insn (insn
);
5336 RTL_CONST_CALL_P (insn
) = 1;
5337 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
5338 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
5339 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
5340 insn
= get_insns ();
5342 tmp1
= gen_reg_rtx (Pmode
);
5343 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
),
5345 emit_libcall_block (insn
, tmp1
, r3
, eqv
);
5346 if (rs6000_tls_size
== 16)
5349 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
5351 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
5353 else if (rs6000_tls_size
== 32)
5355 tmp2
= gen_reg_rtx (Pmode
);
5357 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
5359 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
5362 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
5364 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
5368 tmp2
= gen_reg_rtx (Pmode
);
5370 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
5372 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
5374 insn
= gen_rtx_SET (Pmode
, dest
,
5375 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
5381 /* IE, or 64-bit offset LE. */
5382 tmp2
= gen_reg_rtx (Pmode
);
5384 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
5386 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
5389 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
5391 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
5399 /* Return 1 if X contains a thread-local symbol. */
5402 rs6000_tls_referenced_p (rtx x
)
5404 if (! TARGET_HAVE_TLS
)
5407 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
5410 /* Return 1 if *X is a thread-local symbol. This is the same as
5411 rs6000_tls_symbol_ref except for the type of the unused argument. */
5414 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
5416 return RS6000_SYMBOL_REF_TLS_P (*x
);
5419 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5420 replace the input X, or the original X if no replacement is called for.
5421 The output parameter *WIN is 1 if the calling macro should goto WIN,
5424 For RS/6000, we wish to handle large displacements off a base
5425 register by splitting the addend across an addiu/addis and the mem insn.
5426 This cuts number of extra insns needed from 3 to 1.
5428 On Darwin, we use this to generate code for floating point constants.
5429 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5430 The Darwin code is inside #if TARGET_MACHO because only then are the
5431 machopic_* functions defined. */
5433 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
5434 int opnum
, int type
,
5435 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
5437 bool reg_offset_p
= reg_offset_addressing_ok_p (mode
);
5439 /* We must recognize output that we have already generated ourselves. */
5440 if (GET_CODE (x
) == PLUS
5441 && GET_CODE (XEXP (x
, 0)) == PLUS
5442 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
5443 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
5444 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
5446 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
5447 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
5448 opnum
, (enum reload_type
)type
);
5454 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
5455 && GET_CODE (x
) == LO_SUM
5456 && GET_CODE (XEXP (x
, 0)) == PLUS
5457 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
5458 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
5459 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
5460 && machopic_operand_p (XEXP (x
, 1)))
5462 /* Result of previous invocation of this function on Darwin
5463 floating point constant. */
5464 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
5465 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
5466 opnum
, (enum reload_type
)type
);
5472 /* Force ld/std non-word aligned offset into base register by wrapping
5474 if (GET_CODE (x
) == PLUS
5475 && GET_CODE (XEXP (x
, 0)) == REG
5476 && REGNO (XEXP (x
, 0)) < 32
5477 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 1)
5478 && GET_CODE (XEXP (x
, 1)) == CONST_INT
5480 && (INTVAL (XEXP (x
, 1)) & 3) != 0
5481 && VECTOR_MEM_NONE_P (mode
)
5482 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
5483 && TARGET_POWERPC64
)
5485 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
5486 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
5487 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
5488 opnum
, (enum reload_type
) type
);
5493 if (GET_CODE (x
) == PLUS
5494 && GET_CODE (XEXP (x
, 0)) == REG
5495 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
5496 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 1)
5497 && GET_CODE (XEXP (x
, 1)) == CONST_INT
5499 && !SPE_VECTOR_MODE (mode
)
5500 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5501 || mode
== DDmode
|| mode
== TDmode
5503 && VECTOR_MEM_NONE_P (mode
))
5505 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
5506 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
5508 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5510 /* Check for 32-bit overflow. */
5511 if (high
+ low
!= val
)
5517 /* Reload the high part into a base reg; leave the low part
5518 in the mem directly. */
5520 x
= gen_rtx_PLUS (GET_MODE (x
),
5521 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
5525 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
5526 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
5527 opnum
, (enum reload_type
)type
);
5532 if (GET_CODE (x
) == SYMBOL_REF
5534 && VECTOR_MEM_NONE_P (mode
)
5535 && !SPE_VECTOR_MODE (mode
)
5537 && DEFAULT_ABI
== ABI_DARWIN
5538 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
5540 && DEFAULT_ABI
== ABI_V4
5543 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5544 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5548 && (mode
!= DImode
|| TARGET_POWERPC64
)
5549 && ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_POWERPC64
5550 || (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)))
5555 rtx offset
= machopic_gen_offset (x
);
5556 x
= gen_rtx_LO_SUM (GET_MODE (x
),
5557 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
5558 gen_rtx_HIGH (Pmode
, offset
)), offset
);
5562 x
= gen_rtx_LO_SUM (GET_MODE (x
),
5563 gen_rtx_HIGH (Pmode
, x
), x
);
5565 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
5566 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
5567 opnum
, (enum reload_type
)type
);
5572 /* Reload an offset address wrapped by an AND that represents the
5573 masking of the lower bits. Strip the outer AND and let reload
5574 convert the offset address into an indirect address. For VSX,
5575 force reload to create the address with an AND in a separate
5576 register, because we can't guarantee an altivec register will
5578 if (VECTOR_MEM_ALTIVEC_P (mode
)
5579 && GET_CODE (x
) == AND
5580 && GET_CODE (XEXP (x
, 0)) == PLUS
5581 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
5582 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
5583 && GET_CODE (XEXP (x
, 1)) == CONST_INT
5584 && INTVAL (XEXP (x
, 1)) == -16)
5593 && GET_CODE (x
) == SYMBOL_REF
5594 && constant_pool_expr_p (x
)
5595 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
5597 x
= create_TOC_reference (x
);
5605 /* Debug version of rs6000_legitimize_reload_address. */
5607 rs6000_debug_legitimize_reload_address (rtx x
, enum machine_mode mode
,
5608 int opnum
, int type
,
5609 int ind_levels
, int *win
)
5611 rtx ret
= rs6000_legitimize_reload_address (x
, mode
, opnum
, type
,
5614 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
5615 "type = %d, ind_levels = %d, win = %d, original addr:\n",
5616 GET_MODE_NAME (mode
), opnum
, type
, ind_levels
, *win
);
5620 fprintf (stderr
, "Same address returned\n");
5622 fprintf (stderr
, "NULL returned\n");
5625 fprintf (stderr
, "New address:\n");
5632 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
5633 that is a valid memory address for an instruction.
5634 The MODE argument is the machine mode for the MEM expression
5635 that wants to use this address.
5637 On the RS/6000, there are four valid address: a SYMBOL_REF that
5638 refers to a constant pool entry of an address (or the sum of it
5639 plus a constant), a short (16-bit signed) constant plus a register,
5640 the sum of two registers, or a register indirect, possibly with an
5641 auto-increment. For DFmode, DDmode and DImode with a constant plus
5642 register, we must ensure that both words are addressable or PowerPC64
5643 with offset word aligned.
5645 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
5646 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
5647 because adjacent memory cells are accessed by adding word-sized offsets
5648 during assembly output. */
5650 rs6000_legitimate_address_p (enum machine_mode mode
, rtx x
, bool reg_ok_strict
)
5652 bool reg_offset_p
= reg_offset_addressing_ok_p (mode
);
5654 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
5655 if (VECTOR_MEM_ALTIVEC_P (mode
)
5656 && GET_CODE (x
) == AND
5657 && GET_CODE (XEXP (x
, 1)) == CONST_INT
5658 && INTVAL (XEXP (x
, 1)) == -16)
5661 if (RS6000_SYMBOL_REF_TLS_P (x
))
5663 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
5665 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
5666 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
)
5667 && !SPE_VECTOR_MODE (mode
)
5670 /* Restrict addressing for DI because of our SUBREG hackery. */
5671 && !(TARGET_E500_DOUBLE
5672 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
5674 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
5676 if (virtual_stack_registers_memory_p (x
))
5678 if (reg_offset_p
&& legitimate_small_data_p (mode
, x
))
5680 if (reg_offset_p
&& legitimate_constant_pool_address_p (x
))
5682 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
5685 && GET_CODE (x
) == PLUS
5686 && GET_CODE (XEXP (x
, 0)) == REG
5687 && (XEXP (x
, 0) == virtual_stack_vars_rtx
5688 || XEXP (x
, 0) == arg_pointer_rtx
)
5689 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
5691 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
5696 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
5698 || (mode
!= DFmode
&& mode
!= DDmode
)
5699 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
))
5700 && (TARGET_POWERPC64
|| mode
!= DImode
)
5701 && !avoiding_indexed_address_p (mode
)
5702 && legitimate_indexed_address_p (x
, reg_ok_strict
))
5704 if (GET_CODE (x
) == PRE_MODIFY
5705 && VECTOR_MEM_VSX_P (mode
)
5707 && legitimate_indexed_address_p (XEXP (x
, 1), reg_ok_strict
)
5708 && rtx_equal_p (XEXP (XEXP (x
, 1), 0), XEXP (x
, 0)))
5710 if (GET_CODE (x
) == PRE_MODIFY
5714 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
5716 || ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_E500_DOUBLE
))
5717 && (TARGET_POWERPC64
|| mode
!= DImode
)
5718 && !VECTOR_MEM_ALTIVEC_P (mode
)
5719 && !SPE_VECTOR_MODE (mode
)
5720 /* Restrict addressing for DI because of our SUBREG hackery. */
5721 && !(TARGET_E500_DOUBLE
5722 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
5724 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
)
5725 && (rs6000_legitimate_offset_address_p (mode
, XEXP (x
, 1), reg_ok_strict
)
5726 || (!avoiding_indexed_address_p (mode
)
5727 && legitimate_indexed_address_p (XEXP (x
, 1), reg_ok_strict
)))
5728 && rtx_equal_p (XEXP (XEXP (x
, 1), 0), XEXP (x
, 0)))
5730 if (reg_offset_p
&& legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
5735 /* Debug version of rs6000_legitimate_address_p. */
5737 rs6000_debug_legitimate_address_p (enum machine_mode mode
, rtx x
,
5740 bool ret
= rs6000_legitimate_address_p (mode
, x
, reg_ok_strict
);
5742 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
5743 "strict = %d, code = %s\n",
5744 ret
? "true" : "false",
5745 GET_MODE_NAME (mode
),
5747 GET_RTX_NAME (GET_CODE (x
)));
5753 /* Go to LABEL if ADDR (a legitimate address expression)
5754 has an effect that depends on the machine mode it is used for.
5756 On the RS/6000 this is true of all integral offsets (since AltiVec
5757 and VSX modes don't allow them) or is a pre-increment or decrement.
5759 ??? Except that due to conceptual problems in offsettable_address_p
5760 we can't really report the problems of integral offsets. So leave
5761 this assuming that the adjustable offset must be valid for the
5762 sub-words of a TFmode operand, which is what we had before. */
5765 rs6000_mode_dependent_address (rtx addr
)
5767 switch (GET_CODE (addr
))
5770 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
5771 is considered a legitimate address before reload, so there
5772 are no offset restrictions in that case. Note that this
5773 condition is safe in strict mode because any address involving
5774 virtual_stack_vars_rtx or arg_pointer_rtx would already have
5775 been rejected as illegitimate. */
5776 if (XEXP (addr
, 0) != virtual_stack_vars_rtx
5777 && XEXP (addr
, 0) != arg_pointer_rtx
5778 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
5780 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
5781 return val
+ 12 + 0x8000 >= 0x10000;
5788 /* Auto-increment cases are now treated generically in recog.c. */
5790 return TARGET_UPDATE
;
5792 /* AND is only allowed in Altivec loads. */
5803 /* Debug version of rs6000_mode_dependent_address. */
5805 rs6000_debug_mode_dependent_address (rtx addr
)
5807 bool ret
= rs6000_mode_dependent_address (addr
);
5809 fprintf (stderr
, "\nrs6000_mode_dependent_address: ret = %s\n",
5810 ret
? "true" : "false");
5816 /* Implement FIND_BASE_TERM. */
5819 rs6000_find_base_term (rtx op
)
5823 split_const (op
, &base
, &offset
);
5824 if (GET_CODE (base
) == UNSPEC
)
5825 switch (XINT (base
, 1))
5828 case UNSPEC_MACHOPIC_OFFSET
:
5829 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
5830 for aliasing purposes. */
5831 return XVECEXP (base
, 0, 0);
5837 /* More elaborate version of recog's offsettable_memref_p predicate
5838 that works around the ??? note of rs6000_mode_dependent_address.
5839 In particular it accepts
5841 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
5843 in 32-bit mode, that the recog predicate rejects. */
5846 rs6000_offsettable_memref_p (rtx op
)
5851 /* First mimic offsettable_memref_p. */
5852 if (offsettable_address_p (1, GET_MODE (op
), XEXP (op
, 0)))
5855 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
5856 the latter predicate knows nothing about the mode of the memory
5857 reference and, therefore, assumes that it is the largest supported
5858 mode (TFmode). As a consequence, legitimate offsettable memory
5859 references are rejected. rs6000_legitimate_offset_address_p contains
5860 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
5861 return rs6000_legitimate_offset_address_p (GET_MODE (op
), XEXP (op
, 0), 1);
5864 /* Change register usage conditional on target flags. */
5866 rs6000_conditional_register_usage (void)
5870 /* Set MQ register fixed (already call_used) if not POWER
5871 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
5876 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
5878 fixed_regs
[13] = call_used_regs
[13]
5879 = call_really_used_regs
[13] = 1;
5881 /* Conditionally disable FPRs. */
5882 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
5883 for (i
= 32; i
< 64; i
++)
5884 fixed_regs
[i
] = call_used_regs
[i
]
5885 = call_really_used_regs
[i
] = 1;
5887 /* The TOC register is not killed across calls in a way that is
5888 visible to the compiler. */
5889 if (DEFAULT_ABI
== ABI_AIX
)
5890 call_really_used_regs
[2] = 0;
5892 if (DEFAULT_ABI
== ABI_V4
5893 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
5895 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
5897 if (DEFAULT_ABI
== ABI_V4
5898 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
5900 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
5901 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
5902 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
5904 if (DEFAULT_ABI
== ABI_DARWIN
5905 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
5906 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
5907 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
5908 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
5910 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
5911 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
5912 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
5916 global_regs
[SPEFSCR_REGNO
] = 1;
5917 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
5918 registers in prologues and epilogues. We no longer use r14
5919 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
5920 pool for link-compatibility with older versions of GCC. Once
5921 "old" code has died out, we can return r14 to the allocation
5924 = call_used_regs
[14]
5925 = call_really_used_regs
[14] = 1;
5928 if (!TARGET_ALTIVEC
&& !TARGET_VSX
)
5930 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
5931 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
5932 call_really_used_regs
[VRSAVE_REGNO
] = 1;
5935 if (TARGET_ALTIVEC
|| TARGET_VSX
)
5936 global_regs
[VSCR_REGNO
] = 1;
5938 if (TARGET_ALTIVEC_ABI
)
5940 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
5941 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
5943 /* AIX reserves VR20:31 in non-extended ABI mode. */
5945 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
< FIRST_ALTIVEC_REGNO
+ 32; ++i
)
5946 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
5950 /* Try to output insns to set TARGET equal to the constant C if it can
5951 be done in less than N insns. Do all computations in MODE.
5952 Returns the place where the output has been placed if it can be
5953 done and the insns have been emitted. If it would take more than N
5954 insns, zero is returned and no insns and emitted. */
5957 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
5958 rtx source
, int n ATTRIBUTE_UNUSED
)
5960 rtx result
, insn
, set
;
5961 HOST_WIDE_INT c0
, c1
;
5968 dest
= gen_reg_rtx (mode
);
5969 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
5973 result
= !can_create_pseudo_p () ? dest
: gen_reg_rtx (SImode
);
5975 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (result
),
5976 GEN_INT (INTVAL (source
)
5977 & (~ (HOST_WIDE_INT
) 0xffff))));
5978 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
5979 gen_rtx_IOR (SImode
, copy_rtx (result
),
5980 GEN_INT (INTVAL (source
) & 0xffff))));
5985 switch (GET_CODE (source
))
5988 c0
= INTVAL (source
);
5993 #if HOST_BITS_PER_WIDE_INT >= 64
5994 c0
= CONST_DOUBLE_LOW (source
);
5997 c0
= CONST_DOUBLE_LOW (source
);
5998 c1
= CONST_DOUBLE_HIGH (source
);
6006 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
6013 insn
= get_last_insn ();
6014 set
= single_set (insn
);
6015 if (! CONSTANT_P (SET_SRC (set
)))
6016 set_unique_reg_note (insn
, REG_EQUAL
, source
);
6021 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6022 fall back to a straight forward decomposition. We do this to avoid
6023 exponential run times encountered when looking for longer sequences
6024 with rs6000_emit_set_const. */
6026 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
6028 if (!TARGET_POWERPC64
)
6030 rtx operand1
, operand2
;
6032 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
6034 operand2
= operand_subword_force (copy_rtx (dest
), WORDS_BIG_ENDIAN
!= 0,
6036 emit_move_insn (operand1
, GEN_INT (c1
));
6037 emit_move_insn (operand2
, GEN_INT (c2
));
6041 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
6044 ud2
= (c1
& 0xffff0000) >> 16;
6045 #if HOST_BITS_PER_WIDE_INT >= 64
6049 ud4
= (c2
& 0xffff0000) >> 16;
6051 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
6052 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
6055 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
6057 emit_move_insn (dest
, GEN_INT (ud1
));
6060 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
6061 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
6064 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
6067 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
6069 emit_move_insn (copy_rtx (dest
),
6070 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6073 else if ((ud4
== 0xffff && (ud3
& 0x8000))
6074 || (ud4
== 0 && ! (ud3
& 0x8000)))
6077 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
6080 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
6083 emit_move_insn (copy_rtx (dest
),
6084 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6086 emit_move_insn (copy_rtx (dest
),
6087 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
6090 emit_move_insn (copy_rtx (dest
),
6091 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6097 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
6100 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
6103 emit_move_insn (copy_rtx (dest
),
6104 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6107 emit_move_insn (copy_rtx (dest
),
6108 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
6111 emit_move_insn (copy_rtx (dest
),
6112 gen_rtx_IOR (DImode
, copy_rtx (dest
),
6113 GEN_INT (ud2
<< 16)));
6115 emit_move_insn (copy_rtx (dest
),
6116 gen_rtx_IOR (DImode
, copy_rtx (dest
), GEN_INT (ud1
)));
6122 /* Helper for the following. Get rid of [r+r] memory refs
6123 in cases where it won't work (TImode, TFmode, TDmode). */
6126 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
6128 if (GET_CODE (operands
[0]) == MEM
6129 && GET_CODE (XEXP (operands
[0], 0)) != REG
6130 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0))
6131 && ! reload_in_progress
)
6133 = replace_equiv_address (operands
[0],
6134 copy_addr_to_reg (XEXP (operands
[0], 0)));
6136 if (GET_CODE (operands
[1]) == MEM
6137 && GET_CODE (XEXP (operands
[1], 0)) != REG
6138 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0))
6139 && ! reload_in_progress
)
6141 = replace_equiv_address (operands
[1],
6142 copy_addr_to_reg (XEXP (operands
[1], 0)));
6145 /* Emit a move from SOURCE to DEST in mode MODE. */
6147 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
6151 operands
[1] = source
;
6153 if (TARGET_DEBUG_ADDR
)
6156 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6157 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6158 GET_MODE_NAME (mode
),
6161 can_create_pseudo_p ());
6163 fprintf (stderr
, "source:\n");
6167 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6168 if (GET_CODE (operands
[1]) == CONST_DOUBLE
6169 && ! FLOAT_MODE_P (mode
)
6170 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
6172 /* FIXME. This should never happen. */
6173 /* Since it seems that it does, do the safe thing and convert
6175 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
6177 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
6178 || FLOAT_MODE_P (mode
)
6179 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
6180 || CONST_DOUBLE_LOW (operands
[1]) < 0)
6181 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
6182 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
6184 /* Check if GCC is setting up a block move that will end up using FP
6185 registers as temporaries. We must make sure this is acceptable. */
6186 if (GET_CODE (operands
[0]) == MEM
6187 && GET_CODE (operands
[1]) == MEM
6189 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
6190 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
6191 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
6192 ? 32 : MEM_ALIGN (operands
[0])))
6193 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
6195 : MEM_ALIGN (operands
[1]))))
6196 && ! MEM_VOLATILE_P (operands
[0])
6197 && ! MEM_VOLATILE_P (operands
[1]))
6199 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
6200 adjust_address (operands
[1], SImode
, 0));
6201 emit_move_insn (adjust_address (copy_rtx (operands
[0]), SImode
, 4),
6202 adjust_address (copy_rtx (operands
[1]), SImode
, 4));
6206 /* Fix up invalid (const (plus (symbol_ref) (reg))) that seems to be created
6207 in the secondary_reload phase, which evidently overwrites the CONST_INT
6209 if (GET_CODE (source
) == CONST
&& GET_CODE (XEXP (source
, 0)) == PLUS
6212 rtx add_op0
= XEXP (XEXP (source
, 0), 0);
6213 rtx add_op1
= XEXP (XEXP (source
, 0), 1);
6215 if (GET_CODE (add_op0
) == SYMBOL_REF
&& GET_CODE (add_op1
) == REG
)
6217 rtx tmp
= (can_create_pseudo_p ()) ? gen_reg_rtx (Pmode
) : dest
;
6219 if (TARGET_DEBUG_ADDR
)
6221 fprintf (stderr
, "\nrs6000_emit_move: bad source\n");
6225 rs6000_emit_move (tmp
, add_op0
, Pmode
);
6226 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
6227 gen_rtx_PLUS (Pmode
, tmp
, add_op1
)));
6232 if (can_create_pseudo_p () && GET_CODE (operands
[0]) == MEM
6233 && !gpc_reg_operand (operands
[1], mode
))
6234 operands
[1] = force_reg (mode
, operands
[1]);
6236 if (mode
== SFmode
&& ! TARGET_POWERPC
6237 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
6238 && GET_CODE (operands
[0]) == MEM
)
6242 if (reload_in_progress
|| reload_completed
)
6243 regnum
= true_regnum (operands
[1]);
6244 else if (GET_CODE (operands
[1]) == REG
)
6245 regnum
= REGNO (operands
[1]);
6249 /* If operands[1] is a register, on POWER it may have
6250 double-precision data in it, so truncate it to single
6252 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
6255 newreg
= (!can_create_pseudo_p () ? copy_rtx (operands
[1])
6256 : gen_reg_rtx (mode
));
6257 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
6258 operands
[1] = newreg
;
6262 /* Recognize the case where operand[1] is a reference to thread-local
6263 data and load its address to a register. */
6264 if (rs6000_tls_referenced_p (operands
[1]))
6266 enum tls_model model
;
6267 rtx tmp
= operands
[1];
6270 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
6272 addend
= XEXP (XEXP (tmp
, 0), 1);
6273 tmp
= XEXP (XEXP (tmp
, 0), 0);
6276 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
6277 model
= SYMBOL_REF_TLS_MODEL (tmp
);
6278 gcc_assert (model
!= 0);
6280 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
6283 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
6284 tmp
= force_operand (tmp
, operands
[0]);
6289 /* Handle the case where reload calls us with an invalid address. */
6290 if (reload_in_progress
&& mode
== Pmode
6291 && (! general_operand (operands
[1], mode
)
6292 || ! nonimmediate_operand (operands
[0], mode
)))
6295 /* 128-bit constant floating-point values on Darwin should really be
6296 loaded as two parts. */
6297 if (!TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
6298 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
6300 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6301 know how to get a DFmode SUBREG of a TFmode. */
6302 enum machine_mode imode
= (TARGET_E500_DOUBLE
? DFmode
: DImode
);
6303 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
, 0),
6304 simplify_gen_subreg (imode
, operands
[1], mode
, 0),
6306 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
,
6307 GET_MODE_SIZE (imode
)),
6308 simplify_gen_subreg (imode
, operands
[1], mode
,
6309 GET_MODE_SIZE (imode
)),
6314 if (reload_in_progress
&& cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
6315 cfun
->machine
->sdmode_stack_slot
=
6316 eliminate_regs (cfun
->machine
->sdmode_stack_slot
, VOIDmode
, NULL_RTX
);
6318 if (reload_in_progress
6320 && MEM_P (operands
[0])
6321 && rtx_equal_p (operands
[0], cfun
->machine
->sdmode_stack_slot
)
6322 && REG_P (operands
[1]))
6324 if (FP_REGNO_P (REGNO (operands
[1])))
6326 rtx mem
= adjust_address_nv (operands
[0], DDmode
, 0);
6327 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
6328 emit_insn (gen_movsd_store (mem
, operands
[1]));
6330 else if (INT_REGNO_P (REGNO (operands
[1])))
6332 rtx mem
= adjust_address_nv (operands
[0], mode
, 4);
6333 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
6334 emit_insn (gen_movsd_hardfloat (mem
, operands
[1]));
6340 if (reload_in_progress
6342 && REG_P (operands
[0])
6343 && MEM_P (operands
[1])
6344 && rtx_equal_p (operands
[1], cfun
->machine
->sdmode_stack_slot
))
6346 if (FP_REGNO_P (REGNO (operands
[0])))
6348 rtx mem
= adjust_address_nv (operands
[1], DDmode
, 0);
6349 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
6350 emit_insn (gen_movsd_load (operands
[0], mem
));
6352 else if (INT_REGNO_P (REGNO (operands
[0])))
6354 rtx mem
= adjust_address_nv (operands
[1], mode
, 4);
6355 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
6356 emit_insn (gen_movsd_hardfloat (operands
[0], mem
));
6363 /* FIXME: In the long term, this switch statement should go away
6364 and be replaced by a sequence of tests based on things like
6370 if (CONSTANT_P (operands
[1])
6371 && GET_CODE (operands
[1]) != CONST_INT
)
6372 operands
[1] = force_const_mem (mode
, operands
[1]);
6377 rs6000_eliminate_indexed_memrefs (operands
);
6384 if (CONSTANT_P (operands
[1])
6385 && ! easy_fp_constant (operands
[1], mode
))
6386 operands
[1] = force_const_mem (mode
, operands
[1]);
6399 if (CONSTANT_P (operands
[1])
6400 && !easy_vector_constant (operands
[1], mode
))
6401 operands
[1] = force_const_mem (mode
, operands
[1]);
6406 /* Use default pattern for address of ELF small data */
6409 && DEFAULT_ABI
== ABI_V4
6410 && (GET_CODE (operands
[1]) == SYMBOL_REF
6411 || GET_CODE (operands
[1]) == CONST
)
6412 && small_data_operand (operands
[1], mode
))
6414 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
6418 if (DEFAULT_ABI
== ABI_V4
6419 && mode
== Pmode
&& mode
== SImode
6420 && flag_pic
== 1 && got_operand (operands
[1], mode
))
6422 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
6426 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
6430 && CONSTANT_P (operands
[1])
6431 && GET_CODE (operands
[1]) != HIGH
6432 && GET_CODE (operands
[1]) != CONST_INT
)
6434 rtx target
= (!can_create_pseudo_p ()
6436 : gen_reg_rtx (mode
));
6438 /* If this is a function address on -mcall-aixdesc,
6439 convert it to the address of the descriptor. */
6440 if (DEFAULT_ABI
== ABI_AIX
6441 && GET_CODE (operands
[1]) == SYMBOL_REF
6442 && XSTR (operands
[1], 0)[0] == '.')
6444 const char *name
= XSTR (operands
[1], 0);
6446 while (*name
== '.')
6448 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
6449 CONSTANT_POOL_ADDRESS_P (new_ref
)
6450 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
6451 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
6452 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
6453 SYMBOL_REF_DATA (new_ref
) = SYMBOL_REF_DATA (operands
[1]);
6454 operands
[1] = new_ref
;
6457 if (DEFAULT_ABI
== ABI_DARWIN
)
6460 if (MACHO_DYNAMIC_NO_PIC_P
)
6462 /* Take care of any required data indirection. */
6463 operands
[1] = rs6000_machopic_legitimize_pic_address (
6464 operands
[1], mode
, operands
[0]);
6465 if (operands
[0] != operands
[1])
6466 emit_insn (gen_rtx_SET (VOIDmode
,
6467 operands
[0], operands
[1]));
6471 emit_insn (gen_macho_high (target
, operands
[1]));
6472 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
6476 emit_insn (gen_elf_high (target
, operands
[1]));
6477 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
6481 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6482 and we have put it in the TOC, we just need to make a TOC-relative
6485 && GET_CODE (operands
[1]) == SYMBOL_REF
6486 && constant_pool_expr_p (operands
[1])
6487 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
6488 get_pool_mode (operands
[1])))
6490 operands
[1] = create_TOC_reference (operands
[1]);
6492 else if (mode
== Pmode
6493 && CONSTANT_P (operands
[1])
6494 && ((GET_CODE (operands
[1]) != CONST_INT
6495 && ! easy_fp_constant (operands
[1], mode
))
6496 || (GET_CODE (operands
[1]) == CONST_INT
6497 && num_insns_constant (operands
[1], mode
) > 2)
6498 || (GET_CODE (operands
[0]) == REG
6499 && FP_REGNO_P (REGNO (operands
[0]))))
6500 && GET_CODE (operands
[1]) != HIGH
6501 && ! legitimate_constant_pool_address_p (operands
[1])
6502 && ! toc_relative_expr_p (operands
[1]))
6506 /* Darwin uses a special PIC legitimizer. */
6507 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
6510 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
6512 if (operands
[0] != operands
[1])
6513 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
6518 /* If we are to limit the number of things we put in the TOC and
6519 this is a symbol plus a constant we can add in one insn,
6520 just put the symbol in the TOC and add the constant. Don't do
6521 this if reload is in progress. */
6522 if (GET_CODE (operands
[1]) == CONST
6523 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
6524 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
6525 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
6526 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
6527 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
6528 && ! side_effects_p (operands
[0]))
6531 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
6532 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
6534 sym
= force_reg (mode
, sym
);
6535 emit_insn (gen_add3_insn (operands
[0], sym
, other
));
6539 operands
[1] = force_const_mem (mode
, operands
[1]);
6542 && GET_CODE (XEXP (operands
[1], 0)) == SYMBOL_REF
6543 && constant_pool_expr_p (XEXP (operands
[1], 0))
6544 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6545 get_pool_constant (XEXP (operands
[1], 0)),
6546 get_pool_mode (XEXP (operands
[1], 0))))
6549 = gen_const_mem (mode
,
6550 create_TOC_reference (XEXP (operands
[1], 0)));
6551 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
6557 rs6000_eliminate_indexed_memrefs (operands
);
6561 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
6563 gen_rtx_SET (VOIDmode
,
6564 operands
[0], operands
[1]),
6565 gen_rtx_CLOBBER (VOIDmode
,
6566 gen_rtx_SCRATCH (SImode
)))));
6572 fatal_insn ("bad move", gen_rtx_SET (VOIDmode
, dest
, source
));
6575 /* Above, we may have called force_const_mem which may have returned
6576 an invalid address. If we can, fix this up; otherwise, reload will
6577 have to deal with it. */
6578 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
6579 operands
[1] = validize_mem (operands
[1]);
6582 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
6585 /* Nonzero if we can use a floating-point register to pass this arg. */
6586 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
6587 (SCALAR_FLOAT_MODE_P (MODE) \
6588 && (CUM)->fregno <= FP_ARG_MAX_REG \
6589 && TARGET_HARD_FLOAT && TARGET_FPRS)
6591 /* Nonzero if we can use an AltiVec register to pass this arg. */
6592 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
6593 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
6594 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
6595 && TARGET_ALTIVEC_ABI \
6598 /* Return a nonzero value to say to return the function value in
6599 memory, just as large structures are always returned. TYPE will be
6600 the data type of the value, and FNTYPE will be the type of the
6601 function doing the returning, or @code{NULL} for libcalls.
6603 The AIX ABI for the RS/6000 specifies that all structures are
6604 returned in memory. The Darwin ABI does the same. The SVR4 ABI
6605 specifies that structures <= 8 bytes are returned in r3/r4, but a
6606 draft put them in memory, and GCC used to implement the draft
6607 instead of the final standard. Therefore, aix_struct_return
6608 controls this instead of DEFAULT_ABI; V.4 targets needing backward
6609 compatibility can change DRAFT_V4_STRUCT_RET to override the
6610 default, and -m switches get the final word. See
6611 rs6000_override_options for more details.
6613 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
6614 long double support is enabled. These values are returned in memory.
6616 int_size_in_bytes returns -1 for variable size objects, which go in
6617 memory always. The cast to unsigned makes -1 > 8. */
6620 rs6000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
6622 /* In the darwin64 abi, try to use registers for larger structs
6624 if (rs6000_darwin64_abi
6625 && TREE_CODE (type
) == RECORD_TYPE
6626 && int_size_in_bytes (type
) > 0)
6628 CUMULATIVE_ARGS valcum
;
6632 valcum
.fregno
= FP_ARG_MIN_REG
;
6633 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
6634 /* Do a trial code generation as if this were going to be passed
6635 as an argument; if any part goes in memory, we return NULL. */
6636 valret
= rs6000_darwin64_record_arg (&valcum
, type
, 1, true);
6639 /* Otherwise fall through to more conventional ABI rules. */
6642 if (AGGREGATE_TYPE_P (type
)
6643 && (aix_struct_return
6644 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
6647 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6648 modes only exist for GCC vector types if -maltivec. */
6649 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
6650 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
6653 /* Return synthetic vectors in memory. */
6654 if (TREE_CODE (type
) == VECTOR_TYPE
6655 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
6657 static bool warned_for_return_big_vectors
= false;
6658 if (!warned_for_return_big_vectors
)
6660 warning (0, "GCC vector returned by reference: "
6661 "non-standard ABI extension with no compatibility guarantee");
6662 warned_for_return_big_vectors
= true;
6667 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& TYPE_MODE (type
) == TFmode
)
6673 /* Initialize a variable CUM of type CUMULATIVE_ARGS
6674 for a call to a function whose data type is FNTYPE.
6675 For a library call, FNTYPE is 0.
6677 For incoming args we set the number of arguments in the prototype large
6678 so we never return a PARALLEL. */
6681 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
6682 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
6683 int libcall
, int n_named_args
)
6685 static CUMULATIVE_ARGS zero_cumulative
;
6687 *cum
= zero_cumulative
;
6689 cum
->fregno
= FP_ARG_MIN_REG
;
6690 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
6691 cum
->prototype
= (fntype
&& TYPE_ARG_TYPES (fntype
));
6692 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
6693 ? CALL_LIBCALL
: CALL_NORMAL
);
6694 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
6695 cum
->stdarg
= fntype
6696 && (TYPE_ARG_TYPES (fntype
) != 0
6697 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
6698 != void_type_node
));
6700 cum
->nargs_prototype
= 0;
6701 if (incoming
|| cum
->prototype
)
6702 cum
->nargs_prototype
= n_named_args
;
6704 /* Check for a longcall attribute. */
6705 if ((!fntype
&& rs6000_default_long_calls
)
6707 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
6708 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
6709 cum
->call_cookie
|= CALL_LONG
;
6711 if (TARGET_DEBUG_ARG
)
6713 fprintf (stderr
, "\ninit_cumulative_args:");
6716 tree ret_type
= TREE_TYPE (fntype
);
6717 fprintf (stderr
, " ret code = %s,",
6718 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
6721 if (cum
->call_cookie
& CALL_LONG
)
6722 fprintf (stderr
, " longcall,");
6724 fprintf (stderr
, " proto = %d, nargs = %d\n",
6725 cum
->prototype
, cum
->nargs_prototype
);
6730 && TARGET_ALTIVEC_ABI
6731 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
6733 error ("cannot return value in vector register because"
6734 " altivec instructions are disabled, use -maltivec"
6739 /* Return true if TYPE must be passed on the stack and not in registers. */
6742 rs6000_must_pass_in_stack (enum machine_mode mode
, const_tree type
)
6744 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
6745 return must_pass_in_stack_var_size (mode
, type
);
6747 return must_pass_in_stack_var_size_or_pad (mode
, type
);
6750 /* If defined, a C expression which determines whether, and in which
6751 direction, to pad out an argument with extra space. The value
6752 should be of type `enum direction': either `upward' to pad above
6753 the argument, `downward' to pad below, or `none' to inhibit
6756 For the AIX ABI structs are always stored left shifted in their
6760 function_arg_padding (enum machine_mode mode
, const_tree type
)
6762 #ifndef AGGREGATE_PADDING_FIXED
6763 #define AGGREGATE_PADDING_FIXED 0
6765 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
6766 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
6769 if (!AGGREGATE_PADDING_FIXED
)
6771 /* GCC used to pass structures of the same size as integer types as
6772 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
6773 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6774 passed padded downward, except that -mstrict-align further
6775 muddied the water in that multi-component structures of 2 and 4
6776 bytes in size were passed padded upward.
6778 The following arranges for best compatibility with previous
6779 versions of gcc, but removes the -mstrict-align dependency. */
6780 if (BYTES_BIG_ENDIAN
)
6782 HOST_WIDE_INT size
= 0;
6784 if (mode
== BLKmode
)
6786 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
6787 size
= int_size_in_bytes (type
);
6790 size
= GET_MODE_SIZE (mode
);
6792 if (size
== 1 || size
== 2 || size
== 4)
6798 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
6800 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
6804 /* Fall back to the default. */
6805 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
6808 /* If defined, a C expression that gives the alignment boundary, in bits,
6809 of an argument with the specified mode and type. If it is not defined,
6810 PARM_BOUNDARY is used for all arguments.
6812 V.4 wants long longs and doubles to be double word aligned. Just
6813 testing the mode size is a boneheaded way to do this as it means
6814 that other types such as complex int are also double word aligned.
6815 However, we're stuck with this because changing the ABI might break
6816 existing library interfaces.
6818 Doubleword align SPE vectors.
6819 Quadword align Altivec vectors.
6820 Quadword align large synthetic vector types. */
6823 function_arg_boundary (enum machine_mode mode
, tree type
)
6825 if (DEFAULT_ABI
== ABI_V4
6826 && (GET_MODE_SIZE (mode
) == 8
6827 || (TARGET_HARD_FLOAT
6829 && (mode
== TFmode
|| mode
== TDmode
))))
6831 else if (SPE_VECTOR_MODE (mode
)
6832 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
6833 && int_size_in_bytes (type
) >= 8
6834 && int_size_in_bytes (type
) < 16))
6836 else if ((ALTIVEC_VECTOR_MODE (mode
) || VSX_VECTOR_MODE (mode
))
6837 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
6838 && int_size_in_bytes (type
) >= 16))
6840 else if (rs6000_darwin64_abi
&& mode
== BLKmode
6841 && type
&& TYPE_ALIGN (type
) > 64)
6844 return PARM_BOUNDARY
;
6847 /* For a function parm of MODE and TYPE, return the starting word in
6848 the parameter area. NWORDS of the parameter area are already used. */
6851 rs6000_parm_start (enum machine_mode mode
, tree type
, unsigned int nwords
)
6854 unsigned int parm_offset
;
6856 align
= function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
6857 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
6858 return nwords
+ (-(parm_offset
+ nwords
) & align
);
6861 /* Compute the size (in words) of a function argument. */
6863 static unsigned long
6864 rs6000_arg_size (enum machine_mode mode
, tree type
)
6868 if (mode
!= BLKmode
)
6869 size
= GET_MODE_SIZE (mode
);
6871 size
= int_size_in_bytes (type
);
6874 return (size
+ 3) >> 2;
6876 return (size
+ 7) >> 3;
6879 /* Use this to flush pending int fields. */
6882 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
6883 HOST_WIDE_INT bitpos
)
6885 unsigned int startbit
, endbit
;
6886 int intregs
, intoffset
;
6887 enum machine_mode mode
;
6889 if (cum
->intoffset
== -1)
6892 intoffset
= cum
->intoffset
;
6893 cum
->intoffset
= -1;
6895 if (intoffset
% BITS_PER_WORD
!= 0)
6897 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
6899 if (mode
== BLKmode
)
6901 /* We couldn't find an appropriate mode, which happens,
6902 e.g., in packed structs when there are 3 bytes to load.
6903 Back intoffset back to the beginning of the word in this
6905 intoffset
= intoffset
& -BITS_PER_WORD
;
6909 startbit
= intoffset
& -BITS_PER_WORD
;
6910 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
6911 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
6912 cum
->words
+= intregs
;
6915 /* The darwin64 ABI calls for us to recurse down through structs,
6916 looking for elements passed in registers. Unfortunately, we have
6917 to track int register count here also because of misalignments
6918 in powerpc alignment mode. */
6921 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
6923 HOST_WIDE_INT startbitpos
)
6927 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
6928 if (TREE_CODE (f
) == FIELD_DECL
)
6930 HOST_WIDE_INT bitpos
= startbitpos
;
6931 tree ftype
= TREE_TYPE (f
);
6932 enum machine_mode mode
;
6933 if (ftype
== error_mark_node
)
6935 mode
= TYPE_MODE (ftype
);
6937 if (DECL_SIZE (f
) != 0
6938 && host_integerp (bit_position (f
), 1))
6939 bitpos
+= int_bit_position (f
);
6941 /* ??? FIXME: else assume zero offset. */
6943 if (TREE_CODE (ftype
) == RECORD_TYPE
)
6944 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
6945 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
6947 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
6948 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
6949 cum
->words
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
6951 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
6953 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
6957 else if (cum
->intoffset
== -1)
6958 cum
->intoffset
= bitpos
;
6962 /* Update the data in CUM to advance over an argument
6963 of mode MODE and data type TYPE.
6964 (TYPE is null for libcalls where that information may not be available.)
6966 Note that for args passed by reference, function_arg will be called
6967 with MODE and TYPE set to that of the pointer to the arg, not the arg
6971 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6972 tree type
, int named
, int depth
)
6976 /* Only tick off an argument if we're not recursing. */
6978 cum
->nargs_prototype
--;
6980 if (TARGET_ALTIVEC_ABI
6981 && (ALTIVEC_VECTOR_MODE (mode
)
6982 || VSX_VECTOR_MODE (mode
)
6983 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
6984 && int_size_in_bytes (type
) == 16)))
6988 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
6991 if (!TARGET_ALTIVEC
)
6992 error ("cannot pass argument in vector register because"
6993 " altivec instructions are disabled, use -maltivec"
6996 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
6997 even if it is going to be passed in a vector register.
6998 Darwin does the same for variable-argument functions. */
6999 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
7000 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
7010 /* Vector parameters must be 16-byte aligned. This places
7011 them at 2 mod 4 in terms of words in 32-bit mode, since
7012 the parameter save area starts at offset 24 from the
7013 stack. In 64-bit mode, they just have to start on an
7014 even word, since the parameter save area is 16-byte
7015 aligned. Space for GPRs is reserved even if the argument
7016 will be passed in memory. */
7018 align
= (2 - cum
->words
) & 3;
7020 align
= cum
->words
& 1;
7021 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
7023 if (TARGET_DEBUG_ARG
)
7025 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
7027 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
7028 cum
->nargs_prototype
, cum
->prototype
,
7029 GET_MODE_NAME (mode
));
7033 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
7035 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
7038 else if (rs6000_darwin64_abi
7040 && TREE_CODE (type
) == RECORD_TYPE
7041 && (size
= int_size_in_bytes (type
)) > 0)
7043 /* Variable sized types have size == -1 and are
7044 treated as if consisting entirely of ints.
7045 Pad to 16 byte boundary if needed. */
7046 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
7047 && (cum
->words
% 2) != 0)
7049 /* For varargs, we can just go up by the size of the struct. */
7051 cum
->words
+= (size
+ 7) / 8;
7054 /* It is tempting to say int register count just goes up by
7055 sizeof(type)/8, but this is wrong in a case such as
7056 { int; double; int; } [powerpc alignment]. We have to
7057 grovel through the fields for these too. */
7059 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
7060 rs6000_darwin64_record_arg_advance_flush (cum
,
7061 size
* BITS_PER_UNIT
);
7064 else if (DEFAULT_ABI
== ABI_V4
)
7066 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
7067 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
7068 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
7069 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
7070 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
7072 /* _Decimal128 must use an even/odd register pair. This assumes
7073 that the register number is odd when fregno is odd. */
7074 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
7077 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
7078 <= FP_ARG_V4_MAX_REG
)
7079 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
7082 cum
->fregno
= FP_ARG_V4_MAX_REG
+ 1;
7083 if (mode
== DFmode
|| mode
== TFmode
7084 || mode
== DDmode
|| mode
== TDmode
)
7085 cum
->words
+= cum
->words
& 1;
7086 cum
->words
+= rs6000_arg_size (mode
, type
);
7091 int n_words
= rs6000_arg_size (mode
, type
);
7092 int gregno
= cum
->sysv_gregno
;
7094 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7095 (r7,r8) or (r9,r10). As does any other 2 word item such
7096 as complex int due to a historical mistake. */
7098 gregno
+= (1 - gregno
) & 1;
7100 /* Multi-reg args are not split between registers and stack. */
7101 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
7103 /* Long long and SPE vectors are aligned on the stack.
7104 So are other 2 word items such as complex int due to
7105 a historical mistake. */
7107 cum
->words
+= cum
->words
& 1;
7108 cum
->words
+= n_words
;
7111 /* Note: continuing to accumulate gregno past when we've started
7112 spilling to the stack indicates the fact that we've started
7113 spilling to the stack to expand_builtin_saveregs. */
7114 cum
->sysv_gregno
= gregno
+ n_words
;
7117 if (TARGET_DEBUG_ARG
)
7119 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
7120 cum
->words
, cum
->fregno
);
7121 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
7122 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
7123 fprintf (stderr
, "mode = %4s, named = %d\n",
7124 GET_MODE_NAME (mode
), named
);
7129 int n_words
= rs6000_arg_size (mode
, type
);
7130 int start_words
= cum
->words
;
7131 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
7133 cum
->words
= align_words
+ n_words
;
7135 if (SCALAR_FLOAT_MODE_P (mode
)
7136 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
7138 /* _Decimal128 must be passed in an even/odd float register pair.
7139 This assumes that the register number is odd when fregno is
7141 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
7143 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
7146 if (TARGET_DEBUG_ARG
)
7148 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
7149 cum
->words
, cum
->fregno
);
7150 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
7151 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
7152 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
7153 named
, align_words
- start_words
, depth
);
7159 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
7166 r1
= gen_rtx_REG (DImode
, gregno
);
7167 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
7168 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
7172 r1
= gen_rtx_REG (DImode
, gregno
);
7173 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
7174 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
7175 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
7176 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
7179 r1
= gen_rtx_REG (DImode
, gregno
);
7180 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
7181 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
7182 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
7183 r5
= gen_rtx_REG (DImode
, gregno
+ 4);
7184 r5
= gen_rtx_EXPR_LIST (VOIDmode
, r5
, GEN_INT (16));
7185 r7
= gen_rtx_REG (DImode
, gregno
+ 6);
7186 r7
= gen_rtx_EXPR_LIST (VOIDmode
, r7
, GEN_INT (24));
7187 return gen_rtx_PARALLEL (mode
, gen_rtvec (4, r1
, r3
, r5
, r7
));
7194 /* Determine where to put a SIMD argument on the SPE. */
7196 rs6000_spe_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
7199 int gregno
= cum
->sysv_gregno
;
7201 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7202 are passed and returned in a pair of GPRs for ABI compatibility. */
7203 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
7204 || mode
== DCmode
|| mode
== TCmode
))
7206 int n_words
= rs6000_arg_size (mode
, type
);
7208 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7210 gregno
+= (1 - gregno
) & 1;
7212 /* Multi-reg args are not split between registers and stack. */
7213 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
7216 return spe_build_register_parallel (mode
, gregno
);
7220 int n_words
= rs6000_arg_size (mode
, type
);
7222 /* SPE vectors are put in odd registers. */
7223 if (n_words
== 2 && (gregno
& 1) == 0)
7226 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
7229 enum machine_mode m
= SImode
;
7231 r1
= gen_rtx_REG (m
, gregno
);
7232 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
7233 r2
= gen_rtx_REG (m
, gregno
+ 1);
7234 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
7235 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
7242 if (gregno
<= GP_ARG_MAX_REG
)
7243 return gen_rtx_REG (mode
, gregno
);
7249 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7250 structure between cum->intoffset and bitpos to integer registers. */
7253 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
7254 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
7256 enum machine_mode mode
;
7258 unsigned int startbit
, endbit
;
7259 int this_regno
, intregs
, intoffset
;
7262 if (cum
->intoffset
== -1)
7265 intoffset
= cum
->intoffset
;
7266 cum
->intoffset
= -1;
7268 /* If this is the trailing part of a word, try to only load that
7269 much into the register. Otherwise load the whole register. Note
7270 that in the latter case we may pick up unwanted bits. It's not a
7271 problem at the moment but may wish to revisit. */
7273 if (intoffset
% BITS_PER_WORD
!= 0)
7275 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
7277 if (mode
== BLKmode
)
7279 /* We couldn't find an appropriate mode, which happens,
7280 e.g., in packed structs when there are 3 bytes to load.
7281 Back intoffset back to the beginning of the word in this
7283 intoffset
= intoffset
& -BITS_PER_WORD
;
7290 startbit
= intoffset
& -BITS_PER_WORD
;
7291 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
7292 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
7293 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
7295 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
7298 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
7302 intoffset
/= BITS_PER_UNIT
;
7305 regno
= GP_ARG_MIN_REG
+ this_regno
;
7306 reg
= gen_rtx_REG (mode
, regno
);
7308 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
7311 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
7315 while (intregs
> 0);
7318 /* Recursive workhorse for the following. */
7321 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, const_tree type
,
7322 HOST_WIDE_INT startbitpos
, rtx rvec
[],
7327 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
7328 if (TREE_CODE (f
) == FIELD_DECL
)
7330 HOST_WIDE_INT bitpos
= startbitpos
;
7331 tree ftype
= TREE_TYPE (f
);
7332 enum machine_mode mode
;
7333 if (ftype
== error_mark_node
)
7335 mode
= TYPE_MODE (ftype
);
7337 if (DECL_SIZE (f
) != 0
7338 && host_integerp (bit_position (f
), 1))
7339 bitpos
+= int_bit_position (f
);
7341 /* ??? FIXME: else assume zero offset. */
7343 if (TREE_CODE (ftype
) == RECORD_TYPE
)
7344 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
7345 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
7350 case SCmode
: mode
= SFmode
; break;
7351 case DCmode
: mode
= DFmode
; break;
7352 case TCmode
: mode
= TFmode
; break;
7356 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
7358 = gen_rtx_EXPR_LIST (VOIDmode
,
7359 gen_rtx_REG (mode
, cum
->fregno
++),
7360 GEN_INT (bitpos
/ BITS_PER_UNIT
));
7361 if (mode
== TFmode
|| mode
== TDmode
)
7364 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
7366 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
7368 = gen_rtx_EXPR_LIST (VOIDmode
,
7369 gen_rtx_REG (mode
, cum
->vregno
++),
7370 GEN_INT (bitpos
/ BITS_PER_UNIT
));
7372 else if (cum
->intoffset
== -1)
7373 cum
->intoffset
= bitpos
;
7377 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7378 the register(s) to be used for each field and subfield of a struct
7379 being passed by value, along with the offset of where the
7380 register's value may be found in the block. FP fields go in FP
7381 register, vector fields go in vector registers, and everything
7382 else goes in int registers, packed as in memory.
7384 This code is also used for function return values. RETVAL indicates
7385 whether this is the case.
7387 Much of this is taken from the SPARC V9 port, which has a similar
7388 calling convention. */
7391 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, const_tree type
,
7392 int named
, bool retval
)
7394 rtx rvec
[FIRST_PSEUDO_REGISTER
];
7395 int k
= 1, kbase
= 1;
7396 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
7397 /* This is a copy; modifications are not visible to our caller. */
7398 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
7399 CUMULATIVE_ARGS
*cum
= ©_cum
;
7401 /* Pad to 16 byte boundary if needed. */
7402 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
7403 && (cum
->words
% 2) != 0)
7410 /* Put entries into rvec[] for individual FP and vector fields, and
7411 for the chunks of memory that go in int regs. Note we start at
7412 element 1; 0 is reserved for an indication of using memory, and
7413 may or may not be filled in below. */
7414 rs6000_darwin64_record_arg_recurse (cum
, type
, 0, rvec
, &k
);
7415 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
7417 /* If any part of the struct went on the stack put all of it there.
7418 This hack is because the generic code for
7419 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7420 parts of the struct are not at the beginning. */
7424 return NULL_RTX
; /* doesn't go in registers at all */
7426 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
7428 if (k
> 1 || cum
->use_stack
)
7429 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
7434 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7437 rs6000_mixed_function_arg (enum machine_mode mode
, tree type
, int align_words
)
7441 rtx rvec
[GP_ARG_NUM_REG
+ 1];
7443 if (align_words
>= GP_ARG_NUM_REG
)
7446 n_units
= rs6000_arg_size (mode
, type
);
7448 /* Optimize the simple case where the arg fits in one gpr, except in
7449 the case of BLKmode due to assign_parms assuming that registers are
7450 BITS_PER_WORD wide. */
7452 || (n_units
== 1 && mode
!= BLKmode
))
7453 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
7456 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
7457 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7458 using a magic NULL_RTX component.
7459 This is not strictly correct. Only some of the arg belongs in
7460 memory, not all of it. However, the normal scheme using
7461 function_arg_partial_nregs can result in unusual subregs, eg.
7462 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7463 store the whole arg to memory is often more efficient than code
7464 to store pieces, and we know that space is available in the right
7465 place for the whole arg. */
7466 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
7471 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
7472 rtx off
= GEN_INT (i
++ * 4);
7473 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
7475 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
7477 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
7480 /* Determine where to put an argument to a function.
7481 Value is zero to push the argument on the stack,
7482 or a hard register in which to store the argument.
7484 MODE is the argument's machine mode.
7485 TYPE is the data type of the argument (as a tree).
7486 This is null for libcalls where that information may
7488 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7489 the preceding args and about the function being called. It is
7490 not modified in this routine.
7491 NAMED is nonzero if this argument is a named parameter
7492 (otherwise it is an extra parameter matching an ellipsis).
7494 On RS/6000 the first eight words of non-FP are normally in registers
7495 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7496 Under V.4, the first 8 FP args are in registers.
7498 If this is floating-point and no prototype is specified, we use
7499 both an FP and integer register (or possibly FP reg and stack). Library
7500 functions (when CALL_LIBCALL is set) always have the proper types for args,
7501 so we can pass the FP value just in one register. emit_library_function
7502 doesn't support PARALLEL anyway.
7504 Note that for args passed by reference, function_arg will be called
7505 with MODE and TYPE set to that of the pointer to the arg, not the arg
7509 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
7510 tree type
, int named
)
7512 enum rs6000_abi abi
= DEFAULT_ABI
;
7514 /* Return a marker to indicate whether CR1 needs to set or clear the
7515 bit that V.4 uses to say fp args were passed in registers.
7516 Assume that we don't need the marker for software floating point,
7517 or compiler generated library calls. */
7518 if (mode
== VOIDmode
)
7521 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
7523 || (cum
->nargs_prototype
< 0
7524 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))))
7526 /* For the SPE, we need to crxor CR6 always. */
7528 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
7529 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
7530 return GEN_INT (cum
->call_cookie
7531 | ((cum
->fregno
== FP_ARG_MIN_REG
)
7532 ? CALL_V4_SET_FP_ARGS
7533 : CALL_V4_CLEAR_FP_ARGS
));
7536 return GEN_INT (cum
->call_cookie
);
7539 if (rs6000_darwin64_abi
&& mode
== BLKmode
7540 && TREE_CODE (type
) == RECORD_TYPE
)
7542 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, false);
7543 if (rslt
!= NULL_RTX
)
7545 /* Else fall through to usual handling. */
7548 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
7549 if (TARGET_64BIT
&& ! cum
->prototype
)
7551 /* Vector parameters get passed in vector register
7552 and also in GPRs or memory, in absence of prototype. */
7555 align_words
= (cum
->words
+ 1) & ~1;
7557 if (align_words
>= GP_ARG_NUM_REG
)
7563 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
7565 return gen_rtx_PARALLEL (mode
,
7567 gen_rtx_EXPR_LIST (VOIDmode
,
7569 gen_rtx_EXPR_LIST (VOIDmode
,
7570 gen_rtx_REG (mode
, cum
->vregno
),
7574 return gen_rtx_REG (mode
, cum
->vregno
);
7575 else if (TARGET_ALTIVEC_ABI
7576 && (ALTIVEC_VECTOR_MODE (mode
)
7577 || VSX_VECTOR_MODE (mode
)
7578 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
7579 && int_size_in_bytes (type
) == 16)))
7581 if (named
|| abi
== ABI_V4
)
7585 /* Vector parameters to varargs functions under AIX or Darwin
7586 get passed in memory and possibly also in GPRs. */
7587 int align
, align_words
, n_words
;
7588 enum machine_mode part_mode
;
7590 /* Vector parameters must be 16-byte aligned. This places them at
7591 2 mod 4 in terms of words in 32-bit mode, since the parameter
7592 save area starts at offset 24 from the stack. In 64-bit mode,
7593 they just have to start on an even word, since the parameter
7594 save area is 16-byte aligned. */
7596 align
= (2 - cum
->words
) & 3;
7598 align
= cum
->words
& 1;
7599 align_words
= cum
->words
+ align
;
7601 /* Out of registers? Memory, then. */
7602 if (align_words
>= GP_ARG_NUM_REG
)
7605 if (TARGET_32BIT
&& TARGET_POWERPC64
)
7606 return rs6000_mixed_function_arg (mode
, type
, align_words
);
7608 /* The vector value goes in GPRs. Only the part of the
7609 value in GPRs is reported here. */
7611 n_words
= rs6000_arg_size (mode
, type
);
7612 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
7613 /* Fortunately, there are only two possibilities, the value
7614 is either wholly in GPRs or half in GPRs and half not. */
7617 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
7620 else if (TARGET_SPE_ABI
&& TARGET_SPE
7621 && (SPE_VECTOR_MODE (mode
)
7622 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
7625 || mode
== TCmode
))))
7626 return rs6000_spe_function_arg (cum
, mode
, type
);
7628 else if (abi
== ABI_V4
)
7630 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
7631 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
7632 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
7633 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
7634 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
7636 /* _Decimal128 must use an even/odd register pair. This assumes
7637 that the register number is odd when fregno is odd. */
7638 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
7641 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
7642 <= FP_ARG_V4_MAX_REG
)
7643 return gen_rtx_REG (mode
, cum
->fregno
);
7649 int n_words
= rs6000_arg_size (mode
, type
);
7650 int gregno
= cum
->sysv_gregno
;
7652 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7653 (r7,r8) or (r9,r10). As does any other 2 word item such
7654 as complex int due to a historical mistake. */
7656 gregno
+= (1 - gregno
) & 1;
7658 /* Multi-reg args are not split between registers and stack. */
7659 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
7662 if (TARGET_32BIT
&& TARGET_POWERPC64
)
7663 return rs6000_mixed_function_arg (mode
, type
,
7664 gregno
- GP_ARG_MIN_REG
);
7665 return gen_rtx_REG (mode
, gregno
);
7670 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
7672 /* _Decimal128 must be passed in an even/odd float register pair.
7673 This assumes that the register number is odd when fregno is odd. */
7674 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
7677 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
7679 rtx rvec
[GP_ARG_NUM_REG
+ 1];
7683 enum machine_mode fmode
= mode
;
7684 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
7686 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
7688 /* Currently, we only ever need one reg here because complex
7689 doubles are split. */
7690 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
7691 && (fmode
== TFmode
|| fmode
== TDmode
));
7693 /* Long double or _Decimal128 split over regs and memory. */
7694 fmode
= DECIMAL_FLOAT_MODE_P (fmode
) ? DDmode
: DFmode
;
7697 /* Do we also need to pass this arg in the parameter save
7700 && (cum
->nargs_prototype
<= 0
7701 || (DEFAULT_ABI
== ABI_AIX
7703 && align_words
>= GP_ARG_NUM_REG
)));
7705 if (!needs_psave
&& mode
== fmode
)
7706 return gen_rtx_REG (fmode
, cum
->fregno
);
7711 /* Describe the part that goes in gprs or the stack.
7712 This piece must come first, before the fprs. */
7713 if (align_words
< GP_ARG_NUM_REG
)
7715 unsigned long n_words
= rs6000_arg_size (mode
, type
);
7717 if (align_words
+ n_words
> GP_ARG_NUM_REG
7718 || (TARGET_32BIT
&& TARGET_POWERPC64
))
7720 /* If this is partially on the stack, then we only
7721 include the portion actually in registers here. */
7722 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
7725 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
7726 /* Not all of the arg fits in gprs. Say that it
7727 goes in memory too, using a magic NULL_RTX
7728 component. Also see comment in
7729 rs6000_mixed_function_arg for why the normal
7730 function_arg_partial_nregs scheme doesn't work
7732 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
7736 r
= gen_rtx_REG (rmode
,
7737 GP_ARG_MIN_REG
+ align_words
);
7738 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
7739 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
7741 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
7745 /* The whole arg fits in gprs. */
7746 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
7747 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
7751 /* It's entirely in memory. */
7752 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
7755 /* Describe where this piece goes in the fprs. */
7756 r
= gen_rtx_REG (fmode
, cum
->fregno
);
7757 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
7759 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
7761 else if (align_words
< GP_ARG_NUM_REG
)
7763 if (TARGET_32BIT
&& TARGET_POWERPC64
)
7764 return rs6000_mixed_function_arg (mode
, type
, align_words
);
7766 if (mode
== BLKmode
)
7769 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
7776 /* For an arg passed partly in registers and partly in memory, this is
7777 the number of bytes passed in registers. For args passed entirely in
7778 registers or entirely in memory, zero. When an arg is described by a
7779 PARALLEL, perhaps using more than one register type, this function
7780 returns the number of bytes used by the first element of the PARALLEL. */
7783 rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
7784 tree type
, bool named
)
7789 if (DEFAULT_ABI
== ABI_V4
)
7792 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
7793 && cum
->nargs_prototype
>= 0)
7796 /* In this complicated case we just disable the partial_nregs code. */
7797 if (rs6000_darwin64_abi
&& mode
== BLKmode
7798 && TREE_CODE (type
) == RECORD_TYPE
7799 && int_size_in_bytes (type
) > 0)
7802 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
7804 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
7806 /* If we are passing this arg in the fixed parameter save area
7807 (gprs or memory) as well as fprs, then this function should
7808 return the number of partial bytes passed in the parameter
7809 save area rather than partial bytes passed in fprs. */
7811 && (cum
->nargs_prototype
<= 0
7812 || (DEFAULT_ABI
== ABI_AIX
7814 && align_words
>= GP_ARG_NUM_REG
)))
7816 else if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3)
7817 > FP_ARG_MAX_REG
+ 1)
7818 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
7819 else if (cum
->nargs_prototype
>= 0)
7823 if (align_words
< GP_ARG_NUM_REG
7824 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
7825 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
7827 if (ret
!= 0 && TARGET_DEBUG_ARG
)
7828 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
7833 /* A C expression that indicates when an argument must be passed by
7834 reference. If nonzero for an argument, a copy of that argument is
7835 made in memory and a pointer to the argument is passed instead of
7836 the argument itself. The pointer is passed in whatever way is
7837 appropriate for passing a pointer to that type.
7839 Under V.4, aggregates and long double are passed by reference.
7841 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
7842 reference unless the AltiVec vector extension ABI is in force.
7844 As an extension to all ABIs, variable sized types are passed by
7848 rs6000_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
7849 enum machine_mode mode
, const_tree type
,
7850 bool named ATTRIBUTE_UNUSED
)
7852 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& mode
== TFmode
)
7854 if (TARGET_DEBUG_ARG
)
7855 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
7862 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
7864 if (TARGET_DEBUG_ARG
)
7865 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
7869 if (int_size_in_bytes (type
) < 0)
7871 if (TARGET_DEBUG_ARG
)
7872 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
7876 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7877 modes only exist for GCC vector types if -maltivec. */
7878 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
7880 if (TARGET_DEBUG_ARG
)
7881 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
7885 /* Pass synthetic vectors in memory. */
7886 if (TREE_CODE (type
) == VECTOR_TYPE
7887 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
7889 static bool warned_for_pass_big_vectors
= false;
7890 if (TARGET_DEBUG_ARG
)
7891 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
7892 if (!warned_for_pass_big_vectors
)
7894 warning (0, "GCC vector passed by reference: "
7895 "non-standard ABI extension with no compatibility guarantee");
7896 warned_for_pass_big_vectors
= true;
7905 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
7908 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
7913 for (i
= 0; i
< nregs
; i
++)
7915 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
7916 if (reload_completed
)
7918 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
7921 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
7922 i
* GET_MODE_SIZE (reg_mode
));
7925 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
7929 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
7933 /* Perform any needed actions needed for a function that is receiving a
7934 variable number of arguments.
7938 MODE and TYPE are the mode and type of the current parameter.
7940 PRETEND_SIZE is a variable that should be set to the amount of stack
7941 that must be pushed by the prolog to pretend that our caller pushed
7944 Normally, this macro will push all remaining incoming registers on the
7945 stack and set PRETEND_SIZE to the length of the registers pushed. */
7948 setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
7949 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
7952 CUMULATIVE_ARGS next_cum
;
7953 int reg_size
= TARGET_32BIT
? 4 : 8;
7954 rtx save_area
= NULL_RTX
, mem
;
7955 int first_reg_offset
;
7958 /* Skip the last named argument. */
7960 function_arg_advance (&next_cum
, mode
, type
, 1, 0);
7962 if (DEFAULT_ABI
== ABI_V4
)
7964 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
7968 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
7969 HOST_WIDE_INT offset
= 0;
7971 /* Try to optimize the size of the varargs save area.
7972 The ABI requires that ap.reg_save_area is doubleword
7973 aligned, but we don't need to allocate space for all
7974 the bytes, only those to which we actually will save
7976 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
7977 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
7978 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
7979 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
7980 && cfun
->va_list_fpr_size
)
7983 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
7984 * UNITS_PER_FP_WORD
;
7985 if (cfun
->va_list_fpr_size
7986 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
7987 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
7989 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
7990 * UNITS_PER_FP_WORD
;
7994 offset
= -((first_reg_offset
* reg_size
) & ~7);
7995 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
7997 gpr_reg_num
= cfun
->va_list_gpr_size
;
7998 if (reg_size
== 4 && (first_reg_offset
& 1))
8001 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
8004 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
8006 - (int) (GP_ARG_NUM_REG
* reg_size
);
8008 if (gpr_size
+ fpr_size
)
8011 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
8012 gcc_assert (GET_CODE (reg_save_area
) == MEM
);
8013 reg_save_area
= XEXP (reg_save_area
, 0);
8014 if (GET_CODE (reg_save_area
) == PLUS
)
8016 gcc_assert (XEXP (reg_save_area
, 0)
8017 == virtual_stack_vars_rtx
);
8018 gcc_assert (GET_CODE (XEXP (reg_save_area
, 1)) == CONST_INT
);
8019 offset
+= INTVAL (XEXP (reg_save_area
, 1));
8022 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
8025 cfun
->machine
->varargs_save_offset
= offset
;
8026 save_area
= plus_constant (virtual_stack_vars_rtx
, offset
);
8031 first_reg_offset
= next_cum
.words
;
8032 save_area
= virtual_incoming_args_rtx
;
8034 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
8035 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
8038 set
= get_varargs_alias_set ();
8039 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
8040 && cfun
->va_list_gpr_size
)
8042 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
8044 if (va_list_gpr_counter_field
)
8046 /* V4 va_list_gpr_size counts number of registers needed. */
8047 if (nregs
> cfun
->va_list_gpr_size
)
8048 nregs
= cfun
->va_list_gpr_size
;
8052 /* char * va_list instead counts number of bytes needed. */
8053 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
8054 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
8057 mem
= gen_rtx_MEM (BLKmode
,
8058 plus_constant (save_area
,
8059 first_reg_offset
* reg_size
));
8060 MEM_NOTRAP_P (mem
) = 1;
8061 set_mem_alias_set (mem
, set
);
8062 set_mem_align (mem
, BITS_PER_WORD
);
8064 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
8068 /* Save FP registers if needed. */
8069 if (DEFAULT_ABI
== ABI_V4
8070 && TARGET_HARD_FLOAT
&& TARGET_FPRS
8072 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
8073 && cfun
->va_list_fpr_size
)
8075 int fregno
= next_cum
.fregno
, nregs
;
8076 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
8077 rtx lab
= gen_label_rtx ();
8078 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
8079 * UNITS_PER_FP_WORD
);
8082 (gen_rtx_SET (VOIDmode
,
8084 gen_rtx_IF_THEN_ELSE (VOIDmode
,
8085 gen_rtx_NE (VOIDmode
, cr1
,
8087 gen_rtx_LABEL_REF (VOIDmode
, lab
),
8091 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
8092 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
8094 mem
= gen_rtx_MEM ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
8096 plus_constant (save_area
, off
));
8097 MEM_NOTRAP_P (mem
) = 1;
8098 set_mem_alias_set (mem
, set
);
8099 set_mem_align (mem
, GET_MODE_ALIGNMENT (
8100 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
8101 ? DFmode
: SFmode
));
8102 emit_move_insn (mem
, gen_rtx_REG (
8103 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
8104 ? DFmode
: SFmode
, fregno
));
8111 /* Create the va_list data type. */
8114 rs6000_build_builtin_va_list (void)
8116 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
8118 /* For AIX, prefer 'char *' because that's what the system
8119 header files like. */
8120 if (DEFAULT_ABI
!= ABI_V4
)
8121 return build_pointer_type (char_type_node
);
8123 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
8124 type_decl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
8125 get_identifier ("__va_list_tag"), record
);
8127 f_gpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("gpr"),
8128 unsigned_char_type_node
);
8129 f_fpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("fpr"),
8130 unsigned_char_type_node
);
8131 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8133 f_res
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
8134 get_identifier ("reserved"), short_unsigned_type_node
);
8135 f_ovf
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
8136 get_identifier ("overflow_arg_area"),
8138 f_sav
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
8139 get_identifier ("reg_save_area"),
8142 va_list_gpr_counter_field
= f_gpr
;
8143 va_list_fpr_counter_field
= f_fpr
;
8145 DECL_FIELD_CONTEXT (f_gpr
) = record
;
8146 DECL_FIELD_CONTEXT (f_fpr
) = record
;
8147 DECL_FIELD_CONTEXT (f_res
) = record
;
8148 DECL_FIELD_CONTEXT (f_ovf
) = record
;
8149 DECL_FIELD_CONTEXT (f_sav
) = record
;
8151 TREE_CHAIN (record
) = type_decl
;
8152 TYPE_NAME (record
) = type_decl
;
8153 TYPE_FIELDS (record
) = f_gpr
;
8154 TREE_CHAIN (f_gpr
) = f_fpr
;
8155 TREE_CHAIN (f_fpr
) = f_res
;
8156 TREE_CHAIN (f_res
) = f_ovf
;
8157 TREE_CHAIN (f_ovf
) = f_sav
;
8159 layout_type (record
);
8161 /* The correct type is an array type of one element. */
8162 return build_array_type (record
, build_index_type (size_zero_node
));
8165 /* Implement va_start. */
8168 rs6000_va_start (tree valist
, rtx nextarg
)
8170 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
8171 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
8172 tree gpr
, fpr
, ovf
, sav
, t
;
8174 /* Only SVR4 needs something special. */
8175 if (DEFAULT_ABI
!= ABI_V4
)
8177 std_expand_builtin_va_start (valist
, nextarg
);
8181 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
8182 f_fpr
= TREE_CHAIN (f_gpr
);
8183 f_res
= TREE_CHAIN (f_fpr
);
8184 f_ovf
= TREE_CHAIN (f_res
);
8185 f_sav
= TREE_CHAIN (f_ovf
);
8187 valist
= build_va_arg_indirect_ref (valist
);
8188 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
8189 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
8191 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
8193 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
8196 /* Count number of gp and fp argument registers used. */
8197 words
= crtl
->args
.info
.words
;
8198 n_gpr
= MIN (crtl
->args
.info
.sysv_gregno
- GP_ARG_MIN_REG
,
8200 n_fpr
= MIN (crtl
->args
.info
.fregno
- FP_ARG_MIN_REG
,
8203 if (TARGET_DEBUG_ARG
)
8204 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
8205 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
8206 words
, n_gpr
, n_fpr
);
8208 if (cfun
->va_list_gpr_size
)
8210 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
8211 build_int_cst (NULL_TREE
, n_gpr
));
8212 TREE_SIDE_EFFECTS (t
) = 1;
8213 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
8216 if (cfun
->va_list_fpr_size
)
8218 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
8219 build_int_cst (NULL_TREE
, n_fpr
));
8220 TREE_SIDE_EFFECTS (t
) = 1;
8221 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
8224 /* Find the overflow area. */
8225 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
8227 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ovf
), t
,
8228 size_int (words
* UNITS_PER_WORD
));
8229 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
8230 TREE_SIDE_EFFECTS (t
) = 1;
8231 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
8233 /* If there were no va_arg invocations, don't set up the register
8235 if (!cfun
->va_list_gpr_size
8236 && !cfun
->va_list_fpr_size
8237 && n_gpr
< GP_ARG_NUM_REG
8238 && n_fpr
< FP_ARG_V4_MAX_REG
)
8241 /* Find the register save area. */
8242 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
8243 if (cfun
->machine
->varargs_save_offset
)
8244 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (sav
), t
,
8245 size_int (cfun
->machine
->varargs_save_offset
));
8246 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
8247 TREE_SIDE_EFFECTS (t
) = 1;
8248 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
8251 /* Implement va_arg. */
8254 rs6000_gimplify_va_arg (tree valist
, tree type
, gimple_seq
*pre_p
,
8257 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
8258 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
8259 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
8260 tree lab_false
, lab_over
, addr
;
8262 tree ptrtype
= build_pointer_type_for_mode (type
, ptr_mode
, true);
8266 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
8268 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
8269 return build_va_arg_indirect_ref (t
);
8272 if (DEFAULT_ABI
!= ABI_V4
)
8274 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
8276 tree elem_type
= TREE_TYPE (type
);
8277 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
8278 int elem_size
= GET_MODE_SIZE (elem_mode
);
8280 if (elem_size
< UNITS_PER_WORD
)
8282 tree real_part
, imag_part
;
8283 gimple_seq post
= NULL
;
8285 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
8287 /* Copy the value into a temporary, lest the formal temporary
8288 be reused out from under us. */
8289 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
8290 gimple_seq_add_seq (pre_p
, post
);
8292 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
8295 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
8299 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
8302 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
8303 f_fpr
= TREE_CHAIN (f_gpr
);
8304 f_res
= TREE_CHAIN (f_fpr
);
8305 f_ovf
= TREE_CHAIN (f_res
);
8306 f_sav
= TREE_CHAIN (f_ovf
);
8308 valist
= build_va_arg_indirect_ref (valist
);
8309 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
8310 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
8312 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
8314 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
8317 size
= int_size_in_bytes (type
);
8318 rsize
= (size
+ 3) / 4;
8321 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
8322 && ((TARGET_SINGLE_FLOAT
&& TYPE_MODE (type
) == SFmode
)
8323 || (TARGET_DOUBLE_FLOAT
8324 && (TYPE_MODE (type
) == DFmode
8325 || TYPE_MODE (type
) == TFmode
8326 || TYPE_MODE (type
) == SDmode
8327 || TYPE_MODE (type
) == DDmode
8328 || TYPE_MODE (type
) == TDmode
))))
8330 /* FP args go in FP registers, if present. */
8332 n_reg
= (size
+ 7) / 8;
8333 sav_ofs
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4) * 4;
8334 sav_scale
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4);
8335 if (TYPE_MODE (type
) != SFmode
&& TYPE_MODE (type
) != SDmode
)
8340 /* Otherwise into GP registers. */
8349 /* Pull the value out of the saved registers.... */
8352 addr
= create_tmp_var (ptr_type_node
, "addr");
8354 /* AltiVec vectors never go in registers when -mabi=altivec. */
8355 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
8359 lab_false
= create_artificial_label (input_location
);
8360 lab_over
= create_artificial_label (input_location
);
8362 /* Long long and SPE vectors are aligned in the registers.
8363 As are any other 2 gpr item such as complex int due to a
8364 historical mistake. */
8366 if (n_reg
== 2 && reg
== gpr
)
8369 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
8370 build_int_cst (TREE_TYPE (reg
), n_reg
- 1));
8371 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
),
8372 unshare_expr (reg
), u
);
8374 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8375 reg number is 0 for f1, so we want to make it odd. */
8376 else if (reg
== fpr
&& TYPE_MODE (type
) == TDmode
)
8378 t
= build2 (BIT_IOR_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
8379 build_int_cst (TREE_TYPE (reg
), 1));
8380 u
= build2 (MODIFY_EXPR
, void_type_node
, unshare_expr (reg
), t
);
8383 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
8384 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
8385 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
8386 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
8387 gimplify_and_add (t
, pre_p
);
8391 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, sav
, size_int (sav_ofs
));
8393 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
8394 build_int_cst (TREE_TYPE (reg
), n_reg
));
8395 u
= fold_convert (sizetype
, u
);
8396 u
= build2 (MULT_EXPR
, sizetype
, u
, size_int (sav_scale
));
8397 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
, u
);
8399 /* _Decimal32 varargs are located in the second word of the 64-bit
8400 FP register for 32-bit binaries. */
8401 if (!TARGET_POWERPC64
8402 && TARGET_HARD_FLOAT
&& TARGET_FPRS
8403 && TYPE_MODE (type
) == SDmode
)
8404 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
8406 gimplify_assign (addr
, t
, pre_p
);
8408 gimple_seq_add_stmt (pre_p
, gimple_build_goto (lab_over
));
8410 stmt
= gimple_build_label (lab_false
);
8411 gimple_seq_add_stmt (pre_p
, stmt
);
8413 if ((n_reg
== 2 && !regalign
) || n_reg
> 2)
8415 /* Ensure that we don't find any more args in regs.
8416 Alignment has taken care of for special cases. */
8417 gimplify_assign (reg
, build_int_cst (TREE_TYPE (reg
), 8), pre_p
);
8421 /* ... otherwise out of the overflow area. */
8423 /* Care for on-stack alignment if needed. */
8427 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (align
- 1));
8428 t
= fold_convert (sizetype
, t
);
8429 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
8431 t
= fold_convert (TREE_TYPE (ovf
), t
);
8433 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
8435 gimplify_assign (unshare_expr (addr
), t
, pre_p
);
8437 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
8438 gimplify_assign (unshare_expr (ovf
), t
, pre_p
);
8442 stmt
= gimple_build_label (lab_over
);
8443 gimple_seq_add_stmt (pre_p
, stmt
);
8446 if (STRICT_ALIGNMENT
8447 && (TYPE_ALIGN (type
)
8448 > (unsigned) BITS_PER_UNIT
* (align
< 4 ? 4 : align
)))
8450 /* The value (of type complex double, for example) may not be
8451 aligned in memory in the saved registers, so copy via a
8452 temporary. (This is the same code as used for SPARC.) */
8453 tree tmp
= create_tmp_var (type
, "va_arg_tmp");
8454 tree dest_addr
= build_fold_addr_expr (tmp
);
8456 tree copy
= build_call_expr (implicit_built_in_decls
[BUILT_IN_MEMCPY
],
8457 3, dest_addr
, addr
, size_int (rsize
* 4));
8459 gimplify_and_add (copy
, pre_p
);
8463 addr
= fold_convert (ptrtype
, addr
);
8464 return build_va_arg_indirect_ref (addr
);
8470 def_builtin (int mask
, const char *name
, tree type
, int code
)
8472 if ((mask
& target_flags
) || TARGET_PAIRED_FLOAT
)
8474 if (rs6000_builtin_decls
[code
])
8475 fatal_error ("internal error: builtin function to %s already processed.",
8478 rs6000_builtin_decls
[code
] =
8479 add_builtin_function (name
, type
, code
, BUILT_IN_MD
,
8484 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8486 static const struct builtin_description bdesc_3arg
[] =
8488 { MASK_ALTIVEC
, CODE_FOR_altivec_vmaddfp
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
8489 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
8490 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
8491 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
8492 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
8493 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
8494 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
8495 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
8496 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
8497 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
8498 { MASK_ALTIVEC
, CODE_FOR_altivec_vnmsubfp
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
8499 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2df
, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF
},
8500 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2di
, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI
},
8501 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
8502 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
8503 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
8504 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
8505 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v2di_uns
, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS
},
8506 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si_uns
, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS
},
8507 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi_uns
, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS
},
8508 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS
},
8509 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
8510 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
8511 { MASK_ALTIVEC
, CODE_FOR_vector_select_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
8512 { MASK_ALTIVEC
, CODE_FOR_vector_select_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
8513 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2df
, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF
},
8514 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2di
, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI
},
8515 { MASK_ALTIVEC
, CODE_FOR_vector_select_v4si_uns
, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS
},
8516 { MASK_ALTIVEC
, CODE_FOR_vector_select_v8hi_uns
, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS
},
8517 { MASK_ALTIVEC
, CODE_FOR_vector_select_v16qi_uns
, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS
},
8518 { MASK_ALTIVEC
, CODE_FOR_vector_select_v2di_uns
, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS
},
8519 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
8520 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
8521 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
8522 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
8524 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
8525 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
8526 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
8527 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
8528 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
8529 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
8530 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
8531 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
8532 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
8533 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
8534 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
8535 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
8536 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
8537 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
8538 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
8540 { MASK_VSX
, CODE_FOR_vsx_fmaddv2df4
, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP
},
8541 { MASK_VSX
, CODE_FOR_vsx_fmsubv2df4
, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP
},
8542 { MASK_VSX
, CODE_FOR_vsx_fnmaddv2df4
, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP
},
8543 { MASK_VSX
, CODE_FOR_vsx_fnmsubv2df4
, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP
},
8545 { MASK_VSX
, CODE_FOR_vsx_fmaddv4sf4
, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP
},
8546 { MASK_VSX
, CODE_FOR_vsx_fmsubv4sf4
, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP
},
8547 { MASK_VSX
, CODE_FOR_vsx_fnmaddv4sf4
, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP
},
8548 { MASK_VSX
, CODE_FOR_vsx_fnmsubv4sf4
, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP
},
8550 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB
},
8551 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD
},
8553 { MASK_VSX
, CODE_FOR_vector_select_v2di
, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI
},
8554 { MASK_VSX
, CODE_FOR_vector_select_v2df
, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF
},
8555 { MASK_VSX
, CODE_FOR_vector_select_v4sf
, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF
},
8556 { MASK_VSX
, CODE_FOR_vector_select_v4si
, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI
},
8557 { MASK_VSX
, CODE_FOR_vector_select_v8hi
, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI
},
8558 { MASK_VSX
, CODE_FOR_vector_select_v16qi
, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI
},
8559 { MASK_VSX
, CODE_FOR_vector_select_v2di_uns
, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS
},
8560 { MASK_VSX
, CODE_FOR_vector_select_v4si_uns
, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS
},
8561 { MASK_VSX
, CODE_FOR_vector_select_v8hi_uns
, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS
},
8562 { MASK_VSX
, CODE_FOR_vector_select_v16qi_uns
, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS
},
8564 { MASK_VSX
, CODE_FOR_altivec_vperm_v2di
, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI
},
8565 { MASK_VSX
, CODE_FOR_altivec_vperm_v2df
, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF
},
8566 { MASK_VSX
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF
},
8567 { MASK_VSX
, CODE_FOR_altivec_vperm_v4si
, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI
},
8568 { MASK_VSX
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI
},
8569 { MASK_VSX
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI
},
8570 { MASK_VSX
, CODE_FOR_altivec_vperm_v2di_uns
, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS
},
8571 { MASK_VSX
, CODE_FOR_altivec_vperm_v4si_uns
, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS
},
8572 { MASK_VSX
, CODE_FOR_altivec_vperm_v8hi_uns
, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS
},
8573 { MASK_VSX
, CODE_FOR_altivec_vperm_v16qi_uns
, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS
},
8575 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v2df
, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF
},
8576 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v2di
, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI
},
8577 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v4sf
, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF
},
8578 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v4si
, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI
},
8579 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v8hi
, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI
},
8580 { MASK_VSX
, CODE_FOR_vsx_xxpermdi_v16qi
, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI
},
8581 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI
},
8582 { MASK_VSX
, CODE_FOR_vsx_set_v2df
, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF
},
8583 { MASK_VSX
, CODE_FOR_vsx_set_v2di
, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI
},
8585 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v2di
, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI
},
8586 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v2df
, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF
},
8587 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v4sf
, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF
},
8588 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v4si
, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI
},
8589 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v8hi
, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI
},
8590 { MASK_VSX
, CODE_FOR_vsx_xxsldwi_v16qi
, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI
},
8591 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI
},
8593 { 0, CODE_FOR_paired_msub
, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB
},
8594 { 0, CODE_FOR_paired_madd
, "__builtin_paired_madd", PAIRED_BUILTIN_MADD
},
8595 { 0, CODE_FOR_paired_madds0
, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0
},
8596 { 0, CODE_FOR_paired_madds1
, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1
},
8597 { 0, CODE_FOR_paired_nmsub
, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB
},
8598 { 0, CODE_FOR_paired_nmadd
, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD
},
8599 { 0, CODE_FOR_paired_sum0
, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0
},
8600 { 0, CODE_FOR_paired_sum1
, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1
},
8601 { 0, CODE_FOR_selv2sf4
, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4
},
8604 /* DST operations: void foo (void *, const int, const char). */
8606 static const struct builtin_description bdesc_dst
[] =
8608 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
8609 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
8610 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
8611 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
8613 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
8614 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
8615 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
8616 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
8619 /* Simple binary operations: VECc = foo (VECa, VECb). */
8621 static struct builtin_description bdesc_2arg
[] =
8623 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
8624 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
8625 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
8626 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
8627 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
8628 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
8629 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
8630 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
8631 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
8632 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
8633 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
8634 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
8635 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
8636 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
8637 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
8638 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
8639 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
8640 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
8641 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
8642 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
8643 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
8644 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
8645 { MASK_ALTIVEC
, CODE_FOR_vector_eqv16qi
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
8646 { MASK_ALTIVEC
, CODE_FOR_vector_eqv8hi
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
8647 { MASK_ALTIVEC
, CODE_FOR_vector_eqv4si
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
8648 { MASK_ALTIVEC
, CODE_FOR_vector_eqv4sf
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
8649 { MASK_ALTIVEC
, CODE_FOR_vector_gev4sf
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
8650 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv16qi
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
8651 { MASK_ALTIVEC
, CODE_FOR_vector_gtv16qi
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
8652 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv8hi
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
8653 { MASK_ALTIVEC
, CODE_FOR_vector_gtv8hi
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
8654 { MASK_ALTIVEC
, CODE_FOR_vector_gtuv4si
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
8655 { MASK_ALTIVEC
, CODE_FOR_vector_gtv4si
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
8656 { MASK_ALTIVEC
, CODE_FOR_vector_gtv4sf
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
8657 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
8658 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
8659 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
8660 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
8661 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
8662 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
8663 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
8664 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
8665 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
8666 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
8667 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
8668 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
8669 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
8670 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
8671 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
8672 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
8673 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
8674 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
8675 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
8676 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
8677 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
8678 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
8679 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
8680 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS
},
8681 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
8682 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
8683 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS
},
8684 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
8685 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
8686 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS
},
8687 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
8688 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
8689 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS
},
8690 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
8691 { MASK_ALTIVEC
, CODE_FOR_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
8692 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
8693 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
8694 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
8695 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
8696 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
8697 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
8698 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
8699 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
8700 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
8701 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
8702 { MASK_ALTIVEC
, CODE_FOR_vrotlv16qi3
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
8703 { MASK_ALTIVEC
, CODE_FOR_vrotlv8hi3
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
8704 { MASK_ALTIVEC
, CODE_FOR_vrotlv4si3
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
8705 { MASK_ALTIVEC
, CODE_FOR_vashlv16qi3
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
8706 { MASK_ALTIVEC
, CODE_FOR_vashlv8hi3
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
8707 { MASK_ALTIVEC
, CODE_FOR_vashlv4si3
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
8708 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
8709 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
8710 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
8711 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
8712 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
8713 { MASK_ALTIVEC
, CODE_FOR_vlshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
8714 { MASK_ALTIVEC
, CODE_FOR_vlshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
8715 { MASK_ALTIVEC
, CODE_FOR_vlshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
8716 { MASK_ALTIVEC
, CODE_FOR_vashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
8717 { MASK_ALTIVEC
, CODE_FOR_vashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
8718 { MASK_ALTIVEC
, CODE_FOR_vashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
8719 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
8720 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
8721 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
8722 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
8723 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
8724 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
8725 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
8726 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
8727 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
8728 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
8729 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
8730 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
8731 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
8732 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
8733 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
8734 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
8735 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
8736 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
8737 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
8738 { MASK_ALTIVEC
, CODE_FOR_vector_copysignv4sf3
, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF
},
8740 { MASK_VSX
, CODE_FOR_addv2df3
, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP
},
8741 { MASK_VSX
, CODE_FOR_subv2df3
, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP
},
8742 { MASK_VSX
, CODE_FOR_mulv2df3
, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP
},
8743 { MASK_VSX
, CODE_FOR_divv2df3
, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP
},
8744 { MASK_VSX
, CODE_FOR_sminv2df3
, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP
},
8745 { MASK_VSX
, CODE_FOR_smaxv2df3
, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP
},
8746 { MASK_VSX
, CODE_FOR_vsx_tdivv2df3_fe
, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE
},
8747 { MASK_VSX
, CODE_FOR_vsx_tdivv2df3_fg
, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG
},
8748 { MASK_VSX
, CODE_FOR_vector_eqv2df
, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP
},
8749 { MASK_VSX
, CODE_FOR_vector_gtv2df
, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP
},
8750 { MASK_VSX
, CODE_FOR_vector_gev2df
, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP
},
8752 { MASK_VSX
, CODE_FOR_addv4sf3
, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP
},
8753 { MASK_VSX
, CODE_FOR_subv4sf3
, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP
},
8754 { MASK_VSX
, CODE_FOR_mulv4sf3
, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP
},
8755 { MASK_VSX
, CODE_FOR_divv4sf3
, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP
},
8756 { MASK_VSX
, CODE_FOR_sminv4sf3
, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP
},
8757 { MASK_VSX
, CODE_FOR_smaxv4sf3
, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP
},
8758 { MASK_VSX
, CODE_FOR_vsx_tdivv4sf3_fe
, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE
},
8759 { MASK_VSX
, CODE_FOR_vsx_tdivv4sf3_fg
, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG
},
8760 { MASK_VSX
, CODE_FOR_vector_eqv4sf
, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP
},
8761 { MASK_VSX
, CODE_FOR_vector_gtv4sf
, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP
},
8762 { MASK_VSX
, CODE_FOR_vector_gev4sf
, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP
},
8764 { MASK_VSX
, CODE_FOR_smindf3
, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP
},
8765 { MASK_VSX
, CODE_FOR_smaxdf3
, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP
},
8766 { MASK_VSX
, CODE_FOR_vsx_tdivdf3_fe
, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE
},
8767 { MASK_VSX
, CODE_FOR_vsx_tdivdf3_fg
, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG
},
8768 { MASK_VSX
, CODE_FOR_vector_copysignv2df3
, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP
},
8769 { MASK_VSX
, CODE_FOR_vector_copysignv4sf3
, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP
},
8771 { MASK_VSX
, CODE_FOR_vsx_concat_v2df
, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF
},
8772 { MASK_VSX
, CODE_FOR_vsx_concat_v2di
, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI
},
8773 { MASK_VSX
, CODE_FOR_vsx_splat_v2df
, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF
},
8774 { MASK_VSX
, CODE_FOR_vsx_splat_v2di
, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI
},
8775 { MASK_VSX
, CODE_FOR_vsx_xxmrghw_v4sf
, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF
},
8776 { MASK_VSX
, CODE_FOR_vsx_xxmrghw_v4si
, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI
},
8777 { MASK_VSX
, CODE_FOR_vsx_xxmrglw_v4sf
, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF
},
8778 { MASK_VSX
, CODE_FOR_vsx_xxmrglw_v4si
, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI
},
8780 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
8781 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
8782 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
8783 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
8784 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
8785 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
8786 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
8787 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
8788 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
8789 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
8790 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
8791 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
8792 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
8793 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
8794 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
8795 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
8796 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
8797 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
8798 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
8799 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
8800 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
8801 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
8802 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
8803 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
8804 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
8805 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
8806 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
8807 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
8808 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
8809 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
8810 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
8811 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
8812 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
8813 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
8814 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
8815 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
8816 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
8817 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
8818 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
8819 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN
},
8820 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
8821 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
8822 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
8823 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
8824 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
8825 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
8826 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
8827 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
8828 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
8829 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
8830 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
8831 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
8832 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
8833 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
8834 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
8835 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
8836 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
8837 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
8838 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
8839 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
8840 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
8841 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
8842 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
8843 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
8844 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
8845 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
8846 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
8847 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
8848 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
8849 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
8850 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
8851 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
8852 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
8853 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
8854 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
8855 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
8856 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
8857 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
8858 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
8859 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
8860 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
8861 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
8862 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
8863 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
8864 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
8865 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
8866 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
8867 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
8868 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
8869 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
8870 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
8871 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
8872 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
8873 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
8874 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
8875 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
8876 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
8877 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
8878 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
8879 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
8880 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
8881 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
8882 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
8883 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
8884 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
8885 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
8886 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
8887 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
8888 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
8889 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
8890 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
8891 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
8892 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
8893 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
8894 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
8895 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
8896 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
8897 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
8898 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
8899 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
8900 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
8901 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
8902 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
8903 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
8904 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
8905 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
8906 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
8907 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
8909 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL
},
8910 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV
},
8912 { 0, CODE_FOR_divv2sf3
, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3
},
8913 { 0, CODE_FOR_addv2sf3
, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3
},
8914 { 0, CODE_FOR_subv2sf3
, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3
},
8915 { 0, CODE_FOR_mulv2sf3
, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3
},
8916 { 0, CODE_FOR_paired_muls0
, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0
},
8917 { 0, CODE_FOR_paired_muls1
, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1
},
8918 { 0, CODE_FOR_paired_merge00
, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00
},
8919 { 0, CODE_FOR_paired_merge01
, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01
},
8920 { 0, CODE_FOR_paired_merge10
, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10
},
8921 { 0, CODE_FOR_paired_merge11
, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11
},
8923 /* Place holder, leave as first spe builtin. */
8924 { 0, CODE_FOR_spe_evaddw
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
8925 { 0, CODE_FOR_spe_evand
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
8926 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
8927 { 0, CODE_FOR_spe_evdivws
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
8928 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
8929 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
8930 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
8931 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
8932 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
8933 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
8934 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
8935 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
8936 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
8937 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
8938 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
8939 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
8940 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
8941 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
8942 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
8943 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
8944 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
8945 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
8946 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
8947 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
8948 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
8949 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
8950 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
8951 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
8952 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
8953 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
8954 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
8955 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
8956 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
8957 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
8958 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
8959 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
8960 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
8961 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
8962 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
8963 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
8964 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
8965 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
8966 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
8967 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
8968 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
8969 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
8970 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
8971 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
8972 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
8973 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
8974 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
8975 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
8976 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
8977 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
8978 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
8979 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
8980 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
8981 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
8982 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
8983 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
8984 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
8985 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
8986 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
8987 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
8988 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
8989 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
8990 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
8991 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
8992 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
8993 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
8994 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
8995 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
8996 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
8997 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
8998 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
8999 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
9000 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
9001 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
9002 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
9003 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
9004 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
9005 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
9006 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
9007 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
9008 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
9009 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
9010 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
9011 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
9012 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
9013 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
9014 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
9015 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
9016 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
9017 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
9018 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
9019 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
9020 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
9021 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
9022 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
9023 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
9024 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
9025 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
9026 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
9027 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
9028 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
9029 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
9030 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
9031 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
9032 { 0, CODE_FOR_spe_evsubfw
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
9034 /* SPE binary operations expecting a 5-bit unsigned literal. */
9035 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
9037 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
9038 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
9039 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
9040 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
9041 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
9042 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
9043 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
9044 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
9045 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
9046 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
9047 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
9048 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
9049 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
9050 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
9051 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
9052 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
9053 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
9054 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
9055 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
9056 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
9057 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
9058 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
9059 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
9060 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
9061 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
9062 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
9064 /* Place-holder. Leave as last binary SPE builtin. */
9065 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
9068 /* AltiVec predicates. */
9070 struct builtin_description_predicates
9072 const unsigned int mask
;
9073 const enum insn_code icode
;
9074 const char *const name
;
9075 const enum rs6000_builtins code
;
9078 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
9080 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp_p
, "__builtin_altivec_vcmpbfp_p",
9081 ALTIVEC_BUILTIN_VCMPBFP_P
},
9082 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_eq_v4sf_p
,
9083 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
9084 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_ge_v4sf_p
,
9085 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
9086 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_vector_gt_v4sf_p
,
9087 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
9088 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v4si_p
, "__builtin_altivec_vcmpequw_p",
9089 ALTIVEC_BUILTIN_VCMPEQUW_P
},
9090 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v4si_p
, "__builtin_altivec_vcmpgtsw_p",
9091 ALTIVEC_BUILTIN_VCMPGTSW_P
},
9092 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v4si_p
, "__builtin_altivec_vcmpgtuw_p",
9093 ALTIVEC_BUILTIN_VCMPGTUW_P
},
9094 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v8hi_p
, "__builtin_altivec_vcmpequh_p",
9095 ALTIVEC_BUILTIN_VCMPEQUH_P
},
9096 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v8hi_p
, "__builtin_altivec_vcmpgtsh_p",
9097 ALTIVEC_BUILTIN_VCMPGTSH_P
},
9098 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v8hi_p
, "__builtin_altivec_vcmpgtuh_p",
9099 ALTIVEC_BUILTIN_VCMPGTUH_P
},
9100 { MASK_ALTIVEC
, CODE_FOR_vector_eq_v16qi_p
, "__builtin_altivec_vcmpequb_p",
9101 ALTIVEC_BUILTIN_VCMPEQUB_P
},
9102 { MASK_ALTIVEC
, CODE_FOR_vector_gt_v16qi_p
, "__builtin_altivec_vcmpgtsb_p",
9103 ALTIVEC_BUILTIN_VCMPGTSB_P
},
9104 { MASK_ALTIVEC
, CODE_FOR_vector_gtu_v16qi_p
, "__builtin_altivec_vcmpgtub_p",
9105 ALTIVEC_BUILTIN_VCMPGTUB_P
},
9107 { MASK_VSX
, CODE_FOR_vector_eq_v4sf_p
, "__builtin_vsx_xvcmpeqsp_p",
9108 VSX_BUILTIN_XVCMPEQSP_P
},
9109 { MASK_VSX
, CODE_FOR_vector_ge_v4sf_p
, "__builtin_vsx_xvcmpgesp_p",
9110 VSX_BUILTIN_XVCMPGESP_P
},
9111 { MASK_VSX
, CODE_FOR_vector_gt_v4sf_p
, "__builtin_vsx_xvcmpgtsp_p",
9112 VSX_BUILTIN_XVCMPGTSP_P
},
9113 { MASK_VSX
, CODE_FOR_vector_eq_v2df_p
, "__builtin_vsx_xvcmpeqdp_p",
9114 VSX_BUILTIN_XVCMPEQDP_P
},
9115 { MASK_VSX
, CODE_FOR_vector_ge_v2df_p
, "__builtin_vsx_xvcmpgedp_p",
9116 VSX_BUILTIN_XVCMPGEDP_P
},
9117 { MASK_VSX
, CODE_FOR_vector_gt_v2df_p
, "__builtin_vsx_xvcmpgtdp_p",
9118 VSX_BUILTIN_XVCMPGTDP_P
},
9120 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpeq_p",
9121 ALTIVEC_BUILTIN_VCMPEQ_P
},
9122 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpgt_p",
9123 ALTIVEC_BUILTIN_VCMPGT_P
},
9124 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_vcmpge_p",
9125 ALTIVEC_BUILTIN_VCMPGE_P
}
9128 /* SPE predicates. */
9129 static struct builtin_description bdesc_spe_predicates
[] =
9131 /* Place-holder. Leave as first. */
9132 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
9133 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
9134 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
9135 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
9136 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
9137 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
9138 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
9139 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
9140 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
9141 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
9142 /* Place-holder. Leave as last. */
9143 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
9146 /* SPE evsel predicates. */
9147 static struct builtin_description bdesc_spe_evsel
[] =
9149 /* Place-holder. Leave as first. */
9150 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
9151 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
9152 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
9153 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
9154 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
9155 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
9156 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
9157 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
9158 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
9159 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
9160 /* Place-holder. Leave as last. */
9161 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
9164 /* PAIRED predicates. */
9165 static const struct builtin_description bdesc_paired_preds
[] =
9167 /* Place-holder. Leave as first. */
9168 { 0, CODE_FOR_paired_cmpu0
, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0
},
9169 /* Place-holder. Leave as last. */
9170 { 0, CODE_FOR_paired_cmpu1
, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1
},
9173 /* ABS* operations. */
9175 static const struct builtin_description bdesc_abs
[] =
9177 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
9178 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
9179 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
9180 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
9181 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
9182 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
9183 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
},
9184 { MASK_VSX
, CODE_FOR_absv2df2
, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP
},
9185 { MASK_VSX
, CODE_FOR_vsx_nabsv2df2
, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP
},
9186 { MASK_VSX
, CODE_FOR_absv4sf2
, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP
},
9187 { MASK_VSX
, CODE_FOR_vsx_nabsv4sf2
, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP
},
9190 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9193 static struct builtin_description bdesc_1arg
[] =
9195 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
9196 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
9197 { MASK_ALTIVEC
, CODE_FOR_altivec_vrefp
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
9198 { MASK_ALTIVEC
, CODE_FOR_vector_floorv4sf2
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
9199 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
9200 { MASK_ALTIVEC
, CODE_FOR_vector_ceilv4sf2
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
9201 { MASK_ALTIVEC
, CODE_FOR_vector_btruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
9202 { MASK_ALTIVEC
, CODE_FOR_altivec_vrsqrtefp
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
9203 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
9204 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
9205 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
9206 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
9207 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
9208 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
9209 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
9210 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
9211 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
9213 { MASK_VSX
, CODE_FOR_negv2df2
, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP
},
9214 { MASK_VSX
, CODE_FOR_sqrtv2df2
, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP
},
9215 { MASK_VSX
, CODE_FOR_vsx_rsqrtev2df2
, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP
},
9216 { MASK_VSX
, CODE_FOR_vsx_tsqrtv2df2_fe
, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE
},
9217 { MASK_VSX
, CODE_FOR_vsx_tsqrtv2df2_fg
, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG
},
9218 { MASK_VSX
, CODE_FOR_vsx_frev2df2
, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP
},
9220 { MASK_VSX
, CODE_FOR_negv4sf2
, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP
},
9221 { MASK_VSX
, CODE_FOR_sqrtv4sf2
, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP
},
9222 { MASK_VSX
, CODE_FOR_vsx_rsqrtev4sf2
, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP
},
9223 { MASK_VSX
, CODE_FOR_vsx_tsqrtv4sf2_fe
, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE
},
9224 { MASK_VSX
, CODE_FOR_vsx_tsqrtv4sf2_fg
, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG
},
9225 { MASK_VSX
, CODE_FOR_vsx_frev4sf2
, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP
},
9227 { MASK_VSX
, CODE_FOR_vsx_xscvdpsp
, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP
},
9228 { MASK_VSX
, CODE_FOR_vsx_xscvdpsp
, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP
},
9229 { MASK_VSX
, CODE_FOR_vsx_xvcvdpsp
, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP
},
9230 { MASK_VSX
, CODE_FOR_vsx_xvcvspdp
, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP
},
9231 { MASK_VSX
, CODE_FOR_vsx_tsqrtdf2_fe
, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE
},
9232 { MASK_VSX
, CODE_FOR_vsx_tsqrtdf2_fg
, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG
},
9234 { MASK_VSX
, CODE_FOR_vsx_fix_truncv2dfv2di2
, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS
},
9235 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv2dfv2di2
, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS
},
9236 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv2dfv2di2
, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS
},
9237 { MASK_VSX
, CODE_FOR_vsx_floatv2div2df2
, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP
},
9238 { MASK_VSX
, CODE_FOR_vsx_floatunsv2div2df2
, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP
},
9239 { MASK_VSX
, CODE_FOR_vsx_floatunsv2div2df2
, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS
},
9241 { MASK_VSX
, CODE_FOR_vsx_fix_truncv4sfv4si2
, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS
},
9242 { MASK_VSX
, CODE_FOR_vsx_fixuns_truncv4sfv4si2
, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS
},
9243 { MASK_VSX
, CODE_FOR_vsx_floatv4siv4sf2
, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP
},
9244 { MASK_VSX
, CODE_FOR_vsx_floatunsv4siv4sf2
, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP
},
9246 { MASK_VSX
, CODE_FOR_vsx_xvcvdpsxws
, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS
},
9247 { MASK_VSX
, CODE_FOR_vsx_xvcvdpuxws
, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS
},
9248 { MASK_VSX
, CODE_FOR_vsx_xvcvsxwdp
, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP
},
9249 { MASK_VSX
, CODE_FOR_vsx_xvcvuxwdp
, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP
},
9250 { MASK_VSX
, CODE_FOR_vsx_xvrdpi
, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI
},
9251 { MASK_VSX
, CODE_FOR_vsx_xvrdpic
, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC
},
9252 { MASK_VSX
, CODE_FOR_vsx_floorv2df2
, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM
},
9253 { MASK_VSX
, CODE_FOR_vsx_ceilv2df2
, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP
},
9254 { MASK_VSX
, CODE_FOR_vsx_btruncv2df2
, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ
},
9256 { MASK_VSX
, CODE_FOR_vsx_xvcvspsxds
, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS
},
9257 { MASK_VSX
, CODE_FOR_vsx_xvcvspuxds
, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS
},
9258 { MASK_VSX
, CODE_FOR_vsx_xvcvsxdsp
, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP
},
9259 { MASK_VSX
, CODE_FOR_vsx_xvcvuxdsp
, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP
},
9260 { MASK_VSX
, CODE_FOR_vsx_xvrspi
, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI
},
9261 { MASK_VSX
, CODE_FOR_vsx_xvrspic
, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC
},
9262 { MASK_VSX
, CODE_FOR_vsx_floorv4sf2
, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM
},
9263 { MASK_VSX
, CODE_FOR_vsx_ceilv4sf2
, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP
},
9264 { MASK_VSX
, CODE_FOR_vsx_btruncv4sf2
, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ
},
9266 { MASK_VSX
, CODE_FOR_vsx_xsrdpi
, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI
},
9267 { MASK_VSX
, CODE_FOR_vsx_xsrdpic
, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC
},
9268 { MASK_VSX
, CODE_FOR_vsx_floordf2
, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM
},
9269 { MASK_VSX
, CODE_FOR_vsx_ceildf2
, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP
},
9270 { MASK_VSX
, CODE_FOR_vsx_btruncdf2
, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ
},
9272 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
9273 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
9274 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
9275 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
9276 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
9277 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
9278 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
9279 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
9280 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
9281 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
9282 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
9283 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
9284 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
9285 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
9286 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
9287 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
9288 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
9289 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
9290 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
9292 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT
},
9293 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT
},
9294 { MASK_VSX
, CODE_FOR_nothing
, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT
},
9296 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_floatv4siv4sf2
, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF
},
9297 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_unsigned_floatv4siv4sf2
, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
},
9298 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_fix_truncv4sfv4si2
, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI
},
9299 { MASK_ALTIVEC
|MASK_VSX
, CODE_FOR_fixuns_truncv4sfv4si2
, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
},
9301 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9302 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9303 { 0, CODE_FOR_spe_evabs
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
9304 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
9305 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
9306 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
9307 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
9308 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
9309 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
9310 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
9311 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
9312 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
9313 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
9314 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
9315 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
9316 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
9317 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
9318 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
9319 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
9320 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
9321 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
9322 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
9323 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
9324 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
9325 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
9326 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
9327 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
9328 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
9329 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
9330 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
9332 /* Place-holder. Leave as last unary SPE builtin. */
9333 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
},
9335 { 0, CODE_FOR_absv2sf2
, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2
},
9336 { 0, CODE_FOR_nabsv2sf2
, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2
},
9337 { 0, CODE_FOR_negv2sf2
, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2
},
9338 { 0, CODE_FOR_sqrtv2sf2
, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2
},
9339 { 0, CODE_FOR_resv2sf2
, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2
}
9343 rs6000_expand_unop_builtin (enum insn_code icode
, tree exp
, rtx target
)
9346 tree arg0
= CALL_EXPR_ARG (exp
, 0);
9347 rtx op0
= expand_normal (arg0
);
9348 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
9349 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
9351 if (icode
== CODE_FOR_nothing
)
9352 /* Builtin not supported on this processor. */
9355 /* If we got invalid arguments bail out before generating bad rtl. */
9356 if (arg0
== error_mark_node
)
9359 if (icode
== CODE_FOR_altivec_vspltisb
9360 || icode
== CODE_FOR_altivec_vspltish
9361 || icode
== CODE_FOR_altivec_vspltisw
9362 || icode
== CODE_FOR_spe_evsplatfi
9363 || icode
== CODE_FOR_spe_evsplati
)
9365 /* Only allow 5-bit *signed* literals. */
9366 if (GET_CODE (op0
) != CONST_INT
9367 || INTVAL (op0
) > 15
9368 || INTVAL (op0
) < -16)
9370 error ("argument 1 must be a 5-bit signed literal");
9376 || GET_MODE (target
) != tmode
9377 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
9378 target
= gen_reg_rtx (tmode
);
9380 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
9381 op0
= copy_to_mode_reg (mode0
, op0
);
9383 pat
= GEN_FCN (icode
) (target
, op0
);
9392 altivec_expand_abs_builtin (enum insn_code icode
, tree exp
, rtx target
)
9394 rtx pat
, scratch1
, scratch2
;
9395 tree arg0
= CALL_EXPR_ARG (exp
, 0);
9396 rtx op0
= expand_normal (arg0
);
9397 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
9398 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
9400 /* If we have invalid arguments, bail out before generating bad rtl. */
9401 if (arg0
== error_mark_node
)
9405 || GET_MODE (target
) != tmode
9406 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
9407 target
= gen_reg_rtx (tmode
);
9409 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
9410 op0
= copy_to_mode_reg (mode0
, op0
);
9412 scratch1
= gen_reg_rtx (mode0
);
9413 scratch2
= gen_reg_rtx (mode0
);
9415 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
9424 rs6000_expand_binop_builtin (enum insn_code icode
, tree exp
, rtx target
)
9427 tree arg0
= CALL_EXPR_ARG (exp
, 0);
9428 tree arg1
= CALL_EXPR_ARG (exp
, 1);
9429 rtx op0
= expand_normal (arg0
);
9430 rtx op1
= expand_normal (arg1
);
9431 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
9432 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
9433 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
9435 if (icode
== CODE_FOR_nothing
)
9436 /* Builtin not supported on this processor. */
9439 /* If we got invalid arguments bail out before generating bad rtl. */
9440 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
9443 if (icode
== CODE_FOR_altivec_vcfux
9444 || icode
== CODE_FOR_altivec_vcfsx
9445 || icode
== CODE_FOR_altivec_vctsxs
9446 || icode
== CODE_FOR_altivec_vctuxs
9447 || icode
== CODE_FOR_altivec_vspltb
9448 || icode
== CODE_FOR_altivec_vsplth
9449 || icode
== CODE_FOR_altivec_vspltw
9450 || icode
== CODE_FOR_spe_evaddiw
9451 || icode
== CODE_FOR_spe_evldd
9452 || icode
== CODE_FOR_spe_evldh
9453 || icode
== CODE_FOR_spe_evldw
9454 || icode
== CODE_FOR_spe_evlhhesplat
9455 || icode
== CODE_FOR_spe_evlhhossplat
9456 || icode
== CODE_FOR_spe_evlhhousplat
9457 || icode
== CODE_FOR_spe_evlwhe
9458 || icode
== CODE_FOR_spe_evlwhos
9459 || icode
== CODE_FOR_spe_evlwhou
9460 || icode
== CODE_FOR_spe_evlwhsplat
9461 || icode
== CODE_FOR_spe_evlwwsplat
9462 || icode
== CODE_FOR_spe_evrlwi
9463 || icode
== CODE_FOR_spe_evslwi
9464 || icode
== CODE_FOR_spe_evsrwis
9465 || icode
== CODE_FOR_spe_evsubifw
9466 || icode
== CODE_FOR_spe_evsrwiu
)
9468 /* Only allow 5-bit unsigned literals. */
9470 if (TREE_CODE (arg1
) != INTEGER_CST
9471 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
9473 error ("argument 2 must be a 5-bit unsigned literal");
9479 || GET_MODE (target
) != tmode
9480 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
9481 target
= gen_reg_rtx (tmode
);
9483 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
9484 op0
= copy_to_mode_reg (mode0
, op0
);
9485 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
9486 op1
= copy_to_mode_reg (mode1
, op1
);
9488 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
9497 altivec_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
9500 tree cr6_form
= CALL_EXPR_ARG (exp
, 0);
9501 tree arg0
= CALL_EXPR_ARG (exp
, 1);
9502 tree arg1
= CALL_EXPR_ARG (exp
, 2);
9503 rtx op0
= expand_normal (arg0
);
9504 rtx op1
= expand_normal (arg1
);
9505 enum machine_mode tmode
= SImode
;
9506 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
9507 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
9510 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
9512 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9516 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
9518 gcc_assert (mode0
== mode1
);
9520 /* If we have invalid arguments, bail out before generating bad rtl. */
9521 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
9525 || GET_MODE (target
) != tmode
9526 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
9527 target
= gen_reg_rtx (tmode
);
9529 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
9530 op0
= copy_to_mode_reg (mode0
, op0
);
9531 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
9532 op1
= copy_to_mode_reg (mode1
, op1
);
9534 scratch
= gen_reg_rtx (mode0
);
9536 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
9541 /* The vec_any* and vec_all* predicates use the same opcodes for two
9542 different operations, but the bits in CR6 will be different
9543 depending on what information we want. So we have to play tricks
9544 with CR6 to get the right bits out.
9546 If you think this is disgusting, look at the specs for the
9547 AltiVec predicates. */
9549 switch (cr6_form_int
)
9552 emit_insn (gen_cr6_test_for_zero (target
));
9555 emit_insn (gen_cr6_test_for_zero_reverse (target
));
9558 emit_insn (gen_cr6_test_for_lt (target
));
9561 emit_insn (gen_cr6_test_for_lt_reverse (target
));
9564 error ("argument 1 of __builtin_altivec_predicate is out of range");
9572 paired_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
)
9575 tree arg0
= CALL_EXPR_ARG (exp
, 0);
9576 tree arg1
= CALL_EXPR_ARG (exp
, 1);
9577 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
9578 enum machine_mode mode0
= Pmode
;
9579 enum machine_mode mode1
= Pmode
;
9580 rtx op0
= expand_normal (arg0
);
9581 rtx op1
= expand_normal (arg1
);
9583 if (icode
== CODE_FOR_nothing
)
9584 /* Builtin not supported on this processor. */
9587 /* If we got invalid arguments bail out before generating bad rtl. */
9588 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
9592 || GET_MODE (target
) != tmode
9593 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
9594 target
= gen_reg_rtx (tmode
);
9596 op1
= copy_to_mode_reg (mode1
, op1
);
9598 if (op0
== const0_rtx
)
9600 addr
= gen_rtx_MEM (tmode
, op1
);
9604 op0
= copy_to_mode_reg (mode0
, op0
);
9605 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
9608 pat
= GEN_FCN (icode
) (target
, addr
);
9618 altivec_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
, bool blk
)
9621 tree arg0
= CALL_EXPR_ARG (exp
, 0);
9622 tree arg1
= CALL_EXPR_ARG (exp
, 1);
9623 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
9624 enum machine_mode mode0
= Pmode
;
9625 enum machine_mode mode1
= Pmode
;
9626 rtx op0
= expand_normal (arg0
);
9627 rtx op1
= expand_normal (arg1
);
9629 if (icode
== CODE_FOR_nothing
)
9630 /* Builtin not supported on this processor. */
9633 /* If we got invalid arguments bail out before generating bad rtl. */
9634 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
9638 || GET_MODE (target
) != tmode
9639 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
9640 target
= gen_reg_rtx (tmode
);
9642 op1
= copy_to_mode_reg (mode1
, op1
);
9644 if (op0
== const0_rtx
)
9646 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, op1
);
9650 op0
= copy_to_mode_reg (mode0
, op0
);
9651 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
9654 pat
= GEN_FCN (icode
) (target
, addr
);
9664 spe_expand_stv_builtin (enum insn_code icode
, tree exp
)
9666 tree arg0
= CALL_EXPR_ARG (exp
, 0);
9667 tree arg1
= CALL_EXPR_ARG (exp
, 1);
9668 tree arg2
= CALL_EXPR_ARG (exp
, 2);
9669 rtx op0
= expand_normal (arg0
);
9670 rtx op1
= expand_normal (arg1
);
9671 rtx op2
= expand_normal (arg2
);
9673 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
9674 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
9675 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
9677 /* Invalid arguments. Bail before doing anything stoopid! */
9678 if (arg0
== error_mark_node
9679 || arg1
== error_mark_node
9680 || arg2
== error_mark_node
)
9683 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
9684 op0
= copy_to_mode_reg (mode2
, op0
);
9685 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
9686 op1
= copy_to_mode_reg (mode0
, op1
);
9687 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
9688 op2
= copy_to_mode_reg (mode1
, op2
);
9690 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
9697 paired_expand_stv_builtin (enum insn_code icode
, tree exp
)
9699 tree arg0
= CALL_EXPR_ARG (exp
, 0);
9700 tree arg1
= CALL_EXPR_ARG (exp
, 1);
9701 tree arg2
= CALL_EXPR_ARG (exp
, 2);
9702 rtx op0
= expand_normal (arg0
);
9703 rtx op1
= expand_normal (arg1
);
9704 rtx op2
= expand_normal (arg2
);
9706 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
9707 enum machine_mode mode1
= Pmode
;
9708 enum machine_mode mode2
= Pmode
;
9710 /* Invalid arguments. Bail before doing anything stoopid! */
9711 if (arg0
== error_mark_node
9712 || arg1
== error_mark_node
9713 || arg2
== error_mark_node
)
9716 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
9717 op0
= copy_to_mode_reg (tmode
, op0
);
9719 op2
= copy_to_mode_reg (mode2
, op2
);
9721 if (op1
== const0_rtx
)
9723 addr
= gen_rtx_MEM (tmode
, op2
);
9727 op1
= copy_to_mode_reg (mode1
, op1
);
9728 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
9731 pat
= GEN_FCN (icode
) (addr
, op0
);
9738 altivec_expand_stv_builtin (enum insn_code icode
, tree exp
)
9740 tree arg0
= CALL_EXPR_ARG (exp
, 0);
9741 tree arg1
= CALL_EXPR_ARG (exp
, 1);
9742 tree arg2
= CALL_EXPR_ARG (exp
, 2);
9743 rtx op0
= expand_normal (arg0
);
9744 rtx op1
= expand_normal (arg1
);
9745 rtx op2
= expand_normal (arg2
);
9747 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
9748 enum machine_mode mode1
= Pmode
;
9749 enum machine_mode mode2
= Pmode
;
9751 /* Invalid arguments. Bail before doing anything stoopid! */
9752 if (arg0
== error_mark_node
9753 || arg1
== error_mark_node
9754 || arg2
== error_mark_node
)
9757 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
9758 op0
= copy_to_mode_reg (tmode
, op0
);
9760 op2
= copy_to_mode_reg (mode2
, op2
);
9762 if (op1
== const0_rtx
)
9764 addr
= gen_rtx_MEM (tmode
, op2
);
9768 op1
= copy_to_mode_reg (mode1
, op1
);
9769 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
9772 pat
= GEN_FCN (icode
) (addr
, op0
);
9779 rs6000_expand_ternop_builtin (enum insn_code icode
, tree exp
, rtx target
)
9782 tree arg0
= CALL_EXPR_ARG (exp
, 0);
9783 tree arg1
= CALL_EXPR_ARG (exp
, 1);
9784 tree arg2
= CALL_EXPR_ARG (exp
, 2);
9785 rtx op0
= expand_normal (arg0
);
9786 rtx op1
= expand_normal (arg1
);
9787 rtx op2
= expand_normal (arg2
);
9788 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
9789 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
9790 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
9791 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
9793 if (icode
== CODE_FOR_nothing
)
9794 /* Builtin not supported on this processor. */
9797 /* If we got invalid arguments bail out before generating bad rtl. */
9798 if (arg0
== error_mark_node
9799 || arg1
== error_mark_node
9800 || arg2
== error_mark_node
)
9805 case CODE_FOR_altivec_vsldoi_v4sf
:
9806 case CODE_FOR_altivec_vsldoi_v4si
:
9807 case CODE_FOR_altivec_vsldoi_v8hi
:
9808 case CODE_FOR_altivec_vsldoi_v16qi
:
9809 /* Only allow 4-bit unsigned literals. */
9811 if (TREE_CODE (arg2
) != INTEGER_CST
9812 || TREE_INT_CST_LOW (arg2
) & ~0xf)
9814 error ("argument 3 must be a 4-bit unsigned literal");
9819 case CODE_FOR_vsx_xxpermdi_v2df
:
9820 case CODE_FOR_vsx_xxpermdi_v2di
:
9821 case CODE_FOR_vsx_xxsldwi_v16qi
:
9822 case CODE_FOR_vsx_xxsldwi_v8hi
:
9823 case CODE_FOR_vsx_xxsldwi_v4si
:
9824 case CODE_FOR_vsx_xxsldwi_v4sf
:
9825 case CODE_FOR_vsx_xxsldwi_v2di
:
9826 case CODE_FOR_vsx_xxsldwi_v2df
:
9827 /* Only allow 2-bit unsigned literals. */
9829 if (TREE_CODE (arg2
) != INTEGER_CST
9830 || TREE_INT_CST_LOW (arg2
) & ~0x3)
9832 error ("argument 3 must be a 2-bit unsigned literal");
9837 case CODE_FOR_vsx_set_v2df
:
9838 case CODE_FOR_vsx_set_v2di
:
9839 /* Only allow 1-bit unsigned literals. */
9841 if (TREE_CODE (arg2
) != INTEGER_CST
9842 || TREE_INT_CST_LOW (arg2
) & ~0x1)
9844 error ("argument 3 must be a 1-bit unsigned literal");
9854 || GET_MODE (target
) != tmode
9855 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
9856 target
= gen_reg_rtx (tmode
);
9858 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
9859 op0
= copy_to_mode_reg (mode0
, op0
);
9860 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
9861 op1
= copy_to_mode_reg (mode1
, op1
);
9862 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
9863 op2
= copy_to_mode_reg (mode2
, op2
);
9865 if (TARGET_PAIRED_FLOAT
&& icode
== CODE_FOR_selv2sf4
)
9866 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
, CONST0_RTX (SFmode
));
9868 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
9876 /* Expand the lvx builtins. */
9878 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
9880 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
9881 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
9883 enum machine_mode tmode
, mode0
;
9885 enum insn_code icode
;
9889 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
9890 icode
= CODE_FOR_vector_load_v16qi
;
9892 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
9893 icode
= CODE_FOR_vector_load_v8hi
;
9895 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
9896 icode
= CODE_FOR_vector_load_v4si
;
9898 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
9899 icode
= CODE_FOR_vector_load_v4sf
;
9908 arg0
= CALL_EXPR_ARG (exp
, 0);
9909 op0
= expand_normal (arg0
);
9910 tmode
= insn_data
[icode
].operand
[0].mode
;
9911 mode0
= insn_data
[icode
].operand
[1].mode
;
9914 || GET_MODE (target
) != tmode
9915 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
9916 target
= gen_reg_rtx (tmode
);
9918 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
9919 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
9921 pat
= GEN_FCN (icode
) (target
, op0
);
9928 /* Expand the stvx builtins. */
9930 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
9933 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
9934 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
9936 enum machine_mode mode0
, mode1
;
9938 enum insn_code icode
;
9942 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
9943 icode
= CODE_FOR_vector_store_v16qi
;
9945 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
9946 icode
= CODE_FOR_vector_store_v8hi
;
9948 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
9949 icode
= CODE_FOR_vector_store_v4si
;
9951 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
9952 icode
= CODE_FOR_vector_store_v4sf
;
9959 arg0
= CALL_EXPR_ARG (exp
, 0);
9960 arg1
= CALL_EXPR_ARG (exp
, 1);
9961 op0
= expand_normal (arg0
);
9962 op1
= expand_normal (arg1
);
9963 mode0
= insn_data
[icode
].operand
[0].mode
;
9964 mode1
= insn_data
[icode
].operand
[1].mode
;
9966 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
9967 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
9968 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
9969 op1
= copy_to_mode_reg (mode1
, op1
);
9971 pat
= GEN_FCN (icode
) (op0
, op1
);
9979 /* Expand the dst builtins. */
9981 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
9984 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
9985 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
9986 tree arg0
, arg1
, arg2
;
9987 enum machine_mode mode0
, mode1
, mode2
;
9988 rtx pat
, op0
, op1
, op2
;
9989 const struct builtin_description
*d
;
9994 /* Handle DST variants. */
9996 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
9997 if (d
->code
== fcode
)
9999 arg0
= CALL_EXPR_ARG (exp
, 0);
10000 arg1
= CALL_EXPR_ARG (exp
, 1);
10001 arg2
= CALL_EXPR_ARG (exp
, 2);
10002 op0
= expand_normal (arg0
);
10003 op1
= expand_normal (arg1
);
10004 op2
= expand_normal (arg2
);
10005 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10006 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10007 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
10009 /* Invalid arguments, bail out before generating bad rtl. */
10010 if (arg0
== error_mark_node
10011 || arg1
== error_mark_node
10012 || arg2
== error_mark_node
)
10017 if (TREE_CODE (arg2
) != INTEGER_CST
10018 || TREE_INT_CST_LOW (arg2
) & ~0x3)
10020 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
10024 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
10025 op0
= copy_to_mode_reg (Pmode
, op0
);
10026 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
10027 op1
= copy_to_mode_reg (mode1
, op1
);
10029 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
10039 /* Expand vec_init builtin. */
10041 altivec_expand_vec_init_builtin (tree type
, tree exp
, rtx target
)
10043 enum machine_mode tmode
= TYPE_MODE (type
);
10044 enum machine_mode inner_mode
= GET_MODE_INNER (tmode
);
10045 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
10046 rtvec v
= rtvec_alloc (n_elt
);
10048 gcc_assert (VECTOR_MODE_P (tmode
));
10049 gcc_assert (n_elt
== call_expr_nargs (exp
));
10051 for (i
= 0; i
< n_elt
; ++i
)
10053 rtx x
= expand_normal (CALL_EXPR_ARG (exp
, i
));
10054 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
10057 if (!target
|| !register_operand (target
, tmode
))
10058 target
= gen_reg_rtx (tmode
);
10060 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
10064 /* Return the integer constant in ARG. Constrain it to be in the range
10065 of the subparts of VEC_TYPE; issue an error if not. */
10068 get_element_number (tree vec_type
, tree arg
)
10070 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
10072 if (!host_integerp (arg
, 1)
10073 || (elt
= tree_low_cst (arg
, 1), elt
> max
))
10075 error ("selector must be an integer constant in the range 0..%wi", max
);
10082 /* Expand vec_set builtin. */
10084 altivec_expand_vec_set_builtin (tree exp
)
10086 enum machine_mode tmode
, mode1
;
10087 tree arg0
, arg1
, arg2
;
10091 arg0
= CALL_EXPR_ARG (exp
, 0);
10092 arg1
= CALL_EXPR_ARG (exp
, 1);
10093 arg2
= CALL_EXPR_ARG (exp
, 2);
10095 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
10096 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
10097 gcc_assert (VECTOR_MODE_P (tmode
));
10099 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, EXPAND_NORMAL
);
10100 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, EXPAND_NORMAL
);
10101 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
10103 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
10104 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
10106 op0
= force_reg (tmode
, op0
);
10107 op1
= force_reg (mode1
, op1
);
10109 rs6000_expand_vector_set (op0
, op1
, elt
);
10114 /* Expand vec_ext builtin. */
10116 altivec_expand_vec_ext_builtin (tree exp
, rtx target
)
10118 enum machine_mode tmode
, mode0
;
10123 arg0
= CALL_EXPR_ARG (exp
, 0);
10124 arg1
= CALL_EXPR_ARG (exp
, 1);
10126 op0
= expand_normal (arg0
);
10127 elt
= get_element_number (TREE_TYPE (arg0
), arg1
);
10129 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
10130 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
10131 gcc_assert (VECTOR_MODE_P (mode0
));
10133 op0
= force_reg (mode0
, op0
);
10135 if (optimize
|| !target
|| !register_operand (target
, tmode
))
10136 target
= gen_reg_rtx (tmode
);
10138 rs6000_expand_vector_extract (target
, op0
, elt
);
10143 /* Expand the builtin in EXP and store the result in TARGET. Store
10144 true in *EXPANDEDP if we found a builtin to expand. */
10146 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
10148 const struct builtin_description
*d
;
10149 const struct builtin_description_predicates
*dp
;
10151 enum insn_code icode
;
10152 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
10155 enum machine_mode tmode
, mode0
;
10156 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
10158 if ((fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10159 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
10160 || (fcode
>= VSX_BUILTIN_OVERLOADED_FIRST
10161 && fcode
<= VSX_BUILTIN_OVERLOADED_LAST
))
10164 error ("unresolved overload for Altivec builtin %qF", fndecl
);
10168 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
10172 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
10176 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
10184 case ALTIVEC_BUILTIN_STVX
:
10185 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx
, exp
);
10186 case ALTIVEC_BUILTIN_STVEBX
:
10187 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, exp
);
10188 case ALTIVEC_BUILTIN_STVEHX
:
10189 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, exp
);
10190 case ALTIVEC_BUILTIN_STVEWX
:
10191 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, exp
);
10192 case ALTIVEC_BUILTIN_STVXL
:
10193 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, exp
);
10195 case ALTIVEC_BUILTIN_STVLX
:
10196 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx
, exp
);
10197 case ALTIVEC_BUILTIN_STVLXL
:
10198 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl
, exp
);
10199 case ALTIVEC_BUILTIN_STVRX
:
10200 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx
, exp
);
10201 case ALTIVEC_BUILTIN_STVRXL
:
10202 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl
, exp
);
10204 case ALTIVEC_BUILTIN_MFVSCR
:
10205 icode
= CODE_FOR_altivec_mfvscr
;
10206 tmode
= insn_data
[icode
].operand
[0].mode
;
10209 || GET_MODE (target
) != tmode
10210 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10211 target
= gen_reg_rtx (tmode
);
10213 pat
= GEN_FCN (icode
) (target
);
10219 case ALTIVEC_BUILTIN_MTVSCR
:
10220 icode
= CODE_FOR_altivec_mtvscr
;
10221 arg0
= CALL_EXPR_ARG (exp
, 0);
10222 op0
= expand_normal (arg0
);
10223 mode0
= insn_data
[icode
].operand
[0].mode
;
10225 /* If we got invalid arguments bail out before generating bad rtl. */
10226 if (arg0
== error_mark_node
)
10229 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
10230 op0
= copy_to_mode_reg (mode0
, op0
);
10232 pat
= GEN_FCN (icode
) (op0
);
10237 case ALTIVEC_BUILTIN_DSSALL
:
10238 emit_insn (gen_altivec_dssall ());
10241 case ALTIVEC_BUILTIN_DSS
:
10242 icode
= CODE_FOR_altivec_dss
;
10243 arg0
= CALL_EXPR_ARG (exp
, 0);
10245 op0
= expand_normal (arg0
);
10246 mode0
= insn_data
[icode
].operand
[0].mode
;
10248 /* If we got invalid arguments bail out before generating bad rtl. */
10249 if (arg0
== error_mark_node
)
10252 if (TREE_CODE (arg0
) != INTEGER_CST
10253 || TREE_INT_CST_LOW (arg0
) & ~0x3)
10255 error ("argument to dss must be a 2-bit unsigned literal");
10259 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
10260 op0
= copy_to_mode_reg (mode0
, op0
);
10262 emit_insn (gen_altivec_dss (op0
));
10265 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
10266 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
10267 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
10268 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
10269 case VSX_BUILTIN_VEC_INIT_V2DF
:
10270 case VSX_BUILTIN_VEC_INIT_V2DI
:
10271 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), exp
, target
);
10273 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
10274 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
10275 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
10276 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
10277 case VSX_BUILTIN_VEC_SET_V2DF
:
10278 case VSX_BUILTIN_VEC_SET_V2DI
:
10279 return altivec_expand_vec_set_builtin (exp
);
10281 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
10282 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
10283 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
10284 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
10285 case VSX_BUILTIN_VEC_EXT_V2DF
:
10286 case VSX_BUILTIN_VEC_EXT_V2DI
:
10287 return altivec_expand_vec_ext_builtin (exp
, target
);
10291 /* Fall through. */
10294 /* Expand abs* operations. */
10296 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
10297 if (d
->code
== fcode
)
10298 return altivec_expand_abs_builtin (d
->icode
, exp
, target
);
10300 /* Expand the AltiVec predicates. */
10301 dp
= bdesc_altivec_preds
;
10302 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
10303 if (dp
->code
== fcode
)
10304 return altivec_expand_predicate_builtin (dp
->icode
, exp
, target
);
10306 /* LV* are funky. We initialized them differently. */
10309 case ALTIVEC_BUILTIN_LVSL
:
10310 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
10311 exp
, target
, false);
10312 case ALTIVEC_BUILTIN_LVSR
:
10313 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
10314 exp
, target
, false);
10315 case ALTIVEC_BUILTIN_LVEBX
:
10316 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
10317 exp
, target
, false);
10318 case ALTIVEC_BUILTIN_LVEHX
:
10319 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
10320 exp
, target
, false);
10321 case ALTIVEC_BUILTIN_LVEWX
:
10322 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
10323 exp
, target
, false);
10324 case ALTIVEC_BUILTIN_LVXL
:
10325 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
10326 exp
, target
, false);
10327 case ALTIVEC_BUILTIN_LVX
:
10328 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx
,
10329 exp
, target
, false);
10330 case ALTIVEC_BUILTIN_LVLX
:
10331 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx
,
10332 exp
, target
, true);
10333 case ALTIVEC_BUILTIN_LVLXL
:
10334 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl
,
10335 exp
, target
, true);
10336 case ALTIVEC_BUILTIN_LVRX
:
10337 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx
,
10338 exp
, target
, true);
10339 case ALTIVEC_BUILTIN_LVRXL
:
10340 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl
,
10341 exp
, target
, true);
10344 /* Fall through. */
10347 *expandedp
= false;
10351 /* Expand the builtin in EXP and store the result in TARGET. Store
10352 true in *EXPANDEDP if we found a builtin to expand. */
10354 paired_expand_builtin (tree exp
, rtx target
, bool * expandedp
)
10356 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
10357 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
10358 const struct builtin_description
*d
;
10365 case PAIRED_BUILTIN_STX
:
10366 return paired_expand_stv_builtin (CODE_FOR_paired_stx
, exp
);
10367 case PAIRED_BUILTIN_LX
:
10368 return paired_expand_lv_builtin (CODE_FOR_paired_lx
, exp
, target
);
10371 /* Fall through. */
10374 /* Expand the paired predicates. */
10375 d
= bdesc_paired_preds
;
10376 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); i
++, d
++)
10377 if (d
->code
== fcode
)
10378 return paired_expand_predicate_builtin (d
->icode
, exp
, target
);
10380 *expandedp
= false;
10384 /* Binops that need to be initialized manually, but can be expanded
10385 automagically by rs6000_expand_binop_builtin. */
10386 static struct builtin_description bdesc_2arg_spe
[] =
10388 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
10389 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
10390 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
10391 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
10392 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
10393 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
10394 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
10395 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
10396 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
10397 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
10398 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
10399 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
10400 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
10401 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
10402 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
10403 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
10404 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
10405 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
10406 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
10407 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
10408 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
10409 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
10412 /* Expand the builtin in EXP and store the result in TARGET. Store
10413 true in *EXPANDEDP if we found a builtin to expand.
10415 This expands the SPE builtins that are not simple unary and binary
10418 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
10420 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
10422 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
10423 enum insn_code icode
;
10424 enum machine_mode tmode
, mode0
;
10426 struct builtin_description
*d
;
10431 /* Syntax check for a 5-bit unsigned immediate. */
10434 case SPE_BUILTIN_EVSTDD
:
10435 case SPE_BUILTIN_EVSTDH
:
10436 case SPE_BUILTIN_EVSTDW
:
10437 case SPE_BUILTIN_EVSTWHE
:
10438 case SPE_BUILTIN_EVSTWHO
:
10439 case SPE_BUILTIN_EVSTWWE
:
10440 case SPE_BUILTIN_EVSTWWO
:
10441 arg1
= CALL_EXPR_ARG (exp
, 2);
10442 if (TREE_CODE (arg1
) != INTEGER_CST
10443 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
10445 error ("argument 2 must be a 5-bit unsigned literal");
10453 /* The evsplat*i instructions are not quite generic. */
10456 case SPE_BUILTIN_EVSPLATFI
:
10457 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
10459 case SPE_BUILTIN_EVSPLATI
:
10460 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
10466 d
= (struct builtin_description
*) bdesc_2arg_spe
;
10467 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
10468 if (d
->code
== fcode
)
10469 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
10471 d
= (struct builtin_description
*) bdesc_spe_predicates
;
10472 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
10473 if (d
->code
== fcode
)
10474 return spe_expand_predicate_builtin (d
->icode
, exp
, target
);
10476 d
= (struct builtin_description
*) bdesc_spe_evsel
;
10477 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
10478 if (d
->code
== fcode
)
10479 return spe_expand_evsel_builtin (d
->icode
, exp
, target
);
10483 case SPE_BUILTIN_EVSTDDX
:
10484 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, exp
);
10485 case SPE_BUILTIN_EVSTDHX
:
10486 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, exp
);
10487 case SPE_BUILTIN_EVSTDWX
:
10488 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, exp
);
10489 case SPE_BUILTIN_EVSTWHEX
:
10490 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, exp
);
10491 case SPE_BUILTIN_EVSTWHOX
:
10492 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, exp
);
10493 case SPE_BUILTIN_EVSTWWEX
:
10494 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, exp
);
10495 case SPE_BUILTIN_EVSTWWOX
:
10496 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, exp
);
10497 case SPE_BUILTIN_EVSTDD
:
10498 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, exp
);
10499 case SPE_BUILTIN_EVSTDH
:
10500 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, exp
);
10501 case SPE_BUILTIN_EVSTDW
:
10502 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, exp
);
10503 case SPE_BUILTIN_EVSTWHE
:
10504 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, exp
);
10505 case SPE_BUILTIN_EVSTWHO
:
10506 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, exp
);
10507 case SPE_BUILTIN_EVSTWWE
:
10508 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, exp
);
10509 case SPE_BUILTIN_EVSTWWO
:
10510 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, exp
);
10511 case SPE_BUILTIN_MFSPEFSCR
:
10512 icode
= CODE_FOR_spe_mfspefscr
;
10513 tmode
= insn_data
[icode
].operand
[0].mode
;
10516 || GET_MODE (target
) != tmode
10517 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10518 target
= gen_reg_rtx (tmode
);
10520 pat
= GEN_FCN (icode
) (target
);
10525 case SPE_BUILTIN_MTSPEFSCR
:
10526 icode
= CODE_FOR_spe_mtspefscr
;
10527 arg0
= CALL_EXPR_ARG (exp
, 0);
10528 op0
= expand_normal (arg0
);
10529 mode0
= insn_data
[icode
].operand
[0].mode
;
10531 if (arg0
== error_mark_node
)
10534 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
10535 op0
= copy_to_mode_reg (mode0
, op0
);
10537 pat
= GEN_FCN (icode
) (op0
);
10545 *expandedp
= false;
10550 paired_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
10552 rtx pat
, scratch
, tmp
;
10553 tree form
= CALL_EXPR_ARG (exp
, 0);
10554 tree arg0
= CALL_EXPR_ARG (exp
, 1);
10555 tree arg1
= CALL_EXPR_ARG (exp
, 2);
10556 rtx op0
= expand_normal (arg0
);
10557 rtx op1
= expand_normal (arg1
);
10558 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10559 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
10561 enum rtx_code code
;
10563 if (TREE_CODE (form
) != INTEGER_CST
)
10565 error ("argument 1 of __builtin_paired_predicate must be a constant");
10569 form_int
= TREE_INT_CST_LOW (form
);
10571 gcc_assert (mode0
== mode1
);
10573 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10577 || GET_MODE (target
) != SImode
10578 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
10579 target
= gen_reg_rtx (SImode
);
10580 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10581 op0
= copy_to_mode_reg (mode0
, op0
);
10582 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10583 op1
= copy_to_mode_reg (mode1
, op1
);
10585 scratch
= gen_reg_rtx (CCFPmode
);
10587 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
10609 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
10612 error ("argument 1 of __builtin_paired_predicate is out of range");
10616 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
10617 emit_move_insn (target
, tmp
);
10622 spe_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
10624 rtx pat
, scratch
, tmp
;
10625 tree form
= CALL_EXPR_ARG (exp
, 0);
10626 tree arg0
= CALL_EXPR_ARG (exp
, 1);
10627 tree arg1
= CALL_EXPR_ARG (exp
, 2);
10628 rtx op0
= expand_normal (arg0
);
10629 rtx op1
= expand_normal (arg1
);
10630 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10631 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
10633 enum rtx_code code
;
10635 if (TREE_CODE (form
) != INTEGER_CST
)
10637 error ("argument 1 of __builtin_spe_predicate must be a constant");
10641 form_int
= TREE_INT_CST_LOW (form
);
10643 gcc_assert (mode0
== mode1
);
10645 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
10649 || GET_MODE (target
) != SImode
10650 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
10651 target
= gen_reg_rtx (SImode
);
10653 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10654 op0
= copy_to_mode_reg (mode0
, op0
);
10655 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
10656 op1
= copy_to_mode_reg (mode1
, op1
);
10658 scratch
= gen_reg_rtx (CCmode
);
10660 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
10665 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
10666 _lower_. We use one compare, but look in different bits of the
10667 CR for each variant.
10669 There are 2 elements in each SPE simd type (upper/lower). The CR
10670 bits are set as follows:
10672 BIT0 | BIT 1 | BIT 2 | BIT 3
10673 U | L | (U | L) | (U & L)
10675 So, for an "all" relationship, BIT 3 would be set.
10676 For an "any" relationship, BIT 2 would be set. Etc.
10678 Following traditional nomenclature, these bits map to:
10680 BIT0 | BIT 1 | BIT 2 | BIT 3
10683 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
10688 /* All variant. OV bit. */
10690 /* We need to get to the OV bit, which is the ORDERED bit. We
10691 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
10692 that's ugly and will make validate_condition_mode die.
10693 So let's just use another pattern. */
10694 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
10696 /* Any variant. EQ bit. */
10700 /* Upper variant. LT bit. */
10704 /* Lower variant. GT bit. */
10709 error ("argument 1 of __builtin_spe_predicate is out of range");
10713 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
10714 emit_move_insn (target
, tmp
);
10719 /* The evsel builtins look like this:
10721 e = __builtin_spe_evsel_OP (a, b, c, d);
10723 and work like this:
10725 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
10726 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
10730 spe_expand_evsel_builtin (enum insn_code icode
, tree exp
, rtx target
)
10733 tree arg0
= CALL_EXPR_ARG (exp
, 0);
10734 tree arg1
= CALL_EXPR_ARG (exp
, 1);
10735 tree arg2
= CALL_EXPR_ARG (exp
, 2);
10736 tree arg3
= CALL_EXPR_ARG (exp
, 3);
10737 rtx op0
= expand_normal (arg0
);
10738 rtx op1
= expand_normal (arg1
);
10739 rtx op2
= expand_normal (arg2
);
10740 rtx op3
= expand_normal (arg3
);
10741 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
10742 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
10744 gcc_assert (mode0
== mode1
);
10746 if (arg0
== error_mark_node
|| arg1
== error_mark_node
10747 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
10751 || GET_MODE (target
) != mode0
10752 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
10753 target
= gen_reg_rtx (mode0
);
10755 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
10756 op0
= copy_to_mode_reg (mode0
, op0
);
10757 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
10758 op1
= copy_to_mode_reg (mode0
, op1
);
10759 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
10760 op2
= copy_to_mode_reg (mode0
, op2
);
10761 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
10762 op3
= copy_to_mode_reg (mode0
, op3
);
10764 /* Generate the compare. */
10765 scratch
= gen_reg_rtx (CCmode
);
10766 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
10771 if (mode0
== V2SImode
)
10772 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
10774 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
10779 /* Expand an expression EXP that calls a built-in function,
10780 with result going to TARGET if that's convenient
10781 (and in mode MODE if that's convenient).
10782 SUBTARGET may be used as the target for computing one of EXP's operands.
10783 IGNORE is nonzero if the value is to be ignored. */
10786 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
10787 enum machine_mode mode ATTRIBUTE_UNUSED
,
10788 int ignore ATTRIBUTE_UNUSED
)
10790 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
10791 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
10792 const struct builtin_description
*d
;
10797 if (fcode
== RS6000_BUILTIN_RECIP
)
10798 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3
, exp
, target
);
10800 if (fcode
== RS6000_BUILTIN_RECIPF
)
10801 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3
, exp
, target
);
10803 if (fcode
== RS6000_BUILTIN_RSQRTF
)
10804 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2
, exp
, target
);
10806 if (fcode
== RS6000_BUILTIN_BSWAP_HI
)
10807 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2
, exp
, target
);
10809 if (fcode
== POWER7_BUILTIN_BPERMD
)
10810 return rs6000_expand_binop_builtin (((TARGET_64BIT
)
10811 ? CODE_FOR_bpermd_di
10812 : CODE_FOR_bpermd_si
), exp
, target
);
10814 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_LOAD
10815 || fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
10817 int icode
= (int) CODE_FOR_altivec_lvsr
;
10818 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
10819 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
10823 gcc_assert (TARGET_ALTIVEC
);
10825 arg
= CALL_EXPR_ARG (exp
, 0);
10826 gcc_assert (TREE_CODE (TREE_TYPE (arg
)) == POINTER_TYPE
);
10827 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
10828 addr
= memory_address (mode
, op
);
10829 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
10833 /* For the load case need to negate the address. */
10834 op
= gen_reg_rtx (GET_MODE (addr
));
10835 emit_insn (gen_rtx_SET (VOIDmode
, op
,
10836 gen_rtx_NEG (GET_MODE (addr
), addr
)));
10838 op
= gen_rtx_MEM (mode
, op
);
10841 || GET_MODE (target
) != tmode
10842 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
10843 target
= gen_reg_rtx (tmode
);
10845 /*pat = gen_altivec_lvsr (target, op);*/
10846 pat
= GEN_FCN (icode
) (target
, op
);
10854 /* FIXME: There's got to be a nicer way to handle this case than
10855 constructing a new CALL_EXPR. */
10856 if (fcode
== ALTIVEC_BUILTIN_VCFUX
10857 || fcode
== ALTIVEC_BUILTIN_VCFSX
10858 || fcode
== ALTIVEC_BUILTIN_VCTUXS
10859 || fcode
== ALTIVEC_BUILTIN_VCTSXS
)
10861 if (call_expr_nargs (exp
) == 1)
10862 exp
= build_call_nary (TREE_TYPE (exp
), CALL_EXPR_FN (exp
),
10863 2, CALL_EXPR_ARG (exp
, 0), integer_zero_node
);
10866 if (TARGET_ALTIVEC
)
10868 ret
= altivec_expand_builtin (exp
, target
, &success
);
10875 ret
= spe_expand_builtin (exp
, target
, &success
);
10880 if (TARGET_PAIRED_FLOAT
)
10882 ret
= paired_expand_builtin (exp
, target
, &success
);
10888 gcc_assert (TARGET_ALTIVEC
|| TARGET_VSX
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
);
10890 /* Handle simple unary operations. */
10891 d
= (struct builtin_description
*) bdesc_1arg
;
10892 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
10893 if (d
->code
== fcode
)
10894 return rs6000_expand_unop_builtin (d
->icode
, exp
, target
);
10896 /* Handle simple binary operations. */
10897 d
= (struct builtin_description
*) bdesc_2arg
;
10898 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
10899 if (d
->code
== fcode
)
10900 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
10902 /* Handle simple ternary operations. */
10904 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
10905 if (d
->code
== fcode
)
10906 return rs6000_expand_ternop_builtin (d
->icode
, exp
, target
);
10908 gcc_unreachable ();
10912 rs6000_init_builtins (void)
10916 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
10917 V2SF_type_node
= build_vector_type (float_type_node
, 2);
10918 V2DI_type_node
= build_vector_type (intDI_type_node
, 2);
10919 V2DF_type_node
= build_vector_type (double_type_node
, 2);
10920 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
10921 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
10922 V4SF_type_node
= build_vector_type (float_type_node
, 4);
10923 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
10924 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
10926 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
10927 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
10928 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
10929 unsigned_V2DI_type_node
= build_vector_type (unsigned_intDI_type_node
, 2);
10931 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
10932 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
10933 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
10934 opaque_V4SI_type_node
= build_opaque_vector_type (intSI_type_node
, 4);
10936 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
10937 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
10938 'vector unsigned short'. */
10940 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
10941 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
10942 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
10943 bool_long_type_node
= build_distinct_type_copy (unsigned_intDI_type_node
);
10944 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
10946 long_integer_type_internal_node
= long_integer_type_node
;
10947 long_unsigned_type_internal_node
= long_unsigned_type_node
;
10948 intQI_type_internal_node
= intQI_type_node
;
10949 uintQI_type_internal_node
= unsigned_intQI_type_node
;
10950 intHI_type_internal_node
= intHI_type_node
;
10951 uintHI_type_internal_node
= unsigned_intHI_type_node
;
10952 intSI_type_internal_node
= intSI_type_node
;
10953 uintSI_type_internal_node
= unsigned_intSI_type_node
;
10954 intDI_type_internal_node
= intDI_type_node
;
10955 uintDI_type_internal_node
= unsigned_intDI_type_node
;
10956 float_type_internal_node
= float_type_node
;
10957 double_type_internal_node
= float_type_node
;
10958 void_type_internal_node
= void_type_node
;
10960 /* Initialize the modes for builtin_function_type, mapping a machine mode to
10962 builtin_mode_to_type
[QImode
][0] = integer_type_node
;
10963 builtin_mode_to_type
[HImode
][0] = integer_type_node
;
10964 builtin_mode_to_type
[SImode
][0] = intSI_type_node
;
10965 builtin_mode_to_type
[SImode
][1] = unsigned_intSI_type_node
;
10966 builtin_mode_to_type
[DImode
][0] = intDI_type_node
;
10967 builtin_mode_to_type
[DImode
][1] = unsigned_intDI_type_node
;
10968 builtin_mode_to_type
[SFmode
][0] = float_type_node
;
10969 builtin_mode_to_type
[DFmode
][0] = double_type_node
;
10970 builtin_mode_to_type
[V2SImode
][0] = V2SI_type_node
;
10971 builtin_mode_to_type
[V2SFmode
][0] = V2SF_type_node
;
10972 builtin_mode_to_type
[V2DImode
][0] = V2DI_type_node
;
10973 builtin_mode_to_type
[V2DImode
][1] = unsigned_V2DI_type_node
;
10974 builtin_mode_to_type
[V2DFmode
][0] = V2DF_type_node
;
10975 builtin_mode_to_type
[V4HImode
][0] = V4HI_type_node
;
10976 builtin_mode_to_type
[V4SImode
][0] = V4SI_type_node
;
10977 builtin_mode_to_type
[V4SImode
][1] = unsigned_V4SI_type_node
;
10978 builtin_mode_to_type
[V4SFmode
][0] = V4SF_type_node
;
10979 builtin_mode_to_type
[V8HImode
][0] = V8HI_type_node
;
10980 builtin_mode_to_type
[V8HImode
][1] = unsigned_V8HI_type_node
;
10981 builtin_mode_to_type
[V16QImode
][0] = V16QI_type_node
;
10982 builtin_mode_to_type
[V16QImode
][1] = unsigned_V16QI_type_node
;
10984 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
10985 get_identifier ("__bool char"),
10986 bool_char_type_node
);
10987 TYPE_NAME (bool_char_type_node
) = tdecl
;
10988 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
10989 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
10990 get_identifier ("__bool short"),
10991 bool_short_type_node
);
10992 TYPE_NAME (bool_short_type_node
) = tdecl
;
10993 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
10994 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
10995 get_identifier ("__bool int"),
10996 bool_int_type_node
);
10997 TYPE_NAME (bool_int_type_node
) = tdecl
;
10998 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
10999 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
, get_identifier ("__pixel"),
11001 TYPE_NAME (pixel_type_node
) = tdecl
;
11002 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11004 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
11005 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
11006 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
11007 bool_V2DI_type_node
= build_vector_type (bool_long_type_node
, 2);
11008 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
11010 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
11011 get_identifier ("__vector unsigned char"),
11012 unsigned_V16QI_type_node
);
11013 TYPE_NAME (unsigned_V16QI_type_node
) = tdecl
;
11014 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11015 tdecl
= build_decl (BUILTINS_LOCATION
,
11016 TYPE_DECL
, get_identifier ("__vector signed char"),
11018 TYPE_NAME (V16QI_type_node
) = tdecl
;
11019 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11020 tdecl
= build_decl (BUILTINS_LOCATION
,
11021 TYPE_DECL
, get_identifier ("__vector __bool char"),
11022 bool_V16QI_type_node
);
11023 TYPE_NAME ( bool_V16QI_type_node
) = tdecl
;
11024 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11026 tdecl
= build_decl (BUILTINS_LOCATION
,
11027 TYPE_DECL
, get_identifier ("__vector unsigned short"),
11028 unsigned_V8HI_type_node
);
11029 TYPE_NAME (unsigned_V8HI_type_node
) = tdecl
;
11030 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11031 tdecl
= build_decl (BUILTINS_LOCATION
,
11032 TYPE_DECL
, get_identifier ("__vector signed short"),
11034 TYPE_NAME (V8HI_type_node
) = tdecl
;
11035 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11036 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
11037 get_identifier ("__vector __bool short"),
11038 bool_V8HI_type_node
);
11039 TYPE_NAME (bool_V8HI_type_node
) = tdecl
;
11040 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11042 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
11043 get_identifier ("__vector unsigned int"),
11044 unsigned_V4SI_type_node
);
11045 TYPE_NAME (unsigned_V4SI_type_node
) = tdecl
;
11046 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11047 tdecl
= build_decl (BUILTINS_LOCATION
,
11048 TYPE_DECL
, get_identifier ("__vector signed int"),
11050 TYPE_NAME (V4SI_type_node
) = tdecl
;
11051 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11052 tdecl
= build_decl (BUILTINS_LOCATION
,
11053 TYPE_DECL
, get_identifier ("__vector __bool int"),
11054 bool_V4SI_type_node
);
11055 TYPE_NAME (bool_V4SI_type_node
) = tdecl
;
11056 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11058 tdecl
= build_decl (BUILTINS_LOCATION
,
11059 TYPE_DECL
, get_identifier ("__vector float"),
11061 TYPE_NAME (V4SF_type_node
) = tdecl
;
11062 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11063 tdecl
= build_decl (BUILTINS_LOCATION
,
11064 TYPE_DECL
, get_identifier ("__vector __pixel"),
11065 pixel_V8HI_type_node
);
11066 TYPE_NAME (pixel_V8HI_type_node
) = tdecl
;
11067 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11071 tdecl
= build_decl (BUILTINS_LOCATION
,
11072 TYPE_DECL
, get_identifier ("__vector double"),
11074 TYPE_NAME (V2DF_type_node
) = tdecl
;
11075 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11077 tdecl
= build_decl (BUILTINS_LOCATION
,
11078 TYPE_DECL
, get_identifier ("__vector long"),
11080 TYPE_NAME (V2DI_type_node
) = tdecl
;
11081 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11083 tdecl
= build_decl (BUILTINS_LOCATION
,
11084 TYPE_DECL
, get_identifier ("__vector unsigned long"),
11085 unsigned_V2DI_type_node
);
11086 TYPE_NAME (unsigned_V2DI_type_node
) = tdecl
;
11087 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11089 tdecl
= build_decl (BUILTINS_LOCATION
,
11090 TYPE_DECL
, get_identifier ("__vector __bool long"),
11091 bool_V2DI_type_node
);
11092 TYPE_NAME (bool_V2DI_type_node
) = tdecl
;
11093 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
11096 if (TARGET_PAIRED_FLOAT
)
11097 paired_init_builtins ();
11099 spe_init_builtins ();
11100 if (TARGET_ALTIVEC
)
11101 altivec_init_builtins ();
11102 if (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
|| TARGET_VSX
)
11103 rs6000_common_init_builtins ();
11104 if (TARGET_PPC_GFXOPT
)
11106 tree ftype
= builtin_function_type (SFmode
, SFmode
, SFmode
, VOIDmode
,
11107 RS6000_BUILTIN_RECIPF
,
11108 "__builtin_recipdivf");
11109 def_builtin (MASK_PPC_GFXOPT
, "__builtin_recipdivf", ftype
,
11110 RS6000_BUILTIN_RECIPF
);
11112 ftype
= builtin_function_type (SFmode
, SFmode
, VOIDmode
, VOIDmode
,
11113 RS6000_BUILTIN_RSQRTF
,
11114 "__builtin_rsqrtf");
11115 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrtf", ftype
,
11116 RS6000_BUILTIN_RSQRTF
);
11118 if (TARGET_POPCNTB
)
11120 tree ftype
= builtin_function_type (DFmode
, DFmode
, DFmode
, VOIDmode
,
11121 RS6000_BUILTIN_RECIP
,
11122 "__builtin_recipdiv");
11123 def_builtin (MASK_POPCNTB
, "__builtin_recipdiv", ftype
,
11124 RS6000_BUILTIN_RECIP
);
11127 if (TARGET_POPCNTD
)
11129 enum machine_mode mode
= (TARGET_64BIT
) ? DImode
: SImode
;
11130 tree ftype
= builtin_function_type (mode
, mode
, mode
, VOIDmode
,
11131 POWER7_BUILTIN_BPERMD
,
11132 "__builtin_bpermd");
11133 def_builtin (MASK_POPCNTD
, "__builtin_bpermd", ftype
,
11134 POWER7_BUILTIN_BPERMD
);
11136 if (TARGET_POWERPC
)
11138 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11139 tree ftype
= build_function_type_list (unsigned_intHI_type_node
,
11140 unsigned_intHI_type_node
,
11142 def_builtin (MASK_POWERPC
, "__builtin_bswap16", ftype
,
11143 RS6000_BUILTIN_BSWAP_HI
);
11147 /* AIX libm provides clog as __clog. */
11148 if (built_in_decls
[BUILT_IN_CLOG
])
11149 set_user_assembler_name (built_in_decls
[BUILT_IN_CLOG
], "__clog");
11152 #ifdef SUBTARGET_INIT_BUILTINS
11153 SUBTARGET_INIT_BUILTINS
;
11157 /* Search through a set of builtins and enable the mask bits.
11158 DESC is an array of builtins.
11159 SIZE is the total number of builtins.
11160 START is the builtin enum at which to start.
11161 END is the builtin enum at which to end. */
11163 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
11164 enum rs6000_builtins start
,
11165 enum rs6000_builtins end
)
11169 for (i
= 0; i
< size
; ++i
)
11170 if (desc
[i
].code
== start
)
11176 for (; i
< size
; ++i
)
11178 /* Flip all the bits on. */
11179 desc
[i
].mask
= target_flags
;
11180 if (desc
[i
].code
== end
)
11186 spe_init_builtins (void)
11188 tree endlink
= void_list_node
;
11189 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
11190 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
11191 struct builtin_description
*d
;
11194 tree v2si_ftype_4_v2si
11195 = build_function_type
11196 (opaque_V2SI_type_node
,
11197 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
11198 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
11199 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
11200 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
11203 tree v2sf_ftype_4_v2sf
11204 = build_function_type
11205 (opaque_V2SF_type_node
,
11206 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
11207 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
11208 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
11209 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
11212 tree int_ftype_int_v2si_v2si
11213 = build_function_type
11214 (integer_type_node
,
11215 tree_cons (NULL_TREE
, integer_type_node
,
11216 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
11217 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
11220 tree int_ftype_int_v2sf_v2sf
11221 = build_function_type
11222 (integer_type_node
,
11223 tree_cons (NULL_TREE
, integer_type_node
,
11224 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
11225 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
11228 tree void_ftype_v2si_puint_int
11229 = build_function_type (void_type_node
,
11230 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
11231 tree_cons (NULL_TREE
, puint_type_node
,
11232 tree_cons (NULL_TREE
,
11236 tree void_ftype_v2si_puint_char
11237 = build_function_type (void_type_node
,
11238 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
11239 tree_cons (NULL_TREE
, puint_type_node
,
11240 tree_cons (NULL_TREE
,
11244 tree void_ftype_v2si_pv2si_int
11245 = build_function_type (void_type_node
,
11246 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
11247 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
11248 tree_cons (NULL_TREE
,
11252 tree void_ftype_v2si_pv2si_char
11253 = build_function_type (void_type_node
,
11254 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
11255 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
11256 tree_cons (NULL_TREE
,
11260 tree void_ftype_int
11261 = build_function_type (void_type_node
,
11262 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
11264 tree int_ftype_void
11265 = build_function_type (integer_type_node
, endlink
);
11267 tree v2si_ftype_pv2si_int
11268 = build_function_type (opaque_V2SI_type_node
,
11269 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
11270 tree_cons (NULL_TREE
, integer_type_node
,
11273 tree v2si_ftype_puint_int
11274 = build_function_type (opaque_V2SI_type_node
,
11275 tree_cons (NULL_TREE
, puint_type_node
,
11276 tree_cons (NULL_TREE
, integer_type_node
,
11279 tree v2si_ftype_pushort_int
11280 = build_function_type (opaque_V2SI_type_node
,
11281 tree_cons (NULL_TREE
, pushort_type_node
,
11282 tree_cons (NULL_TREE
, integer_type_node
,
11285 tree v2si_ftype_signed_char
11286 = build_function_type (opaque_V2SI_type_node
,
11287 tree_cons (NULL_TREE
, signed_char_type_node
,
11290 /* The initialization of the simple binary and unary builtins is
11291 done in rs6000_common_init_builtins, but we have to enable the
11292 mask bits here manually because we have run out of `target_flags'
11293 bits. We really need to redesign this mask business. */
11295 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
11296 ARRAY_SIZE (bdesc_2arg
),
11297 SPE_BUILTIN_EVADDW
,
11298 SPE_BUILTIN_EVXOR
);
11299 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
11300 ARRAY_SIZE (bdesc_1arg
),
11302 SPE_BUILTIN_EVSUBFUSIAAW
);
11303 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
11304 ARRAY_SIZE (bdesc_spe_predicates
),
11305 SPE_BUILTIN_EVCMPEQ
,
11306 SPE_BUILTIN_EVFSTSTLT
);
11307 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
11308 ARRAY_SIZE (bdesc_spe_evsel
),
11309 SPE_BUILTIN_EVSEL_CMPGTS
,
11310 SPE_BUILTIN_EVSEL_FSTSTEQ
);
11312 (*lang_hooks
.decls
.pushdecl
)
11313 (build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
11314 get_identifier ("__ev64_opaque__"),
11315 opaque_V2SI_type_node
));
11317 /* Initialize irregular SPE builtins. */
11319 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
11320 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
11321 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
11322 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
11323 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
11324 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
11325 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
11326 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
11327 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
11328 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
11329 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
11330 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
11331 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
11332 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
11333 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
11334 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
11335 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
11336 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
11339 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
11340 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
11341 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
11342 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
11343 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
11344 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
11345 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
11346 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
11347 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
11348 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
11349 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
11350 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
11351 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
11352 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
11353 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
11354 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
11355 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
11356 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
11357 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
11358 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
11359 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
11360 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
11363 d
= (struct builtin_description
*) bdesc_spe_predicates
;
11364 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
11368 switch (insn_data
[d
->icode
].operand
[1].mode
)
11371 type
= int_ftype_int_v2si_v2si
;
11374 type
= int_ftype_int_v2sf_v2sf
;
11377 gcc_unreachable ();
11380 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
11383 /* Evsel predicates. */
11384 d
= (struct builtin_description
*) bdesc_spe_evsel
;
11385 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
11389 switch (insn_data
[d
->icode
].operand
[1].mode
)
11392 type
= v2si_ftype_4_v2si
;
11395 type
= v2sf_ftype_4_v2sf
;
11398 gcc_unreachable ();
11401 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
11406 paired_init_builtins (void)
11408 const struct builtin_description
*d
;
11410 tree endlink
= void_list_node
;
11412 tree int_ftype_int_v2sf_v2sf
11413 = build_function_type
11414 (integer_type_node
,
11415 tree_cons (NULL_TREE
, integer_type_node
,
11416 tree_cons (NULL_TREE
, V2SF_type_node
,
11417 tree_cons (NULL_TREE
, V2SF_type_node
,
11419 tree pcfloat_type_node
=
11420 build_pointer_type (build_qualified_type
11421 (float_type_node
, TYPE_QUAL_CONST
));
11423 tree v2sf_ftype_long_pcfloat
= build_function_type_list (V2SF_type_node
,
11424 long_integer_type_node
,
11427 tree void_ftype_v2sf_long_pcfloat
=
11428 build_function_type_list (void_type_node
,
11430 long_integer_type_node
,
11435 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat
,
11436 PAIRED_BUILTIN_LX
);
11439 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat
,
11440 PAIRED_BUILTIN_STX
);
11443 d
= bdesc_paired_preds
;
11444 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); ++i
, d
++)
11448 switch (insn_data
[d
->icode
].operand
[1].mode
)
11451 type
= int_ftype_int_v2sf_v2sf
;
11454 gcc_unreachable ();
11457 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
11462 altivec_init_builtins (void)
11464 const struct builtin_description
*d
;
11465 const struct builtin_description_predicates
*dp
;
11469 tree pfloat_type_node
= build_pointer_type (float_type_node
);
11470 tree pint_type_node
= build_pointer_type (integer_type_node
);
11471 tree pshort_type_node
= build_pointer_type (short_integer_type_node
);
11472 tree pchar_type_node
= build_pointer_type (char_type_node
);
11474 tree pvoid_type_node
= build_pointer_type (void_type_node
);
11476 tree pcfloat_type_node
= build_pointer_type (build_qualified_type (float_type_node
, TYPE_QUAL_CONST
));
11477 tree pcint_type_node
= build_pointer_type (build_qualified_type (integer_type_node
, TYPE_QUAL_CONST
));
11478 tree pcshort_type_node
= build_pointer_type (build_qualified_type (short_integer_type_node
, TYPE_QUAL_CONST
));
11479 tree pcchar_type_node
= build_pointer_type (build_qualified_type (char_type_node
, TYPE_QUAL_CONST
));
11481 tree pcvoid_type_node
= build_pointer_type (build_qualified_type (void_type_node
, TYPE_QUAL_CONST
));
11483 tree int_ftype_opaque
11484 = build_function_type_list (integer_type_node
,
11485 opaque_V4SI_type_node
, NULL_TREE
);
11486 tree opaque_ftype_opaque
11487 = build_function_type (integer_type_node
,
11489 tree opaque_ftype_opaque_int
11490 = build_function_type_list (opaque_V4SI_type_node
,
11491 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
11492 tree opaque_ftype_opaque_opaque_int
11493 = build_function_type_list (opaque_V4SI_type_node
,
11494 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
11495 integer_type_node
, NULL_TREE
);
11496 tree int_ftype_int_opaque_opaque
11497 = build_function_type_list (integer_type_node
,
11498 integer_type_node
, opaque_V4SI_type_node
,
11499 opaque_V4SI_type_node
, NULL_TREE
);
11500 tree int_ftype_int_v4si_v4si
11501 = build_function_type_list (integer_type_node
,
11502 integer_type_node
, V4SI_type_node
,
11503 V4SI_type_node
, NULL_TREE
);
11504 tree v4sf_ftype_pcfloat
11505 = build_function_type_list (V4SF_type_node
, pcfloat_type_node
, NULL_TREE
);
11506 tree void_ftype_pfloat_v4sf
11507 = build_function_type_list (void_type_node
,
11508 pfloat_type_node
, V4SF_type_node
, NULL_TREE
);
11509 tree v4si_ftype_pcint
11510 = build_function_type_list (V4SI_type_node
, pcint_type_node
, NULL_TREE
);
11511 tree void_ftype_pint_v4si
11512 = build_function_type_list (void_type_node
,
11513 pint_type_node
, V4SI_type_node
, NULL_TREE
);
11514 tree v8hi_ftype_pcshort
11515 = build_function_type_list (V8HI_type_node
, pcshort_type_node
, NULL_TREE
);
11516 tree void_ftype_pshort_v8hi
11517 = build_function_type_list (void_type_node
,
11518 pshort_type_node
, V8HI_type_node
, NULL_TREE
);
11519 tree v16qi_ftype_pcchar
11520 = build_function_type_list (V16QI_type_node
, pcchar_type_node
, NULL_TREE
);
11521 tree void_ftype_pchar_v16qi
11522 = build_function_type_list (void_type_node
,
11523 pchar_type_node
, V16QI_type_node
, NULL_TREE
);
11524 tree void_ftype_v4si
11525 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
11526 tree v8hi_ftype_void
11527 = build_function_type (V8HI_type_node
, void_list_node
);
11528 tree void_ftype_void
11529 = build_function_type (void_type_node
, void_list_node
);
11530 tree void_ftype_int
11531 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
11533 tree opaque_ftype_long_pcvoid
11534 = build_function_type_list (opaque_V4SI_type_node
,
11535 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
11536 tree v16qi_ftype_long_pcvoid
11537 = build_function_type_list (V16QI_type_node
,
11538 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
11539 tree v8hi_ftype_long_pcvoid
11540 = build_function_type_list (V8HI_type_node
,
11541 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
11542 tree v4si_ftype_long_pcvoid
11543 = build_function_type_list (V4SI_type_node
,
11544 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
11546 tree void_ftype_opaque_long_pvoid
11547 = build_function_type_list (void_type_node
,
11548 opaque_V4SI_type_node
, long_integer_type_node
,
11549 pvoid_type_node
, NULL_TREE
);
11550 tree void_ftype_v4si_long_pvoid
11551 = build_function_type_list (void_type_node
,
11552 V4SI_type_node
, long_integer_type_node
,
11553 pvoid_type_node
, NULL_TREE
);
11554 tree void_ftype_v16qi_long_pvoid
11555 = build_function_type_list (void_type_node
,
11556 V16QI_type_node
, long_integer_type_node
,
11557 pvoid_type_node
, NULL_TREE
);
11558 tree void_ftype_v8hi_long_pvoid
11559 = build_function_type_list (void_type_node
,
11560 V8HI_type_node
, long_integer_type_node
,
11561 pvoid_type_node
, NULL_TREE
);
11562 tree int_ftype_int_v8hi_v8hi
11563 = build_function_type_list (integer_type_node
,
11564 integer_type_node
, V8HI_type_node
,
11565 V8HI_type_node
, NULL_TREE
);
11566 tree int_ftype_int_v16qi_v16qi
11567 = build_function_type_list (integer_type_node
,
11568 integer_type_node
, V16QI_type_node
,
11569 V16QI_type_node
, NULL_TREE
);
11570 tree int_ftype_int_v4sf_v4sf
11571 = build_function_type_list (integer_type_node
,
11572 integer_type_node
, V4SF_type_node
,
11573 V4SF_type_node
, NULL_TREE
);
11574 tree int_ftype_int_v2df_v2df
11575 = build_function_type_list (integer_type_node
,
11576 integer_type_node
, V2DF_type_node
,
11577 V2DF_type_node
, NULL_TREE
);
11578 tree v4si_ftype_v4si
11579 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
11580 tree v8hi_ftype_v8hi
11581 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
11582 tree v16qi_ftype_v16qi
11583 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
11584 tree v4sf_ftype_v4sf
11585 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
11586 tree v2df_ftype_v2df
11587 = build_function_type_list (V2DF_type_node
, V2DF_type_node
, NULL_TREE
);
11588 tree void_ftype_pcvoid_int_int
11589 = build_function_type_list (void_type_node
,
11590 pcvoid_type_node
, integer_type_node
,
11591 integer_type_node
, NULL_TREE
);
11593 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat
,
11594 ALTIVEC_BUILTIN_LD_INTERNAL_4sf
);
11595 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf
,
11596 ALTIVEC_BUILTIN_ST_INTERNAL_4sf
);
11597 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint
,
11598 ALTIVEC_BUILTIN_LD_INTERNAL_4si
);
11599 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si
,
11600 ALTIVEC_BUILTIN_ST_INTERNAL_4si
);
11601 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort
,
11602 ALTIVEC_BUILTIN_LD_INTERNAL_8hi
);
11603 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi
,
11604 ALTIVEC_BUILTIN_ST_INTERNAL_8hi
);
11605 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar
,
11606 ALTIVEC_BUILTIN_LD_INTERNAL_16qi
);
11607 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi
,
11608 ALTIVEC_BUILTIN_ST_INTERNAL_16qi
);
11609 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
11610 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
11611 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
11612 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
11613 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
11614 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
11615 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
11616 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
11617 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
11618 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
11619 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
11620 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
11621 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
11622 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
11623 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
11624 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
11625 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
11626 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
11627 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
11628 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
11629 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
11630 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
11631 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
11632 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
11633 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
11634 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
11635 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
11636 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
11637 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
11638 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
11640 if (rs6000_cpu
== PROCESSOR_CELL
)
11642 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLX
);
11643 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLXL
);
11644 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRX
);
11645 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRXL
);
11647 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLX
);
11648 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLXL
);
11649 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRX
);
11650 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRXL
);
11652 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLX
);
11653 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLXL
);
11654 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRX
);
11655 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRXL
);
11657 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLX
);
11658 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLXL
);
11659 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRX
);
11660 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRXL
);
11662 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
11663 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splats", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_SPLATS
);
11664 def_builtin (MASK_ALTIVEC
, "__builtin_vec_promote", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_PROMOTE
);
11666 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
11667 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
11668 def_builtin (MASK_ALTIVEC
, "__builtin_vec_extract", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_EXTRACT
);
11669 def_builtin (MASK_ALTIVEC
, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_INSERT
);
11670 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
11671 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
11672 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
11673 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
11674 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
11675 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
11676 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
11677 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
11679 /* Add the DST variants. */
11681 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
11682 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
11684 /* Initialize the predicates. */
11685 dp
= bdesc_altivec_preds
;
11686 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
11688 enum machine_mode mode1
;
11690 bool is_overloaded
= ((dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11691 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
11692 || (dp
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
11693 && dp
->code
<= VSX_BUILTIN_OVERLOADED_LAST
));
11698 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
11703 type
= int_ftype_int_opaque_opaque
;
11706 type
= int_ftype_int_v4si_v4si
;
11709 type
= int_ftype_int_v8hi_v8hi
;
11712 type
= int_ftype_int_v16qi_v16qi
;
11715 type
= int_ftype_int_v4sf_v4sf
;
11718 type
= int_ftype_int_v2df_v2df
;
11721 gcc_unreachable ();
11724 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
11727 /* Initialize the abs* operators. */
11729 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
11731 enum machine_mode mode0
;
11734 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
11739 type
= v4si_ftype_v4si
;
11742 type
= v8hi_ftype_v8hi
;
11745 type
= v16qi_ftype_v16qi
;
11748 type
= v4sf_ftype_v4sf
;
11751 type
= v2df_ftype_v2df
;
11754 gcc_unreachable ();
11757 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
11760 if (TARGET_ALTIVEC
)
11764 /* Initialize target builtin that implements
11765 targetm.vectorize.builtin_mask_for_load. */
11767 decl
= add_builtin_function ("__builtin_altivec_mask_for_load",
11768 v16qi_ftype_long_pcvoid
,
11769 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
11770 BUILT_IN_MD
, NULL
, NULL_TREE
);
11771 TREE_READONLY (decl
) = 1;
11772 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
11773 altivec_builtin_mask_for_load
= decl
;
11776 /* Access to the vec_init patterns. */
11777 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
11778 integer_type_node
, integer_type_node
,
11779 integer_type_node
, NULL_TREE
);
11780 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4si", ftype
,
11781 ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
11783 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
11784 short_integer_type_node
,
11785 short_integer_type_node
,
11786 short_integer_type_node
,
11787 short_integer_type_node
,
11788 short_integer_type_node
,
11789 short_integer_type_node
,
11790 short_integer_type_node
, NULL_TREE
);
11791 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v8hi", ftype
,
11792 ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
11794 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
11795 char_type_node
, char_type_node
,
11796 char_type_node
, char_type_node
,
11797 char_type_node
, char_type_node
,
11798 char_type_node
, char_type_node
,
11799 char_type_node
, char_type_node
,
11800 char_type_node
, char_type_node
,
11801 char_type_node
, char_type_node
,
11802 char_type_node
, NULL_TREE
);
11803 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v16qi", ftype
,
11804 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
11806 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
11807 float_type_node
, float_type_node
,
11808 float_type_node
, NULL_TREE
);
11809 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4sf", ftype
,
11810 ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
11814 ftype
= build_function_type_list (V2DF_type_node
, double_type_node
,
11815 double_type_node
, NULL_TREE
);
11816 def_builtin (MASK_VSX
, "__builtin_vec_init_v2df", ftype
,
11817 VSX_BUILTIN_VEC_INIT_V2DF
);
11819 ftype
= build_function_type_list (V2DI_type_node
, intDI_type_node
,
11820 intDI_type_node
, NULL_TREE
);
11821 def_builtin (MASK_VSX
, "__builtin_vec_init_v2di", ftype
,
11822 VSX_BUILTIN_VEC_INIT_V2DI
);
11825 /* Access to the vec_set patterns. */
11826 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
11828 integer_type_node
, NULL_TREE
);
11829 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4si", ftype
,
11830 ALTIVEC_BUILTIN_VEC_SET_V4SI
);
11832 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
11834 integer_type_node
, NULL_TREE
);
11835 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v8hi", ftype
,
11836 ALTIVEC_BUILTIN_VEC_SET_V8HI
);
11838 ftype
= build_function_type_list (V16QI_type_node
, V16QI_type_node
,
11840 integer_type_node
, NULL_TREE
);
11841 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v16qi", ftype
,
11842 ALTIVEC_BUILTIN_VEC_SET_V16QI
);
11844 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
11846 integer_type_node
, NULL_TREE
);
11847 def_builtin (MASK_ALTIVEC
|MASK_VSX
, "__builtin_vec_set_v4sf", ftype
,
11848 ALTIVEC_BUILTIN_VEC_SET_V4SF
);
11852 ftype
= build_function_type_list (V2DF_type_node
, V2DF_type_node
,
11854 integer_type_node
, NULL_TREE
);
11855 def_builtin (MASK_VSX
, "__builtin_vec_set_v2df", ftype
,
11856 VSX_BUILTIN_VEC_SET_V2DF
);
11858 ftype
= build_function_type_list (V2DI_type_node
, V2DI_type_node
,
11860 integer_type_node
, NULL_TREE
);
11861 def_builtin (MASK_VSX
, "__builtin_vec_set_v2di", ftype
,
11862 VSX_BUILTIN_VEC_SET_V2DI
);
11865 /* Access to the vec_extract patterns. */
11866 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
11867 integer_type_node
, NULL_TREE
);
11868 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4si", ftype
,
11869 ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
11871 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
11872 integer_type_node
, NULL_TREE
);
11873 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v8hi", ftype
,
11874 ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
11876 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
11877 integer_type_node
, NULL_TREE
);
11878 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v16qi", ftype
,
11879 ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
11881 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
11882 integer_type_node
, NULL_TREE
);
11883 def_builtin (MASK_ALTIVEC
|MASK_VSX
, "__builtin_vec_ext_v4sf", ftype
,
11884 ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
11888 ftype
= build_function_type_list (double_type_node
, V2DF_type_node
,
11889 integer_type_node
, NULL_TREE
);
11890 def_builtin (MASK_VSX
, "__builtin_vec_ext_v2df", ftype
,
11891 VSX_BUILTIN_VEC_EXT_V2DF
);
11893 ftype
= build_function_type_list (intDI_type_node
, V2DI_type_node
,
11894 integer_type_node
, NULL_TREE
);
11895 def_builtin (MASK_VSX
, "__builtin_vec_ext_v2di", ftype
,
11896 VSX_BUILTIN_VEC_EXT_V2DI
);
11900 /* Hash function for builtin functions with up to 3 arguments and a return
11903 builtin_hash_function (const void *hash_entry
)
11907 const struct builtin_hash_struct
*bh
=
11908 (const struct builtin_hash_struct
*) hash_entry
;
11910 for (i
= 0; i
< 4; i
++)
11912 ret
= (ret
* (unsigned)MAX_MACHINE_MODE
) + ((unsigned)bh
->mode
[i
]);
11913 ret
= (ret
* 2) + bh
->uns_p
[i
];
11919 /* Compare builtin hash entries H1 and H2 for equivalence. */
11921 builtin_hash_eq (const void *h1
, const void *h2
)
11923 const struct builtin_hash_struct
*p1
= (const struct builtin_hash_struct
*) h1
;
11924 const struct builtin_hash_struct
*p2
= (const struct builtin_hash_struct
*) h2
;
11926 return ((p1
->mode
[0] == p2
->mode
[0])
11927 && (p1
->mode
[1] == p2
->mode
[1])
11928 && (p1
->mode
[2] == p2
->mode
[2])
11929 && (p1
->mode
[3] == p2
->mode
[3])
11930 && (p1
->uns_p
[0] == p2
->uns_p
[0])
11931 && (p1
->uns_p
[1] == p2
->uns_p
[1])
11932 && (p1
->uns_p
[2] == p2
->uns_p
[2])
11933 && (p1
->uns_p
[3] == p2
->uns_p
[3]));
11936 /* Map types for builtin functions with an explicit return type and up to 3
11937 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
11938 of the argument. */
11940 builtin_function_type (enum machine_mode mode_ret
, enum machine_mode mode_arg0
,
11941 enum machine_mode mode_arg1
, enum machine_mode mode_arg2
,
11942 enum rs6000_builtins builtin
, const char *name
)
11944 struct builtin_hash_struct h
;
11945 struct builtin_hash_struct
*h2
;
11949 tree ret_type
= NULL_TREE
;
11950 tree arg_type
[3] = { NULL_TREE
, NULL_TREE
, NULL_TREE
};
11953 /* Create builtin_hash_table. */
11954 if (builtin_hash_table
== NULL
)
11955 builtin_hash_table
= htab_create_ggc (1500, builtin_hash_function
,
11956 builtin_hash_eq
, NULL
);
11958 h
.type
= NULL_TREE
;
11959 h
.mode
[0] = mode_ret
;
11960 h
.mode
[1] = mode_arg0
;
11961 h
.mode
[2] = mode_arg1
;
11962 h
.mode
[3] = mode_arg2
;
11968 /* If the builtin is a type that produces unsigned results or takes unsigned
11969 arguments, and it is returned as a decl for the vectorizer (such as
11970 widening multiplies, permute), make sure the arguments and return value
11971 are type correct. */
11974 /* unsigned 2 argument functions. */
11975 case ALTIVEC_BUILTIN_VMULEUB_UNS
:
11976 case ALTIVEC_BUILTIN_VMULEUH_UNS
:
11977 case ALTIVEC_BUILTIN_VMULOUB_UNS
:
11978 case ALTIVEC_BUILTIN_VMULOUH_UNS
:
11984 /* unsigned 3 argument functions. */
11985 case ALTIVEC_BUILTIN_VPERM_16QI_UNS
:
11986 case ALTIVEC_BUILTIN_VPERM_8HI_UNS
:
11987 case ALTIVEC_BUILTIN_VPERM_4SI_UNS
:
11988 case ALTIVEC_BUILTIN_VPERM_2DI_UNS
:
11989 case ALTIVEC_BUILTIN_VSEL_16QI_UNS
:
11990 case ALTIVEC_BUILTIN_VSEL_8HI_UNS
:
11991 case ALTIVEC_BUILTIN_VSEL_4SI_UNS
:
11992 case ALTIVEC_BUILTIN_VSEL_2DI_UNS
:
11993 case VSX_BUILTIN_VPERM_16QI_UNS
:
11994 case VSX_BUILTIN_VPERM_8HI_UNS
:
11995 case VSX_BUILTIN_VPERM_4SI_UNS
:
11996 case VSX_BUILTIN_VPERM_2DI_UNS
:
11997 case VSX_BUILTIN_XXSEL_16QI_UNS
:
11998 case VSX_BUILTIN_XXSEL_8HI_UNS
:
11999 case VSX_BUILTIN_XXSEL_4SI_UNS
:
12000 case VSX_BUILTIN_XXSEL_2DI_UNS
:
12007 /* signed permute functions with unsigned char mask. */
12008 case ALTIVEC_BUILTIN_VPERM_16QI
:
12009 case ALTIVEC_BUILTIN_VPERM_8HI
:
12010 case ALTIVEC_BUILTIN_VPERM_4SI
:
12011 case ALTIVEC_BUILTIN_VPERM_4SF
:
12012 case ALTIVEC_BUILTIN_VPERM_2DI
:
12013 case ALTIVEC_BUILTIN_VPERM_2DF
:
12014 case VSX_BUILTIN_VPERM_16QI
:
12015 case VSX_BUILTIN_VPERM_8HI
:
12016 case VSX_BUILTIN_VPERM_4SI
:
12017 case VSX_BUILTIN_VPERM_4SF
:
12018 case VSX_BUILTIN_VPERM_2DI
:
12019 case VSX_BUILTIN_VPERM_2DF
:
12023 /* unsigned args, signed return. */
12024 case VSX_BUILTIN_XVCVUXDDP_UNS
:
12025 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF
:
12029 /* signed args, unsigned return. */
12030 case VSX_BUILTIN_XVCVDPUXDS_UNS
:
12031 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI
:
12039 /* Figure out how many args are present. */
12040 while (num_args
> 0 && h
.mode
[num_args
] == VOIDmode
)
12044 fatal_error ("internal error: builtin function %s had no type", name
);
12046 ret_type
= builtin_mode_to_type
[h
.mode
[0]][h
.uns_p
[0]];
12047 if (!ret_type
&& h
.uns_p
[0])
12048 ret_type
= builtin_mode_to_type
[h
.mode
[0]][0];
12051 fatal_error ("internal error: builtin function %s had an unexpected "
12052 "return type %s", name
, GET_MODE_NAME (h
.mode
[0]));
12054 for (i
= 0; i
< num_args
; i
++)
12056 int m
= (int) h
.mode
[i
+1];
12057 int uns_p
= h
.uns_p
[i
+1];
12059 arg_type
[i
] = builtin_mode_to_type
[m
][uns_p
];
12060 if (!arg_type
[i
] && uns_p
)
12061 arg_type
[i
] = builtin_mode_to_type
[m
][0];
12064 fatal_error ("internal error: builtin function %s, argument %d "
12065 "had unexpected argument type %s", name
, i
,
12066 GET_MODE_NAME (m
));
12069 found
= htab_find_slot (builtin_hash_table
, &h
, INSERT
);
12070 if (*found
== NULL
)
12072 h2
= GGC_NEW (struct builtin_hash_struct
);
12074 *found
= (void *)h2
;
12075 args
= void_list_node
;
12077 for (i
= num_args
- 1; i
>= 0; i
--)
12078 args
= tree_cons (NULL_TREE
, arg_type
[i
], args
);
12080 h2
->type
= build_function_type (ret_type
, args
);
12083 return ((struct builtin_hash_struct
*)(*found
))->type
;
12087 rs6000_common_init_builtins (void)
12089 const struct builtin_description
*d
;
12092 tree opaque_ftype_opaque
= NULL_TREE
;
12093 tree opaque_ftype_opaque_opaque
= NULL_TREE
;
12094 tree opaque_ftype_opaque_opaque_opaque
= NULL_TREE
;
12095 tree v2si_ftype_qi
= NULL_TREE
;
12096 tree v2si_ftype_v2si_qi
= NULL_TREE
;
12097 tree v2si_ftype_int_qi
= NULL_TREE
;
12099 if (!TARGET_PAIRED_FLOAT
)
12101 builtin_mode_to_type
[V2SImode
][0] = opaque_V2SI_type_node
;
12102 builtin_mode_to_type
[V2SFmode
][0] = opaque_V2SF_type_node
;
12105 /* Add the ternary operators. */
12107 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
12110 int mask
= d
->mask
;
12112 if ((mask
!= 0 && (mask
& target_flags
) == 0)
12113 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
12116 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12117 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
12118 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
12119 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
12121 if (! (type
= opaque_ftype_opaque_opaque_opaque
))
12122 type
= opaque_ftype_opaque_opaque_opaque
12123 = build_function_type_list (opaque_V4SI_type_node
,
12124 opaque_V4SI_type_node
,
12125 opaque_V4SI_type_node
,
12126 opaque_V4SI_type_node
,
12131 enum insn_code icode
= d
->icode
;
12132 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
12135 type
= builtin_function_type (insn_data
[icode
].operand
[0].mode
,
12136 insn_data
[icode
].operand
[1].mode
,
12137 insn_data
[icode
].operand
[2].mode
,
12138 insn_data
[icode
].operand
[3].mode
,
12142 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12145 /* Add the binary operators. */
12147 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
12149 enum machine_mode mode0
, mode1
, mode2
;
12151 int mask
= d
->mask
;
12153 if ((mask
!= 0 && (mask
& target_flags
) == 0)
12154 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
12157 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12158 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
12159 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
12160 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
12162 if (! (type
= opaque_ftype_opaque_opaque
))
12163 type
= opaque_ftype_opaque_opaque
12164 = build_function_type_list (opaque_V4SI_type_node
,
12165 opaque_V4SI_type_node
,
12166 opaque_V4SI_type_node
,
12171 enum insn_code icode
= d
->icode
;
12172 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
12175 mode0
= insn_data
[icode
].operand
[0].mode
;
12176 mode1
= insn_data
[icode
].operand
[1].mode
;
12177 mode2
= insn_data
[icode
].operand
[2].mode
;
12179 if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
12181 if (! (type
= v2si_ftype_v2si_qi
))
12182 type
= v2si_ftype_v2si_qi
12183 = build_function_type_list (opaque_V2SI_type_node
,
12184 opaque_V2SI_type_node
,
12189 else if (mode0
== V2SImode
&& GET_MODE_CLASS (mode1
) == MODE_INT
12190 && mode2
== QImode
)
12192 if (! (type
= v2si_ftype_int_qi
))
12193 type
= v2si_ftype_int_qi
12194 = build_function_type_list (opaque_V2SI_type_node
,
12201 type
= builtin_function_type (mode0
, mode1
, mode2
, VOIDmode
,
12205 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12208 /* Add the simple unary operators. */
12209 d
= (struct builtin_description
*) bdesc_1arg
;
12210 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
12212 enum machine_mode mode0
, mode1
;
12214 int mask
= d
->mask
;
12216 if ((mask
!= 0 && (mask
& target_flags
) == 0)
12217 || (mask
== 0 && !TARGET_PAIRED_FLOAT
))
12220 if ((d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12221 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
12222 || (d
->code
>= VSX_BUILTIN_OVERLOADED_FIRST
12223 && d
->code
<= VSX_BUILTIN_OVERLOADED_LAST
))
12225 if (! (type
= opaque_ftype_opaque
))
12226 type
= opaque_ftype_opaque
12227 = build_function_type_list (opaque_V4SI_type_node
,
12228 opaque_V4SI_type_node
,
12233 enum insn_code icode
= d
->icode
;
12234 if (d
->name
== 0 || icode
== CODE_FOR_nothing
)
12237 mode0
= insn_data
[icode
].operand
[0].mode
;
12238 mode1
= insn_data
[icode
].operand
[1].mode
;
12240 if (mode0
== V2SImode
&& mode1
== QImode
)
12242 if (! (type
= v2si_ftype_qi
))
12243 type
= v2si_ftype_qi
12244 = build_function_type_list (opaque_V2SI_type_node
,
12250 type
= builtin_function_type (mode0
, mode1
, VOIDmode
, VOIDmode
,
12254 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
12259 rs6000_init_libfuncs (void)
12261 if (DEFAULT_ABI
!= ABI_V4
&& TARGET_XCOFF
12262 && !TARGET_POWER2
&& !TARGET_POWERPC
)
12264 /* AIX library routines for float->int conversion. */
12265 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
12266 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
12267 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
12268 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
12271 if (!TARGET_IEEEQUAD
)
12272 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12273 if (!TARGET_XL_COMPAT
)
12275 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
12276 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
12277 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
12278 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
12280 if (!(TARGET_HARD_FLOAT
&& (TARGET_FPRS
|| TARGET_E500_DOUBLE
)))
12282 set_optab_libfunc (neg_optab
, TFmode
, "__gcc_qneg");
12283 set_optab_libfunc (eq_optab
, TFmode
, "__gcc_qeq");
12284 set_optab_libfunc (ne_optab
, TFmode
, "__gcc_qne");
12285 set_optab_libfunc (gt_optab
, TFmode
, "__gcc_qgt");
12286 set_optab_libfunc (ge_optab
, TFmode
, "__gcc_qge");
12287 set_optab_libfunc (lt_optab
, TFmode
, "__gcc_qlt");
12288 set_optab_libfunc (le_optab
, TFmode
, "__gcc_qle");
12290 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "__gcc_stoq");
12291 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "__gcc_dtoq");
12292 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "__gcc_qtos");
12293 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "__gcc_qtod");
12294 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "__gcc_qtoi");
12295 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "__gcc_qtou");
12296 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "__gcc_itoq");
12297 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "__gcc_utoq");
12300 if (!(TARGET_HARD_FLOAT
&& TARGET_FPRS
))
12301 set_optab_libfunc (unord_optab
, TFmode
, "__gcc_qunord");
12305 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
12306 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
12307 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
12308 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
12312 /* 32-bit SVR4 quad floating point routines. */
12314 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
12315 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
12316 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
12317 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
12318 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
12319 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
12320 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
12322 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
12323 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
12324 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
12325 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
12326 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
12327 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
12329 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
12330 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
12331 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
12332 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
12333 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
12334 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
12335 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
12336 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "_q_utoq");
12341 /* Expand a block clear operation, and return 1 if successful. Return 0
12342 if we should let the compiler generate normal code.
12344 operands[0] is the destination
12345 operands[1] is the length
12346 operands[3] is the alignment */
12349 expand_block_clear (rtx operands
[])
12351 rtx orig_dest
= operands
[0];
12352 rtx bytes_rtx
= operands
[1];
12353 rtx align_rtx
= operands
[3];
12354 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
12355 HOST_WIDE_INT align
;
12356 HOST_WIDE_INT bytes
;
12361 /* If this is not a fixed size move, just call memcpy */
12365 /* This must be a fixed size alignment */
12366 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
12367 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
12369 /* Anything to clear? */
12370 bytes
= INTVAL (bytes_rtx
);
12374 /* Use the builtin memset after a point, to avoid huge code bloat.
12375 When optimize_size, avoid any significant code bloat; calling
12376 memset is about 4 instructions, so allow for one instruction to
12377 load zero and three to do clearing. */
12378 if (TARGET_ALTIVEC
&& align
>= 128)
12380 else if (TARGET_POWERPC64
&& align
>= 32)
12382 else if (TARGET_SPE
&& align
>= 64)
12387 if (optimize_size
&& bytes
> 3 * clear_step
)
12389 if (! optimize_size
&& bytes
> 8 * clear_step
)
12392 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
12394 enum machine_mode mode
= BLKmode
;
12397 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
12402 else if (bytes
>= 8 && TARGET_SPE
&& align
>= 64)
12407 else if (bytes
>= 8 && TARGET_POWERPC64
12408 /* 64-bit loads and stores require word-aligned
12410 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
12415 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
12416 { /* move 4 bytes */
12420 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
12421 { /* move 2 bytes */
12425 else /* move 1 byte at a time */
12431 dest
= adjust_address (orig_dest
, mode
, offset
);
12433 emit_move_insn (dest
, CONST0_RTX (mode
));
12440 /* Expand a block move operation, and return 1 if successful. Return 0
12441 if we should let the compiler generate normal code.
12443 operands[0] is the destination
12444 operands[1] is the source
12445 operands[2] is the length
12446 operands[3] is the alignment */
12448 #define MAX_MOVE_REG 4
12451 expand_block_move (rtx operands
[])
12453 rtx orig_dest
= operands
[0];
12454 rtx orig_src
= operands
[1];
12455 rtx bytes_rtx
= operands
[2];
12456 rtx align_rtx
= operands
[3];
12457 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
12462 rtx stores
[MAX_MOVE_REG
];
12465 /* If this is not a fixed size move, just call memcpy */
12469 /* This must be a fixed size alignment */
12470 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
12471 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
12473 /* Anything to move? */
12474 bytes
= INTVAL (bytes_rtx
);
12478 /* store_one_arg depends on expand_block_move to handle at least the size of
12479 reg_parm_stack_space. */
12480 if (bytes
> (TARGET_POWERPC64
? 64 : 32))
12483 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
12486 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
12487 rtx (*mov
) (rtx
, rtx
);
12489 enum machine_mode mode
= BLKmode
;
12492 /* Altivec first, since it will be faster than a string move
12493 when it applies, and usually not significantly larger. */
12494 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
12498 gen_func
.mov
= gen_movv4si
;
12500 else if (TARGET_SPE
&& bytes
>= 8 && align
>= 64)
12504 gen_func
.mov
= gen_movv2si
;
12506 else if (TARGET_STRING
12507 && bytes
> 24 /* move up to 32 bytes at a time */
12513 && ! fixed_regs
[10]
12514 && ! fixed_regs
[11]
12515 && ! fixed_regs
[12])
12517 move_bytes
= (bytes
> 32) ? 32 : bytes
;
12518 gen_func
.movmemsi
= gen_movmemsi_8reg
;
12520 else if (TARGET_STRING
12521 && bytes
> 16 /* move up to 24 bytes at a time */
12527 && ! fixed_regs
[10])
12529 move_bytes
= (bytes
> 24) ? 24 : bytes
;
12530 gen_func
.movmemsi
= gen_movmemsi_6reg
;
12532 else if (TARGET_STRING
12533 && bytes
> 8 /* move up to 16 bytes at a time */
12537 && ! fixed_regs
[8])
12539 move_bytes
= (bytes
> 16) ? 16 : bytes
;
12540 gen_func
.movmemsi
= gen_movmemsi_4reg
;
12542 else if (bytes
>= 8 && TARGET_POWERPC64
12543 /* 64-bit loads and stores require word-aligned
12545 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
12549 gen_func
.mov
= gen_movdi
;
12551 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
12552 { /* move up to 8 bytes at a time */
12553 move_bytes
= (bytes
> 8) ? 8 : bytes
;
12554 gen_func
.movmemsi
= gen_movmemsi_2reg
;
12556 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
12557 { /* move 4 bytes */
12560 gen_func
.mov
= gen_movsi
;
12562 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
12563 { /* move 2 bytes */
12566 gen_func
.mov
= gen_movhi
;
12568 else if (TARGET_STRING
&& bytes
> 1)
12569 { /* move up to 4 bytes at a time */
12570 move_bytes
= (bytes
> 4) ? 4 : bytes
;
12571 gen_func
.movmemsi
= gen_movmemsi_1reg
;
12573 else /* move 1 byte at a time */
12577 gen_func
.mov
= gen_movqi
;
12580 src
= adjust_address (orig_src
, mode
, offset
);
12581 dest
= adjust_address (orig_dest
, mode
, offset
);
12583 if (mode
!= BLKmode
)
12585 rtx tmp_reg
= gen_reg_rtx (mode
);
12587 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
12588 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
12591 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
12594 for (i
= 0; i
< num_reg
; i
++)
12595 emit_insn (stores
[i
]);
12599 if (mode
== BLKmode
)
12601 /* Move the address into scratch registers. The movmemsi
12602 patterns require zero offset. */
12603 if (!REG_P (XEXP (src
, 0)))
12605 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
12606 src
= replace_equiv_address (src
, src_reg
);
12608 set_mem_size (src
, GEN_INT (move_bytes
));
12610 if (!REG_P (XEXP (dest
, 0)))
12612 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
12613 dest
= replace_equiv_address (dest
, dest_reg
);
12615 set_mem_size (dest
, GEN_INT (move_bytes
));
12617 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
12618 GEN_INT (move_bytes
& 31),
12627 /* Return a string to perform a load_multiple operation.
12628 operands[0] is the vector.
12629 operands[1] is the source address.
12630 operands[2] is the first destination register. */
12633 rs6000_output_load_multiple (rtx operands
[3])
12635 /* We have to handle the case where the pseudo used to contain the address
12636 is assigned to one of the output registers. */
12638 int words
= XVECLEN (operands
[0], 0);
12641 if (XVECLEN (operands
[0], 0) == 1)
12642 return "{l|lwz} %2,0(%1)";
12644 for (i
= 0; i
< words
; i
++)
12645 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
12646 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
12650 xop
[0] = GEN_INT (4 * (words
-1));
12651 xop
[1] = operands
[1];
12652 xop
[2] = operands
[2];
12653 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
12658 xop
[0] = GEN_INT (4 * (words
-1));
12659 xop
[1] = operands
[1];
12660 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
12661 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
);
12666 for (j
= 0; j
< words
; j
++)
12669 xop
[0] = GEN_INT (j
* 4);
12670 xop
[1] = operands
[1];
12671 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
12672 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
12674 xop
[0] = GEN_INT (i
* 4);
12675 xop
[1] = operands
[1];
12676 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
12681 return "{lsi|lswi} %2,%1,%N0";
12685 /* A validation routine: say whether CODE, a condition code, and MODE
12686 match. The other alternatives either don't make sense or should
12687 never be generated. */
12690 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
12692 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
12693 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
12694 && GET_MODE_CLASS (mode
) == MODE_CC
);
12696 /* These don't make sense. */
12697 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
12698 || mode
!= CCUNSmode
);
12700 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
12701 || mode
== CCUNSmode
);
12703 gcc_assert (mode
== CCFPmode
12704 || (code
!= ORDERED
&& code
!= UNORDERED
12705 && code
!= UNEQ
&& code
!= LTGT
12706 && code
!= UNGT
&& code
!= UNLT
12707 && code
!= UNGE
&& code
!= UNLE
));
12709 /* These should never be generated except for
12710 flag_finite_math_only. */
12711 gcc_assert (mode
!= CCFPmode
12712 || flag_finite_math_only
12713 || (code
!= LE
&& code
!= GE
12714 && code
!= UNEQ
&& code
!= LTGT
12715 && code
!= UNGT
&& code
!= UNLT
));
12717 /* These are invalid; the information is not there. */
12718 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
12722 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
12723 mask required to convert the result of a rotate insn into a shift
12724 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
12727 includes_lshift_p (rtx shiftop
, rtx andop
)
12729 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
12731 shift_mask
<<= INTVAL (shiftop
);
12733 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
12736 /* Similar, but for right shift. */
12739 includes_rshift_p (rtx shiftop
, rtx andop
)
12741 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
12743 shift_mask
>>= INTVAL (shiftop
);
12745 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
12748 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
12749 to perform a left shift. It must have exactly SHIFTOP least
12750 significant 0's, then one or more 1's, then zero or more 0's. */
12753 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
12755 if (GET_CODE (andop
) == CONST_INT
)
12757 HOST_WIDE_INT c
, lsb
, shift_mask
;
12759 c
= INTVAL (andop
);
12760 if (c
== 0 || c
== ~0)
12764 shift_mask
<<= INTVAL (shiftop
);
12766 /* Find the least significant one bit. */
12769 /* It must coincide with the LSB of the shift mask. */
12770 if (-lsb
!= shift_mask
)
12773 /* Invert to look for the next transition (if any). */
12776 /* Remove the low group of ones (originally low group of zeros). */
12779 /* Again find the lsb, and check we have all 1's above. */
12783 else if (GET_CODE (andop
) == CONST_DOUBLE
12784 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
12786 HOST_WIDE_INT low
, high
, lsb
;
12787 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
12789 low
= CONST_DOUBLE_LOW (andop
);
12790 if (HOST_BITS_PER_WIDE_INT
< 64)
12791 high
= CONST_DOUBLE_HIGH (andop
);
12793 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
12794 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
12797 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
12799 shift_mask_high
= ~0;
12800 if (INTVAL (shiftop
) > 32)
12801 shift_mask_high
<<= INTVAL (shiftop
) - 32;
12803 lsb
= high
& -high
;
12805 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
12811 lsb
= high
& -high
;
12812 return high
== -lsb
;
12815 shift_mask_low
= ~0;
12816 shift_mask_low
<<= INTVAL (shiftop
);
12820 if (-lsb
!= shift_mask_low
)
12823 if (HOST_BITS_PER_WIDE_INT
< 64)
12828 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
12830 lsb
= high
& -high
;
12831 return high
== -lsb
;
12835 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
12841 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
12842 to perform a left shift. It must have SHIFTOP or more least
12843 significant 0's, with the remainder of the word 1's. */
12846 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
12848 if (GET_CODE (andop
) == CONST_INT
)
12850 HOST_WIDE_INT c
, lsb
, shift_mask
;
12853 shift_mask
<<= INTVAL (shiftop
);
12854 c
= INTVAL (andop
);
12856 /* Find the least significant one bit. */
12859 /* It must be covered by the shift mask.
12860 This test also rejects c == 0. */
12861 if ((lsb
& shift_mask
) == 0)
12864 /* Check we have all 1's above the transition, and reject all 1's. */
12865 return c
== -lsb
&& lsb
!= 1;
12867 else if (GET_CODE (andop
) == CONST_DOUBLE
12868 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
12870 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
12872 low
= CONST_DOUBLE_LOW (andop
);
12874 if (HOST_BITS_PER_WIDE_INT
< 64)
12876 HOST_WIDE_INT high
, shift_mask_high
;
12878 high
= CONST_DOUBLE_HIGH (andop
);
12882 shift_mask_high
= ~0;
12883 if (INTVAL (shiftop
) > 32)
12884 shift_mask_high
<<= INTVAL (shiftop
) - 32;
12886 lsb
= high
& -high
;
12888 if ((lsb
& shift_mask_high
) == 0)
12891 return high
== -lsb
;
12897 shift_mask_low
= ~0;
12898 shift_mask_low
<<= INTVAL (shiftop
);
12902 if ((lsb
& shift_mask_low
) == 0)
12905 return low
== -lsb
&& lsb
!= 1;
12911 /* Return 1 if operands will generate a valid arguments to rlwimi
12912 instruction for insert with right shift in 64-bit mode. The mask may
12913 not start on the first bit or stop on the last bit because wrap-around
12914 effects of instruction do not correspond to semantics of RTL insn. */
12917 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
12919 if (INTVAL (startop
) > 32
12920 && INTVAL (startop
) < 64
12921 && INTVAL (sizeop
) > 1
12922 && INTVAL (sizeop
) + INTVAL (startop
) < 64
12923 && INTVAL (shiftop
) > 0
12924 && INTVAL (sizeop
) + INTVAL (shiftop
) < 32
12925 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
12931 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
12932 for lfq and stfq insns iff the registers are hard registers. */
12935 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
12937 /* We might have been passed a SUBREG. */
12938 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
12941 /* We might have been passed non floating point registers. */
12942 if (!FP_REGNO_P (REGNO (reg1
))
12943 || !FP_REGNO_P (REGNO (reg2
)))
12946 return (REGNO (reg1
) == REGNO (reg2
) - 1);
12949 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
12950 addr1 and addr2 must be in consecutive memory locations
12951 (addr2 == addr1 + 8). */
12954 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
12957 unsigned int reg1
, reg2
;
12958 int offset1
, offset2
;
12960 /* The mems cannot be volatile. */
12961 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
12964 addr1
= XEXP (mem1
, 0);
12965 addr2
= XEXP (mem2
, 0);
12967 /* Extract an offset (if used) from the first addr. */
12968 if (GET_CODE (addr1
) == PLUS
)
12970 /* If not a REG, return zero. */
12971 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
12975 reg1
= REGNO (XEXP (addr1
, 0));
12976 /* The offset must be constant! */
12977 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
12979 offset1
= INTVAL (XEXP (addr1
, 1));
12982 else if (GET_CODE (addr1
) != REG
)
12986 reg1
= REGNO (addr1
);
12987 /* This was a simple (mem (reg)) expression. Offset is 0. */
12991 /* And now for the second addr. */
12992 if (GET_CODE (addr2
) == PLUS
)
12994 /* If not a REG, return zero. */
12995 if (GET_CODE (XEXP (addr2
, 0)) != REG
)
12999 reg2
= REGNO (XEXP (addr2
, 0));
13000 /* The offset must be constant. */
13001 if (GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
13003 offset2
= INTVAL (XEXP (addr2
, 1));
13006 else if (GET_CODE (addr2
) != REG
)
13010 reg2
= REGNO (addr2
);
13011 /* This was a simple (mem (reg)) expression. Offset is 0. */
13015 /* Both of these must have the same base register. */
13019 /* The offset for the second addr must be 8 more than the first addr. */
13020 if (offset2
!= offset1
+ 8)
13023 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13030 rs6000_secondary_memory_needed_rtx (enum machine_mode mode
)
13032 static bool eliminated
= false;
13035 if (mode
!= SDmode
)
13036 ret
= assign_stack_local (mode
, GET_MODE_SIZE (mode
), 0);
13039 rtx mem
= cfun
->machine
->sdmode_stack_slot
;
13040 gcc_assert (mem
!= NULL_RTX
);
13044 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
13045 cfun
->machine
->sdmode_stack_slot
= mem
;
13051 if (TARGET_DEBUG_ADDR
)
13053 fprintf (stderr
, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13054 GET_MODE_NAME (mode
));
13056 fprintf (stderr
, "\tNULL_RTX\n");
13065 rs6000_check_sdmode (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
13067 /* Don't walk into types. */
13068 if (*tp
== NULL_TREE
|| *tp
== error_mark_node
|| TYPE_P (*tp
))
13070 *walk_subtrees
= 0;
13074 switch (TREE_CODE (*tp
))
13083 case ALIGN_INDIRECT_REF
:
13084 case MISALIGNED_INDIRECT_REF
:
13085 case VIEW_CONVERT_EXPR
:
13086 if (TYPE_MODE (TREE_TYPE (*tp
)) == SDmode
)
13096 enum reload_reg_type
{
13098 VECTOR_REGISTER_TYPE
,
13099 OTHER_REGISTER_TYPE
13102 static enum reload_reg_type
13103 rs6000_reload_register_type (enum reg_class rclass
)
13109 return GPR_REGISTER_TYPE
;
13114 return VECTOR_REGISTER_TYPE
;
13117 return OTHER_REGISTER_TYPE
;
13121 /* Inform reload about cases where moving X with a mode MODE to a register in
13122 RCLASS requires an extra scratch or immediate register. Return the class
13123 needed for the immediate register.
13125 For VSX and Altivec, we may need a register to convert sp+offset into
13128 static enum reg_class
13129 rs6000_secondary_reload (bool in_p
,
13131 enum reg_class rclass
,
13132 enum machine_mode mode
,
13133 secondary_reload_info
*sri
)
13135 enum reg_class ret
= ALL_REGS
;
13136 enum insn_code icode
;
13137 bool default_p
= false;
13139 sri
->icode
= CODE_FOR_nothing
;
13141 /* Convert vector loads and stores into gprs to use an additional base
13143 icode
= rs6000_vector_reload
[mode
][in_p
!= false];
13144 if (icode
!= CODE_FOR_nothing
)
13147 sri
->icode
= CODE_FOR_nothing
;
13148 sri
->extra_cost
= 0;
13150 if (GET_CODE (x
) == MEM
)
13152 rtx addr
= XEXP (x
, 0);
13154 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13155 an extra register in that case, but it would need an extra
13156 register if the addressing is reg+reg or (reg+reg)&(-16). */
13157 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
)
13159 if (!legitimate_indirect_address_p (addr
, false)
13160 && !rs6000_legitimate_offset_address_p (TImode
, addr
, false))
13162 sri
->icode
= icode
;
13163 /* account for splitting the loads, and converting the
13164 address from reg+reg to reg. */
13165 sri
->extra_cost
= (((TARGET_64BIT
) ? 3 : 5)
13166 + ((GET_CODE (addr
) == AND
) ? 1 : 0));
13169 /* Loads to and stores from vector registers can only do reg+reg
13170 addressing. Altivec registers can also do (reg+reg)&(-16). */
13171 else if (rclass
== VSX_REGS
|| rclass
== ALTIVEC_REGS
13172 || rclass
== FLOAT_REGS
|| rclass
== NO_REGS
)
13174 if (!VECTOR_MEM_ALTIVEC_P (mode
)
13175 && GET_CODE (addr
) == AND
13176 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
13177 && INTVAL (XEXP (addr
, 1)) == -16
13178 && (legitimate_indirect_address_p (XEXP (addr
, 0), false)
13179 || legitimate_indexed_address_p (XEXP (addr
, 0), false)))
13181 sri
->icode
= icode
;
13182 sri
->extra_cost
= ((GET_CODE (XEXP (addr
, 0)) == PLUS
)
13185 else if (!legitimate_indirect_address_p (addr
, false)
13186 && (rclass
== NO_REGS
13187 || !legitimate_indexed_address_p (addr
, false)))
13189 sri
->icode
= icode
;
13190 sri
->extra_cost
= 1;
13193 icode
= CODE_FOR_nothing
;
13195 /* Any other loads, including to pseudo registers which haven't been
13196 assigned to a register yet, default to require a scratch
13200 sri
->icode
= icode
;
13201 sri
->extra_cost
= 2;
13204 else if (REG_P (x
))
13206 int regno
= true_regnum (x
);
13208 icode
= CODE_FOR_nothing
;
13209 if (regno
< 0 || regno
>= FIRST_PSEUDO_REGISTER
)
13213 enum reg_class xclass
= REGNO_REG_CLASS (regno
);
13214 enum reload_reg_type rtype1
= rs6000_reload_register_type (rclass
);
13215 enum reload_reg_type rtype2
= rs6000_reload_register_type (xclass
);
13217 /* If memory is needed, use default_secondary_reload to create the
13219 if (rtype1
!= rtype2
|| rtype1
== OTHER_REGISTER_TYPE
)
13232 ret
= default_secondary_reload (in_p
, x
, rclass
, mode
, sri
);
13234 gcc_assert (ret
!= ALL_REGS
);
13236 if (TARGET_DEBUG_ADDR
)
13239 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13241 reg_class_names
[ret
],
13242 in_p
? "true" : "false",
13243 reg_class_names
[rclass
],
13244 GET_MODE_NAME (mode
));
13247 fprintf (stderr
, ", default secondary reload");
13249 if (sri
->icode
!= CODE_FOR_nothing
)
13250 fprintf (stderr
, ", reload func = %s, extra cost = %d\n",
13251 insn_data
[sri
->icode
].name
, sri
->extra_cost
);
13253 fprintf (stderr
, "\n");
13261 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13262 to SP+reg addressing. */
13265 rs6000_secondary_reload_inner (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
13267 int regno
= true_regnum (reg
);
13268 enum machine_mode mode
= GET_MODE (reg
);
13269 enum reg_class rclass
;
13271 rtx and_op2
= NULL_RTX
;
13274 rtx scratch_or_premodify
= scratch
;
13278 if (TARGET_DEBUG_ADDR
)
13280 fprintf (stderr
, "\nrs6000_secondary_reload_inner, type = %s\n",
13281 store_p
? "store" : "load");
13282 fprintf (stderr
, "reg:\n");
13284 fprintf (stderr
, "mem:\n");
13286 fprintf (stderr
, "scratch:\n");
13287 debug_rtx (scratch
);
13290 gcc_assert (regno
>= 0 && regno
< FIRST_PSEUDO_REGISTER
);
13291 gcc_assert (GET_CODE (mem
) == MEM
);
13292 rclass
= REGNO_REG_CLASS (regno
);
13293 addr
= XEXP (mem
, 0);
13297 /* GPRs can handle reg + small constant, all other addresses need to use
13298 the scratch register. */
13301 if (GET_CODE (addr
) == AND
)
13303 and_op2
= XEXP (addr
, 1);
13304 addr
= XEXP (addr
, 0);
13307 if (GET_CODE (addr
) == PRE_MODIFY
)
13309 scratch_or_premodify
= XEXP (addr
, 0);
13310 gcc_assert (REG_P (scratch_or_premodify
));
13311 gcc_assert (GET_CODE (XEXP (addr
, 1)) == PLUS
);
13312 addr
= XEXP (addr
, 1);
13315 if (GET_CODE (addr
) == PLUS
13316 && (!rs6000_legitimate_offset_address_p (TImode
, addr
, false)
13317 || and_op2
!= NULL_RTX
))
13319 addr_op1
= XEXP (addr
, 0);
13320 addr_op2
= XEXP (addr
, 1);
13321 gcc_assert (legitimate_indirect_address_p (addr_op1
, false));
13323 if (!REG_P (addr_op2
)
13324 && (GET_CODE (addr_op2
) != CONST_INT
13325 || !satisfies_constraint_I (addr_op2
)))
13327 if (TARGET_DEBUG_ADDR
)
13330 "\nMove plus addr to register %s, mode = %s: ",
13331 rs6000_reg_names
[REGNO (scratch
)],
13332 GET_MODE_NAME (mode
));
13333 debug_rtx (addr_op2
);
13335 rs6000_emit_move (scratch
, addr_op2
, Pmode
);
13336 addr_op2
= scratch
;
13339 emit_insn (gen_rtx_SET (VOIDmode
,
13340 scratch_or_premodify
,
13341 gen_rtx_PLUS (Pmode
,
13345 addr
= scratch_or_premodify
;
13346 scratch_or_premodify
= scratch
;
13348 else if (!legitimate_indirect_address_p (addr
, false)
13349 && !rs6000_legitimate_offset_address_p (TImode
, addr
, false))
13351 if (TARGET_DEBUG_ADDR
)
13353 fprintf (stderr
, "\nMove addr to register %s, mode = %s: ",
13354 rs6000_reg_names
[REGNO (scratch_or_premodify
)],
13355 GET_MODE_NAME (mode
));
13358 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
13359 addr
= scratch_or_premodify
;
13360 scratch_or_premodify
= scratch
;
13364 /* Float/Altivec registers can only handle reg+reg addressing. Move
13365 other addresses into a scratch register. */
13370 /* With float regs, we need to handle the AND ourselves, since we can't
13371 use the Altivec instruction with an implicit AND -16. Allow scalar
13372 loads to float registers to use reg+offset even if VSX. */
13373 if (GET_CODE (addr
) == AND
13374 && (rclass
!= ALTIVEC_REGS
|| GET_MODE_SIZE (mode
) != 16
13375 || GET_CODE (XEXP (addr
, 1)) != CONST_INT
13376 || INTVAL (XEXP (addr
, 1)) != -16
13377 || !VECTOR_MEM_ALTIVEC_P (mode
)))
13379 and_op2
= XEXP (addr
, 1);
13380 addr
= XEXP (addr
, 0);
13383 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13384 as the address later. */
13385 if (GET_CODE (addr
) == PRE_MODIFY
13386 && (!VECTOR_MEM_VSX_P (mode
)
13387 || and_op2
!= NULL_RTX
13388 || !legitimate_indexed_address_p (XEXP (addr
, 1), false)))
13390 scratch_or_premodify
= XEXP (addr
, 0);
13391 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify
,
13393 gcc_assert (GET_CODE (XEXP (addr
, 1)) == PLUS
);
13394 addr
= XEXP (addr
, 1);
13397 if (legitimate_indirect_address_p (addr
, false) /* reg */
13398 || legitimate_indexed_address_p (addr
, false) /* reg+reg */
13399 || GET_CODE (addr
) == PRE_MODIFY
/* VSX pre-modify */
13400 || (GET_CODE (addr
) == AND
/* Altivec memory */
13401 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
13402 && INTVAL (XEXP (addr
, 1)) == -16
13403 && VECTOR_MEM_ALTIVEC_P (mode
))
13404 || (rclass
== FLOAT_REGS
/* legacy float mem */
13405 && GET_MODE_SIZE (mode
) == 8
13406 && and_op2
== NULL_RTX
13407 && scratch_or_premodify
== scratch
13408 && rs6000_legitimate_offset_address_p (mode
, addr
, false)))
13411 else if (GET_CODE (addr
) == PLUS
)
13413 addr_op1
= XEXP (addr
, 0);
13414 addr_op2
= XEXP (addr
, 1);
13415 gcc_assert (REG_P (addr_op1
));
13417 if (TARGET_DEBUG_ADDR
)
13419 fprintf (stderr
, "\nMove plus addr to register %s, mode = %s: ",
13420 rs6000_reg_names
[REGNO (scratch
)], GET_MODE_NAME (mode
));
13421 debug_rtx (addr_op2
);
13423 rs6000_emit_move (scratch
, addr_op2
, Pmode
);
13424 emit_insn (gen_rtx_SET (VOIDmode
,
13425 scratch_or_premodify
,
13426 gen_rtx_PLUS (Pmode
,
13429 addr
= scratch_or_premodify
;
13430 scratch_or_premodify
= scratch
;
13433 else if (GET_CODE (addr
) == SYMBOL_REF
|| GET_CODE (addr
) == CONST
13434 || GET_CODE (addr
) == CONST_INT
|| REG_P (addr
))
13436 if (TARGET_DEBUG_ADDR
)
13438 fprintf (stderr
, "\nMove addr to register %s, mode = %s: ",
13439 rs6000_reg_names
[REGNO (scratch_or_premodify
)],
13440 GET_MODE_NAME (mode
));
13444 rs6000_emit_move (scratch_or_premodify
, addr
, Pmode
);
13445 addr
= scratch_or_premodify
;
13446 scratch_or_premodify
= scratch
;
13450 gcc_unreachable ();
13455 gcc_unreachable ();
13458 /* If the original address involved a pre-modify that we couldn't use the VSX
13459 memory instruction with update, and we haven't taken care of already,
13460 store the address in the pre-modify register and use that as the
13462 if (scratch_or_premodify
!= scratch
&& scratch_or_premodify
!= addr
)
13464 emit_insn (gen_rtx_SET (VOIDmode
, scratch_or_premodify
, addr
));
13465 addr
= scratch_or_premodify
;
13468 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13469 memory instruction, recreate the AND now, including the clobber which is
13470 generated by the general ANDSI3/ANDDI3 patterns for the
13471 andi. instruction. */
13472 if (and_op2
!= NULL_RTX
)
13474 if (! legitimate_indirect_address_p (addr
, false))
13476 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, addr
));
13480 if (TARGET_DEBUG_ADDR
)
13482 fprintf (stderr
, "\nAnd addr to register %s, mode = %s: ",
13483 rs6000_reg_names
[REGNO (scratch
)], GET_MODE_NAME (mode
));
13484 debug_rtx (and_op2
);
13487 and_rtx
= gen_rtx_SET (VOIDmode
,
13489 gen_rtx_AND (Pmode
,
13493 cc_clobber
= gen_rtx_CLOBBER (CCmode
, gen_rtx_SCRATCH (CCmode
));
13494 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
13495 gen_rtvec (2, and_rtx
, cc_clobber
)));
13499 /* Adjust the address if it changed. */
13500 if (addr
!= XEXP (mem
, 0))
13502 mem
= change_address (mem
, mode
, addr
);
13503 if (TARGET_DEBUG_ADDR
)
13504 fprintf (stderr
, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
13507 /* Now create the move. */
13509 emit_insn (gen_rtx_SET (VOIDmode
, mem
, reg
));
13511 emit_insn (gen_rtx_SET (VOIDmode
, reg
, mem
));
13516 /* Target hook to return the cover classes for Integrated Register Allocator.
13517 Cover classes is a set of non-intersected register classes covering all hard
13518 registers used for register allocation purpose. Any move between two
13519 registers of a cover class should be cheaper than load or store of the
13520 registers. The value is array of register classes with LIM_REG_CLASSES used
13523 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
13524 account for the Altivec and Floating registers being subsets of the VSX
13525 register set under VSX, but distinct register sets on pre-VSX machines. */
13527 static const enum reg_class
*
13528 rs6000_ira_cover_classes (void)
13530 static const enum reg_class cover_pre_vsx
[] = IRA_COVER_CLASSES_PRE_VSX
;
13531 static const enum reg_class cover_vsx
[] = IRA_COVER_CLASSES_VSX
;
13533 return (TARGET_VSX
) ? cover_vsx
: cover_pre_vsx
;
13536 /* Allocate a 64-bit stack slot to be used for copying SDmode
13537 values through if this function has any SDmode references. */
13540 rs6000_alloc_sdmode_stack_slot (void)
13544 gimple_stmt_iterator gsi
;
13546 gcc_assert (cfun
->machine
->sdmode_stack_slot
== NULL_RTX
);
13549 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
13551 tree ret
= walk_gimple_op (gsi_stmt (gsi
), rs6000_check_sdmode
, NULL
);
13554 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
13555 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
13561 /* Check for any SDmode parameters of the function. */
13562 for (t
= DECL_ARGUMENTS (cfun
->decl
); t
; t
= TREE_CHAIN (t
))
13564 if (TREE_TYPE (t
) == error_mark_node
)
13567 if (TYPE_MODE (TREE_TYPE (t
)) == SDmode
13568 || TYPE_MODE (DECL_ARG_TYPE (t
)) == SDmode
)
13570 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
13571 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
13579 rs6000_instantiate_decls (void)
13581 if (cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
13582 instantiate_decl_rtl (cfun
->machine
->sdmode_stack_slot
);
13585 /* Given an rtx X being reloaded into a reg required to be
13586 in class CLASS, return the class of reg to actually use.
13587 In general this is just CLASS; but on some machines
13588 in some cases it is preferable to use a more restrictive class.
13590 On the RS/6000, we have to return NO_REGS when we want to reload a
13591 floating-point CONST_DOUBLE to force it to be copied to memory.
13593 We also don't want to reload integer values into floating-point
13594 registers if we can at all help it. In fact, this can
13595 cause reload to die, if it tries to generate a reload of CTR
13596 into a FP register and discovers it doesn't have the memory location
13599 ??? Would it be a good idea to have reload do the converse, that is
13600 try to reload floating modes into FP registers if possible?
13603 static enum reg_class
13604 rs6000_preferred_reload_class (rtx x
, enum reg_class rclass
)
13606 enum machine_mode mode
= GET_MODE (x
);
13608 if (VECTOR_UNIT_VSX_P (mode
)
13609 && x
== CONST0_RTX (mode
) && VSX_REG_CLASS_P (rclass
))
13612 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode
)
13613 && (rclass
== ALTIVEC_REGS
|| rclass
== VSX_REGS
)
13614 && easy_vector_constant (x
, mode
))
13615 return ALTIVEC_REGS
;
13617 if (CONSTANT_P (x
) && reg_classes_intersect_p (rclass
, FLOAT_REGS
))
13620 if (GET_MODE_CLASS (mode
) == MODE_INT
&& rclass
== NON_SPECIAL_REGS
)
13621 return GENERAL_REGS
;
13623 /* For VSX, prefer the traditional registers for DF if the address is of the
13624 form reg+offset because we can use the non-VSX loads. Prefer the Altivec
13625 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI,
13627 if (rclass
== VSX_REGS
&& VECTOR_MEM_VSX_P (mode
))
13629 if (mode
== DFmode
&& GET_CODE (x
) == MEM
)
13631 rtx addr
= XEXP (x
, 0);
13633 if (legitimate_indirect_address_p (addr
, false)) /* reg */
13636 if (legitimate_indexed_address_p (addr
, false)) /* reg+reg */
13639 if (GET_CODE (addr
) == PRE_MODIFY
13640 && legitimate_indexed_address_p (XEXP (addr
, 0), false))
13646 if (VECTOR_UNIT_ALTIVEC_P (mode
))
13647 return ALTIVEC_REGS
;
13655 /* Debug version of rs6000_preferred_reload_class. */
13656 static enum reg_class
13657 rs6000_debug_preferred_reload_class (rtx x
, enum reg_class rclass
)
13659 enum reg_class ret
= rs6000_preferred_reload_class (x
, rclass
);
13662 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
13664 reg_class_names
[ret
], reg_class_names
[rclass
],
13665 GET_MODE_NAME (GET_MODE (x
)));
13671 /* If we are copying between FP or AltiVec registers and anything else, we need
13672 a memory location. The exception is when we are targeting ppc64 and the
13673 move to/from fpr to gpr instructions are available. Also, under VSX, you
13674 can copy vector registers from the FP register set to the Altivec register
13675 set and vice versa. */
13678 rs6000_secondary_memory_needed (enum reg_class class1
,
13679 enum reg_class class2
,
13680 enum machine_mode mode
)
13682 if (class1
== class2
)
13685 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
13686 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
13687 between these classes. But we need memory for other things that can go in
13688 FLOAT_REGS like SFmode. */
13690 && (VECTOR_MEM_VSX_P (mode
) || VECTOR_UNIT_VSX_P (mode
))
13691 && (class1
== VSX_REGS
|| class1
== ALTIVEC_REGS
13692 || class1
== FLOAT_REGS
))
13693 return (class2
!= VSX_REGS
&& class2
!= ALTIVEC_REGS
13694 && class2
!= FLOAT_REGS
);
13696 if (class1
== VSX_REGS
|| class2
== VSX_REGS
)
13699 if (class1
== FLOAT_REGS
13700 && (!TARGET_MFPGPR
|| !TARGET_POWERPC64
13701 || ((mode
!= DFmode
)
13702 && (mode
!= DDmode
)
13703 && (mode
!= DImode
))))
13706 if (class2
== FLOAT_REGS
13707 && (!TARGET_MFPGPR
|| !TARGET_POWERPC64
13708 || ((mode
!= DFmode
)
13709 && (mode
!= DDmode
)
13710 && (mode
!= DImode
))))
13713 if (class1
== ALTIVEC_REGS
|| class2
== ALTIVEC_REGS
)
13719 /* Debug version of rs6000_secondary_memory_needed. */
13721 rs6000_debug_secondary_memory_needed (enum reg_class class1
,
13722 enum reg_class class2
,
13723 enum machine_mode mode
)
13725 bool ret
= rs6000_secondary_memory_needed (class1
, class2
, mode
);
13728 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
13729 "class2 = %s, mode = %s\n",
13730 ret
? "true" : "false", reg_class_names
[class1
],
13731 reg_class_names
[class2
], GET_MODE_NAME (mode
));
13736 /* Return the register class of a scratch register needed to copy IN into
13737 or out of a register in RCLASS in MODE. If it can be done directly,
13738 NO_REGS is returned. */
13740 static enum reg_class
13741 rs6000_secondary_reload_class (enum reg_class rclass
, enum machine_mode mode
,
13746 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
13748 && MACHOPIC_INDIRECT
13752 /* We cannot copy a symbolic operand directly into anything
13753 other than BASE_REGS for TARGET_ELF. So indicate that a
13754 register from BASE_REGS is needed as an intermediate
13757 On Darwin, pic addresses require a load from memory, which
13758 needs a base register. */
13759 if (rclass
!= BASE_REGS
13760 && (GET_CODE (in
) == SYMBOL_REF
13761 || GET_CODE (in
) == HIGH
13762 || GET_CODE (in
) == LABEL_REF
13763 || GET_CODE (in
) == CONST
))
13767 if (GET_CODE (in
) == REG
)
13769 regno
= REGNO (in
);
13770 if (regno
>= FIRST_PSEUDO_REGISTER
)
13772 regno
= true_regnum (in
);
13773 if (regno
>= FIRST_PSEUDO_REGISTER
)
13777 else if (GET_CODE (in
) == SUBREG
)
13779 regno
= true_regnum (in
);
13780 if (regno
>= FIRST_PSEUDO_REGISTER
)
13786 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
13788 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
13789 || (regno
>= 0 && INT_REGNO_P (regno
)))
13792 /* Constants, memory, and FP registers can go into FP registers. */
13793 if ((regno
== -1 || FP_REGNO_P (regno
))
13794 && (rclass
== FLOAT_REGS
|| rclass
== NON_SPECIAL_REGS
))
13795 return (mode
!= SDmode
) ? NO_REGS
: GENERAL_REGS
;
13797 /* Memory, and FP/altivec registers can go into fp/altivec registers under
13800 && (regno
== -1 || VSX_REGNO_P (regno
))
13801 && VSX_REG_CLASS_P (rclass
))
13804 /* Memory, and AltiVec registers can go into AltiVec registers. */
13805 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
13806 && rclass
== ALTIVEC_REGS
)
13809 /* We can copy among the CR registers. */
13810 if ((rclass
== CR_REGS
|| rclass
== CR0_REGS
)
13811 && regno
>= 0 && CR_REGNO_P (regno
))
13814 /* Otherwise, we need GENERAL_REGS. */
13815 return GENERAL_REGS
;
13818 /* Debug version of rs6000_secondary_reload_class. */
13819 static enum reg_class
13820 rs6000_debug_secondary_reload_class (enum reg_class rclass
,
13821 enum machine_mode mode
, rtx in
)
13823 enum reg_class ret
= rs6000_secondary_reload_class (rclass
, mode
, in
);
13825 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
13826 "mode = %s, input rtx:\n",
13827 reg_class_names
[ret
], reg_class_names
[rclass
],
13828 GET_MODE_NAME (mode
));
13834 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
13837 rs6000_cannot_change_mode_class (enum machine_mode from
,
13838 enum machine_mode to
,
13839 enum reg_class rclass
)
13841 unsigned from_size
= GET_MODE_SIZE (from
);
13842 unsigned to_size
= GET_MODE_SIZE (to
);
13844 if (from_size
!= to_size
)
13846 enum reg_class xclass
= (TARGET_VSX
) ? VSX_REGS
: FLOAT_REGS
;
13847 return ((from_size
< 8 || to_size
< 8 || TARGET_IEEEQUAD
)
13848 && reg_classes_intersect_p (xclass
, rclass
));
13851 if (TARGET_E500_DOUBLE
13852 && ((((to
) == DFmode
) + ((from
) == DFmode
)) == 1
13853 || (((to
) == TFmode
) + ((from
) == TFmode
)) == 1
13854 || (((to
) == DDmode
) + ((from
) == DDmode
)) == 1
13855 || (((to
) == TDmode
) + ((from
) == TDmode
)) == 1
13856 || (((to
) == DImode
) + ((from
) == DImode
)) == 1))
13859 /* Since the VSX register set includes traditional floating point registers
13860 and altivec registers, just check for the size being different instead of
13861 trying to check whether the modes are vector modes. Otherwise it won't
13862 allow say DF and DI to change classes. */
13863 if (TARGET_VSX
&& VSX_REG_CLASS_P (rclass
))
13864 return (from_size
!= 8 && from_size
!= 16);
13866 if (TARGET_ALTIVEC
&& rclass
== ALTIVEC_REGS
13867 && (ALTIVEC_VECTOR_MODE (from
) + ALTIVEC_VECTOR_MODE (to
)) == 1)
13870 if (TARGET_SPE
&& (SPE_VECTOR_MODE (from
) + SPE_VECTOR_MODE (to
)) == 1
13871 && reg_classes_intersect_p (GENERAL_REGS
, rclass
))
13877 /* Debug version of rs6000_cannot_change_mode_class. */
13879 rs6000_debug_cannot_change_mode_class (enum machine_mode from
,
13880 enum machine_mode to
,
13881 enum reg_class rclass
)
13883 bool ret
= rs6000_cannot_change_mode_class (from
, to
, rclass
);
13886 "rs6000_cannot_change_mode_class, return %s, from = %s, "
13887 "to = %s, rclass = %s\n",
13888 ret
? "true" : "false",
13889 GET_MODE_NAME (from
), GET_MODE_NAME (to
),
13890 reg_class_names
[rclass
]);
13895 /* Given a comparison operation, return the bit number in CCR to test. We
13896 know this is a valid comparison.
13898 SCC_P is 1 if this is for an scc. That means that %D will have been
13899 used instead of %C, so the bits will be in different places.
13901 Return -1 if OP isn't a valid comparison for some reason. */
13904 ccr_bit (rtx op
, int scc_p
)
13906 enum rtx_code code
= GET_CODE (op
);
13907 enum machine_mode cc_mode
;
13912 if (!COMPARISON_P (op
))
13915 reg
= XEXP (op
, 0);
13917 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
13919 cc_mode
= GET_MODE (reg
);
13920 cc_regnum
= REGNO (reg
);
13921 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
13923 validate_condition_mode (code
, cc_mode
);
13925 /* When generating a sCOND operation, only positive conditions are
13928 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
13929 || code
== GTU
|| code
== LTU
);
13934 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
13936 return base_bit
+ 2;
13937 case GT
: case GTU
: case UNLE
:
13938 return base_bit
+ 1;
13939 case LT
: case LTU
: case UNGE
:
13941 case ORDERED
: case UNORDERED
:
13942 return base_bit
+ 3;
13945 /* If scc, we will have done a cror to put the bit in the
13946 unordered position. So test that bit. For integer, this is ! LT
13947 unless this is an scc insn. */
13948 return scc_p
? base_bit
+ 3 : base_bit
;
13951 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
13954 gcc_unreachable ();
13958 /* Return the GOT register. */
13961 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
13963 /* The second flow pass currently (June 1999) can't update
13964 regs_ever_live without disturbing other parts of the compiler, so
13965 update it here to make the prolog/epilogue code happy. */
13966 if (!can_create_pseudo_p ()
13967 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
))
13968 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM
, true);
13970 crtl
->uses_pic_offset_table
= 1;
13972 return pic_offset_table_rtx
;
13975 /* Function to init struct machine_function.
13976 This will be called, via a pointer variable,
13977 from push_function_context. */
13979 static struct machine_function
*
13980 rs6000_init_machine_status (void)
13982 return GGC_CNEW (machine_function
);
13985 /* These macros test for integers and extract the low-order bits. */
13987 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
13988 && GET_MODE (X) == VOIDmode)
13990 #define INT_LOWPART(X) \
13991 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
13994 extract_MB (rtx op
)
13997 unsigned long val
= INT_LOWPART (op
);
13999 /* If the high bit is zero, the value is the first 1 bit we find
14001 if ((val
& 0x80000000) == 0)
14003 gcc_assert (val
& 0xffffffff);
14006 while (((val
<<= 1) & 0x80000000) == 0)
14011 /* If the high bit is set and the low bit is not, or the mask is all
14012 1's, the value is zero. */
14013 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
14016 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14019 while (((val
>>= 1) & 1) != 0)
14026 extract_ME (rtx op
)
14029 unsigned long val
= INT_LOWPART (op
);
14031 /* If the low bit is zero, the value is the first 1 bit we find from
14033 if ((val
& 1) == 0)
14035 gcc_assert (val
& 0xffffffff);
14038 while (((val
>>= 1) & 1) == 0)
14044 /* If the low bit is set and the high bit is not, or the mask is all
14045 1's, the value is 31. */
14046 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
14049 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14052 while (((val
<<= 1) & 0x80000000) != 0)
14058 /* Locate some local-dynamic symbol still in use by this function
14059 so that we can print its name in some tls_ld pattern. */
14061 static const char *
14062 rs6000_get_some_local_dynamic_name (void)
14066 if (cfun
->machine
->some_ld_name
)
14067 return cfun
->machine
->some_ld_name
;
14069 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
14071 && for_each_rtx (&PATTERN (insn
),
14072 rs6000_get_some_local_dynamic_name_1
, 0))
14073 return cfun
->machine
->some_ld_name
;
14075 gcc_unreachable ();
14078 /* Helper function for rs6000_get_some_local_dynamic_name. */
14081 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
14085 if (GET_CODE (x
) == SYMBOL_REF
)
14087 const char *str
= XSTR (x
, 0);
14088 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
14090 cfun
->machine
->some_ld_name
= str
;
14098 /* Write out a function code label. */
14101 rs6000_output_function_entry (FILE *file
, const char *fname
)
14103 if (fname
[0] != '.')
14105 switch (DEFAULT_ABI
)
14108 gcc_unreachable ();
14114 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
14123 RS6000_OUTPUT_BASENAME (file
, fname
);
14125 assemble_name (file
, fname
);
14128 /* Print an operand. Recognize special options, documented below. */
14131 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14132 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14134 #define SMALL_DATA_RELOC "sda21"
14135 #define SMALL_DATA_REG 0
14139 print_operand (FILE *file
, rtx x
, int code
)
14143 unsigned HOST_WIDE_INT uval
;
14148 /* Write out an instruction after the call which may be replaced
14149 with glue code by the loader. This depends on the AIX version. */
14150 asm_fprintf (file
, RS6000_CALL_GLUE
);
14153 /* %a is output_address. */
14156 /* If X is a constant integer whose low-order 5 bits are zero,
14157 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14158 in the AIX assembler where "sri" with a zero shift count
14159 writes a trash instruction. */
14160 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
14167 /* If constant, low-order 16 bits of constant, unsigned.
14168 Otherwise, write normally. */
14170 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
14172 print_operand (file
, x
, 0);
14176 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14177 for 64-bit mask direction. */
14178 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
14181 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14185 /* X is a CR register. Print the number of the GT bit of the CR. */
14186 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
14187 output_operand_lossage ("invalid %%c value");
14189 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
14193 /* Like 'J' but get to the GT bit only. */
14194 gcc_assert (GET_CODE (x
) == REG
);
14196 /* Bit 1 is GT bit. */
14197 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 1;
14199 /* Add one for shift count in rlinm for scc. */
14200 fprintf (file
, "%d", i
+ 1);
14204 /* X is a CR register. Print the number of the EQ bit of the CR */
14205 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
14206 output_operand_lossage ("invalid %%E value");
14208 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
14212 /* X is a CR register. Print the shift count needed to move it
14213 to the high-order four bits. */
14214 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
14215 output_operand_lossage ("invalid %%f value");
14217 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
14221 /* Similar, but print the count for the rotate in the opposite
14223 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
14224 output_operand_lossage ("invalid %%F value");
14226 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
14230 /* X is a constant integer. If it is negative, print "m",
14231 otherwise print "z". This is to make an aze or ame insn. */
14232 if (GET_CODE (x
) != CONST_INT
)
14233 output_operand_lossage ("invalid %%G value");
14234 else if (INTVAL (x
) >= 0)
14241 /* If constant, output low-order five bits. Otherwise, write
14244 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
14246 print_operand (file
, x
, 0);
14250 /* If constant, output low-order six bits. Otherwise, write
14253 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
14255 print_operand (file
, x
, 0);
14259 /* Print `i' if this is a constant, else nothing. */
14265 /* Write the bit number in CCR for jump. */
14266 i
= ccr_bit (x
, 0);
14268 output_operand_lossage ("invalid %%j code");
14270 fprintf (file
, "%d", i
);
14274 /* Similar, but add one for shift count in rlinm for scc and pass
14275 scc flag to `ccr_bit'. */
14276 i
= ccr_bit (x
, 1);
14278 output_operand_lossage ("invalid %%J code");
14280 /* If we want bit 31, write a shift count of zero, not 32. */
14281 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
14285 /* X must be a constant. Write the 1's complement of the
14288 output_operand_lossage ("invalid %%k value");
14290 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
14294 /* X must be a symbolic constant on ELF. Write an
14295 expression suitable for an 'addi' that adds in the low 16
14296 bits of the MEM. */
14297 if (GET_CODE (x
) != CONST
)
14299 print_operand_address (file
, x
);
14300 fputs ("@l", file
);
14304 if (GET_CODE (XEXP (x
, 0)) != PLUS
14305 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
14306 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
14307 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
14308 output_operand_lossage ("invalid %%K value");
14309 print_operand_address (file
, XEXP (XEXP (x
, 0), 0));
14310 fputs ("@l", file
);
14311 /* For GNU as, there must be a non-alphanumeric character
14312 between 'l' and the number. The '-' is added by
14313 print_operand() already. */
14314 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
14316 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
14320 /* %l is output_asm_label. */
14323 /* Write second word of DImode or DFmode reference. Works on register
14324 or non-indexed memory only. */
14325 if (GET_CODE (x
) == REG
)
14326 fputs (reg_names
[REGNO (x
) + 1], file
);
14327 else if (GET_CODE (x
) == MEM
)
14329 /* Handle possible auto-increment. Since it is pre-increment and
14330 we have already done it, we can just use an offset of word. */
14331 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
14332 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
14333 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
14335 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
14336 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
14339 output_address (XEXP (adjust_address_nv (x
, SImode
,
14343 if (small_data_operand (x
, GET_MODE (x
)))
14344 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
14345 reg_names
[SMALL_DATA_REG
]);
14350 /* MB value for a mask operand. */
14351 if (! mask_operand (x
, SImode
))
14352 output_operand_lossage ("invalid %%m value");
14354 fprintf (file
, "%d", extract_MB (x
));
14358 /* ME value for a mask operand. */
14359 if (! mask_operand (x
, SImode
))
14360 output_operand_lossage ("invalid %%M value");
14362 fprintf (file
, "%d", extract_ME (x
));
14365 /* %n outputs the negative of its operand. */
14368 /* Write the number of elements in the vector times 4. */
14369 if (GET_CODE (x
) != PARALLEL
)
14370 output_operand_lossage ("invalid %%N value");
14372 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
14376 /* Similar, but subtract 1 first. */
14377 if (GET_CODE (x
) != PARALLEL
)
14378 output_operand_lossage ("invalid %%O value");
14380 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
14384 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14386 || INT_LOWPART (x
) < 0
14387 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
14388 output_operand_lossage ("invalid %%p value");
14390 fprintf (file
, "%d", i
);
14394 /* The operand must be an indirect memory reference. The result
14395 is the register name. */
14396 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
14397 || REGNO (XEXP (x
, 0)) >= 32)
14398 output_operand_lossage ("invalid %%P value");
14400 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
14404 /* This outputs the logical code corresponding to a boolean
14405 expression. The expression may have one or both operands
14406 negated (if one, only the first one). For condition register
14407 logical operations, it will also treat the negated
14408 CR codes as NOTs, but not handle NOTs of them. */
14410 const char *const *t
= 0;
14412 enum rtx_code code
= GET_CODE (x
);
14413 static const char * const tbl
[3][3] = {
14414 { "and", "andc", "nor" },
14415 { "or", "orc", "nand" },
14416 { "xor", "eqv", "xor" } };
14420 else if (code
== IOR
)
14422 else if (code
== XOR
)
14425 output_operand_lossage ("invalid %%q value");
14427 if (GET_CODE (XEXP (x
, 0)) != NOT
)
14431 if (GET_CODE (XEXP (x
, 1)) == NOT
)
14449 /* X is a CR register. Print the mask for `mtcrf'. */
14450 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
14451 output_operand_lossage ("invalid %%R value");
14453 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
14457 /* Low 5 bits of 32 - value */
14459 output_operand_lossage ("invalid %%s value");
14461 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
14465 /* PowerPC64 mask position. All 0's is excluded.
14466 CONST_INT 32-bit mask is considered sign-extended so any
14467 transition must occur within the CONST_INT, not on the boundary. */
14468 if (! mask64_operand (x
, DImode
))
14469 output_operand_lossage ("invalid %%S value");
14471 uval
= INT_LOWPART (x
);
14473 if (uval
& 1) /* Clear Left */
14475 #if HOST_BITS_PER_WIDE_INT > 64
14476 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
14480 else /* Clear Right */
14483 #if HOST_BITS_PER_WIDE_INT > 64
14484 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
14490 gcc_assert (i
>= 0);
14491 fprintf (file
, "%d", i
);
14495 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14496 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
14498 /* Bit 3 is OV bit. */
14499 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
14501 /* If we want bit 31, write a shift count of zero, not 32. */
14502 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
14506 /* Print the symbolic name of a branch target register. */
14507 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LR_REGNO
14508 && REGNO (x
) != CTR_REGNO
))
14509 output_operand_lossage ("invalid %%T value");
14510 else if (REGNO (x
) == LR_REGNO
)
14511 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
14513 fputs ("ctr", file
);
14517 /* High-order 16 bits of constant for use in unsigned operand. */
14519 output_operand_lossage ("invalid %%u value");
14521 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
14522 (INT_LOWPART (x
) >> 16) & 0xffff);
14526 /* High-order 16 bits of constant for use in signed operand. */
14528 output_operand_lossage ("invalid %%v value");
14530 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
14531 (INT_LOWPART (x
) >> 16) & 0xffff);
14535 /* Print `u' if this has an auto-increment or auto-decrement. */
14536 if (GET_CODE (x
) == MEM
14537 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
14538 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
14539 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
))
14544 /* Print the trap code for this operand. */
14545 switch (GET_CODE (x
))
14548 fputs ("eq", file
); /* 4 */
14551 fputs ("ne", file
); /* 24 */
14554 fputs ("lt", file
); /* 16 */
14557 fputs ("le", file
); /* 20 */
14560 fputs ("gt", file
); /* 8 */
14563 fputs ("ge", file
); /* 12 */
14566 fputs ("llt", file
); /* 2 */
14569 fputs ("lle", file
); /* 6 */
14572 fputs ("lgt", file
); /* 1 */
14575 fputs ("lge", file
); /* 5 */
14578 gcc_unreachable ();
14583 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
14586 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
14587 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
14589 print_operand (file
, x
, 0);
14593 /* MB value for a PowerPC64 rldic operand. */
14594 val
= (GET_CODE (x
) == CONST_INT
14595 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
14600 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
14601 if ((val
<<= 1) < 0)
14604 #if HOST_BITS_PER_WIDE_INT == 32
14605 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
14606 i
+= 32; /* zero-extend high-part was all 0's */
14607 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
14609 val
= CONST_DOUBLE_LOW (x
);
14615 for ( ; i
< 64; i
++)
14616 if ((val
<<= 1) < 0)
14621 fprintf (file
, "%d", i
+ 1);
14625 /* X is a FPR or Altivec register used in a VSX context. */
14626 if (GET_CODE (x
) != REG
|| !VSX_REGNO_P (REGNO (x
)))
14627 output_operand_lossage ("invalid %%x value");
14630 int reg
= REGNO (x
);
14631 int vsx_reg
= (FP_REGNO_P (reg
)
14633 : reg
- FIRST_ALTIVEC_REGNO
+ 32);
14635 #ifdef TARGET_REGNAMES
14636 if (TARGET_REGNAMES
)
14637 fprintf (file
, "%%vs%d", vsx_reg
);
14640 fprintf (file
, "%d", vsx_reg
);
14645 if (GET_CODE (x
) == MEM
14646 && (legitimate_indexed_address_p (XEXP (x
, 0), 0)
14647 || (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
14648 && legitimate_indexed_address_p (XEXP (XEXP (x
, 0), 1), 0))))
14653 /* Like 'L', for third word of TImode */
14654 if (GET_CODE (x
) == REG
)
14655 fputs (reg_names
[REGNO (x
) + 2], file
);
14656 else if (GET_CODE (x
) == MEM
)
14658 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
14659 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
14660 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
14661 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
14662 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
14664 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
14665 if (small_data_operand (x
, GET_MODE (x
)))
14666 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
14667 reg_names
[SMALL_DATA_REG
]);
14672 /* X is a SYMBOL_REF. Write out the name preceded by a
14673 period and without any trailing data in brackets. Used for function
14674 names. If we are configured for System V (or the embedded ABI) on
14675 the PowerPC, do not emit the period, since those systems do not use
14676 TOCs and the like. */
14677 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
14679 /* Mark the decl as referenced so that cgraph will output the
14681 if (SYMBOL_REF_DECL (x
))
14682 mark_decl_referenced (SYMBOL_REF_DECL (x
));
14684 /* For macho, check to see if we need a stub. */
14687 const char *name
= XSTR (x
, 0);
14689 if (MACHOPIC_INDIRECT
14690 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
14691 name
= machopic_indirection_name (x
, /*stub_p=*/true);
14693 assemble_name (file
, name
);
14695 else if (!DOT_SYMBOLS
)
14696 assemble_name (file
, XSTR (x
, 0));
14698 rs6000_output_function_entry (file
, XSTR (x
, 0));
14702 /* Like 'L', for last word of TImode. */
14703 if (GET_CODE (x
) == REG
)
14704 fputs (reg_names
[REGNO (x
) + 3], file
);
14705 else if (GET_CODE (x
) == MEM
)
14707 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
14708 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
14709 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
14710 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
14711 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
14713 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
14714 if (small_data_operand (x
, GET_MODE (x
)))
14715 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
14716 reg_names
[SMALL_DATA_REG
]);
14720 /* Print AltiVec or SPE memory operand. */
14725 gcc_assert (GET_CODE (x
) == MEM
);
14729 /* Ugly hack because %y is overloaded. */
14730 if ((TARGET_SPE
|| TARGET_E500_DOUBLE
)
14731 && (GET_MODE_SIZE (GET_MODE (x
)) == 8
14732 || GET_MODE (x
) == TFmode
14733 || GET_MODE (x
) == TImode
))
14735 /* Handle [reg]. */
14736 if (GET_CODE (tmp
) == REG
)
14738 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
14741 /* Handle [reg+UIMM]. */
14742 else if (GET_CODE (tmp
) == PLUS
&&
14743 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
14747 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
14749 x
= INTVAL (XEXP (tmp
, 1));
14750 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
14754 /* Fall through. Must be [reg+reg]. */
14756 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x
))
14757 && GET_CODE (tmp
) == AND
14758 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
14759 && INTVAL (XEXP (tmp
, 1)) == -16)
14760 tmp
= XEXP (tmp
, 0);
14761 else if (VECTOR_MEM_VSX_P (GET_MODE (x
))
14762 && GET_CODE (tmp
) == PRE_MODIFY
)
14763 tmp
= XEXP (tmp
, 1);
14764 if (GET_CODE (tmp
) == REG
)
14765 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
14768 if (!GET_CODE (tmp
) == PLUS
14769 || !REG_P (XEXP (tmp
, 0))
14770 || !REG_P (XEXP (tmp
, 1)))
14772 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
14776 if (REGNO (XEXP (tmp
, 0)) == 0)
14777 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
14778 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
14780 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
14781 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
14787 if (GET_CODE (x
) == REG
)
14788 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
14789 else if (GET_CODE (x
) == MEM
)
14791 /* We need to handle PRE_INC and PRE_DEC here, since we need to
14792 know the width from the mode. */
14793 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
14794 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
14795 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
14796 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
14797 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
14798 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
14799 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
14800 output_address (XEXP (XEXP (x
, 0), 1));
14802 output_address (XEXP (x
, 0));
14805 output_addr_const (file
, x
);
14809 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
14813 output_operand_lossage ("invalid %%xn code");
14817 /* Print the address of an operand. */
14820 print_operand_address (FILE *file
, rtx x
)
14822 if (GET_CODE (x
) == REG
)
14823 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
14824 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
14825 || GET_CODE (x
) == LABEL_REF
)
14827 output_addr_const (file
, x
);
14828 if (small_data_operand (x
, GET_MODE (x
)))
14829 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
14830 reg_names
[SMALL_DATA_REG
]);
14832 gcc_assert (!TARGET_TOC
);
14834 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
14836 gcc_assert (REG_P (XEXP (x
, 0)));
14837 if (REGNO (XEXP (x
, 0)) == 0)
14838 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
14839 reg_names
[ REGNO (XEXP (x
, 0)) ]);
14841 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
14842 reg_names
[ REGNO (XEXP (x
, 1)) ]);
14844 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
14845 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
14846 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
14848 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
14849 && CONSTANT_P (XEXP (x
, 1)))
14851 output_addr_const (file
, XEXP (x
, 1));
14852 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
14856 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
14857 && CONSTANT_P (XEXP (x
, 1)))
14859 fprintf (file
, "lo16(");
14860 output_addr_const (file
, XEXP (x
, 1));
14861 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
14864 else if (legitimate_constant_pool_address_p (x
))
14866 output_addr_const (file
, XEXP (x
, 1));
14867 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
14870 gcc_unreachable ();
14873 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
14876 rs6000_output_addr_const_extra (FILE *file
, rtx x
)
14878 if (GET_CODE (x
) == UNSPEC
)
14879 switch (XINT (x
, 1))
14881 case UNSPEC_TOCREL
:
14882 x
= XVECEXP (x
, 0, 0);
14883 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
14884 output_addr_const (file
, x
);
14885 if (!TARGET_AIX
|| (TARGET_ELF
&& TARGET_MINIMAL_TOC
))
14888 assemble_name (file
, toc_label_name
);
14890 else if (TARGET_ELF
)
14891 fputs ("@toc", file
);
14895 case UNSPEC_MACHOPIC_OFFSET
:
14896 output_addr_const (file
, XVECEXP (x
, 0, 0));
14898 machopic_output_function_base_name (file
);
14905 /* Target hook for assembling integer objects. The PowerPC version has
14906 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
14907 is defined. It also needs to handle DI-mode objects on 64-bit
14911 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
14913 #ifdef RELOCATABLE_NEEDS_FIXUP
14914 /* Special handling for SI values. */
14915 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
14917 static int recurse
= 0;
14919 /* For -mrelocatable, we mark all addresses that need to be fixed up
14920 in the .fixup section. */
14921 if (TARGET_RELOCATABLE
14922 && in_section
!= toc_section
14923 && in_section
!= text_section
14924 && !unlikely_text_section_p (in_section
)
14926 && GET_CODE (x
) != CONST_INT
14927 && GET_CODE (x
) != CONST_DOUBLE
14933 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
14935 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
14936 fprintf (asm_out_file
, "\t.long\t(");
14937 output_addr_const (asm_out_file
, x
);
14938 fprintf (asm_out_file
, ")@fixup\n");
14939 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
14940 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
14941 fprintf (asm_out_file
, "\t.long\t");
14942 assemble_name (asm_out_file
, buf
);
14943 fprintf (asm_out_file
, "\n\t.previous\n");
14947 /* Remove initial .'s to turn a -mcall-aixdesc function
14948 address into the address of the descriptor, not the function
14950 else if (GET_CODE (x
) == SYMBOL_REF
14951 && XSTR (x
, 0)[0] == '.'
14952 && DEFAULT_ABI
== ABI_AIX
)
14954 const char *name
= XSTR (x
, 0);
14955 while (*name
== '.')
14958 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
14962 #endif /* RELOCATABLE_NEEDS_FIXUP */
14963 return default_assemble_integer (x
, size
, aligned_p
);
14966 #ifdef HAVE_GAS_HIDDEN
14967 /* Emit an assembler directive to set symbol visibility for DECL to
14968 VISIBILITY_TYPE. */
14971 rs6000_assemble_visibility (tree decl
, int vis
)
14973 /* Functions need to have their entry point symbol visibility set as
14974 well as their descriptor symbol visibility. */
14975 if (DEFAULT_ABI
== ABI_AIX
14977 && TREE_CODE (decl
) == FUNCTION_DECL
)
14979 static const char * const visibility_types
[] = {
14980 NULL
, "internal", "hidden", "protected"
14983 const char *name
, *type
;
14985 name
= ((* targetm
.strip_name_encoding
)
14986 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
14987 type
= visibility_types
[vis
];
14989 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
14990 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
14993 default_assemble_visibility (decl
, vis
);
14998 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
15000 /* Reversal of FP compares takes care -- an ordered compare
15001 becomes an unordered compare and vice versa. */
15002 if (mode
== CCFPmode
15003 && (!flag_finite_math_only
15004 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
15005 || code
== UNEQ
|| code
== LTGT
))
15006 return reverse_condition_maybe_unordered (code
);
15008 return reverse_condition (code
);
15011 /* Generate a compare for CODE. Return a brand-new rtx that
15012 represents the result of the compare. */
15015 rs6000_generate_compare (rtx cmp
, enum machine_mode mode
)
15017 enum machine_mode comp_mode
;
15018 rtx compare_result
;
15019 enum rtx_code code
= GET_CODE (cmp
);
15020 rtx op0
= XEXP (cmp
, 0);
15021 rtx op1
= XEXP (cmp
, 1);
15023 if (FLOAT_MODE_P (mode
))
15024 comp_mode
= CCFPmode
;
15025 else if (code
== GTU
|| code
== LTU
15026 || code
== GEU
|| code
== LEU
)
15027 comp_mode
= CCUNSmode
;
15028 else if ((code
== EQ
|| code
== NE
)
15029 && GET_CODE (op0
) == SUBREG
15030 && GET_CODE (op1
) == SUBREG
15031 && SUBREG_PROMOTED_UNSIGNED_P (op0
)
15032 && SUBREG_PROMOTED_UNSIGNED_P (op1
))
15033 /* These are unsigned values, perhaps there will be a later
15034 ordering compare that can be shared with this one.
15035 Unfortunately we cannot detect the signedness of the operands
15036 for non-subregs. */
15037 comp_mode
= CCUNSmode
;
15039 comp_mode
= CCmode
;
15041 /* First, the compare. */
15042 compare_result
= gen_reg_rtx (comp_mode
);
15044 /* E500 FP compare instructions on the GPRs. Yuck! */
15045 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
)
15046 && FLOAT_MODE_P (mode
))
15048 rtx cmp
, or_result
, compare_result2
;
15049 enum machine_mode op_mode
= GET_MODE (op0
);
15051 if (op_mode
== VOIDmode
)
15052 op_mode
= GET_MODE (op1
);
15054 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15055 This explains the following mess. */
15059 case EQ
: case UNEQ
: case NE
: case LTGT
:
15063 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
15064 ? gen_tstsfeq_gpr (compare_result
, op0
, op1
)
15065 : gen_cmpsfeq_gpr (compare_result
, op0
, op1
);
15069 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
15070 ? gen_tstdfeq_gpr (compare_result
, op0
, op1
)
15071 : gen_cmpdfeq_gpr (compare_result
, op0
, op1
);
15075 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
15076 ? gen_tsttfeq_gpr (compare_result
, op0
, op1
)
15077 : gen_cmptfeq_gpr (compare_result
, op0
, op1
);
15081 gcc_unreachable ();
15085 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
15089 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
15090 ? gen_tstsfgt_gpr (compare_result
, op0
, op1
)
15091 : gen_cmpsfgt_gpr (compare_result
, op0
, op1
);
15095 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
15096 ? gen_tstdfgt_gpr (compare_result
, op0
, op1
)
15097 : gen_cmpdfgt_gpr (compare_result
, op0
, op1
);
15101 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
15102 ? gen_tsttfgt_gpr (compare_result
, op0
, op1
)
15103 : gen_cmptfgt_gpr (compare_result
, op0
, op1
);
15107 gcc_unreachable ();
15111 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
15115 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
15116 ? gen_tstsflt_gpr (compare_result
, op0
, op1
)
15117 : gen_cmpsflt_gpr (compare_result
, op0
, op1
);
15121 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
15122 ? gen_tstdflt_gpr (compare_result
, op0
, op1
)
15123 : gen_cmpdflt_gpr (compare_result
, op0
, op1
);
15127 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
15128 ? gen_tsttflt_gpr (compare_result
, op0
, op1
)
15129 : gen_cmptflt_gpr (compare_result
, op0
, op1
);
15133 gcc_unreachable ();
15137 gcc_unreachable ();
15140 /* Synthesize LE and GE from LT/GT || EQ. */
15141 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
15147 case LE
: code
= LT
; break;
15148 case GE
: code
= GT
; break;
15149 case LEU
: code
= LT
; break;
15150 case GEU
: code
= GT
; break;
15151 default: gcc_unreachable ();
15154 compare_result2
= gen_reg_rtx (CCFPmode
);
15160 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
15161 ? gen_tstsfeq_gpr (compare_result2
, op0
, op1
)
15162 : gen_cmpsfeq_gpr (compare_result2
, op0
, op1
);
15166 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
15167 ? gen_tstdfeq_gpr (compare_result2
, op0
, op1
)
15168 : gen_cmpdfeq_gpr (compare_result2
, op0
, op1
);
15172 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
15173 ? gen_tsttfeq_gpr (compare_result2
, op0
, op1
)
15174 : gen_cmptfeq_gpr (compare_result2
, op0
, op1
);
15178 gcc_unreachable ();
15182 /* OR them together. */
15183 or_result
= gen_reg_rtx (CCFPmode
);
15184 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
15186 compare_result
= or_result
;
15191 if (code
== NE
|| code
== LTGT
)
15201 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15202 CLOBBERs to match cmptf_internal2 pattern. */
15203 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
15204 && GET_MODE (op0
) == TFmode
15205 && !TARGET_IEEEQUAD
15206 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
15207 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
15209 gen_rtx_SET (VOIDmode
,
15211 gen_rtx_COMPARE (comp_mode
, op0
, op1
)),
15212 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
15213 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
15214 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
15215 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
15216 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
15217 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
15218 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
15219 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)))));
15220 else if (GET_CODE (op1
) == UNSPEC
15221 && XINT (op1
, 1) == UNSPEC_SP_TEST
)
15223 rtx op1b
= XVECEXP (op1
, 0, 0);
15224 comp_mode
= CCEQmode
;
15225 compare_result
= gen_reg_rtx (CCEQmode
);
15227 emit_insn (gen_stack_protect_testdi (compare_result
, op0
, op1b
));
15229 emit_insn (gen_stack_protect_testsi (compare_result
, op0
, op1b
));
15232 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
15233 gen_rtx_COMPARE (comp_mode
, op0
, op1
)));
15236 /* Some kinds of FP comparisons need an OR operation;
15237 under flag_finite_math_only we don't bother. */
15238 if (FLOAT_MODE_P (mode
)
15239 && !flag_finite_math_only
15240 && !(TARGET_HARD_FLOAT
&& !TARGET_FPRS
)
15241 && (code
== LE
|| code
== GE
15242 || code
== UNEQ
|| code
== LTGT
15243 || code
== UNGT
|| code
== UNLT
))
15245 enum rtx_code or1
, or2
;
15246 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
15247 rtx or_result
= gen_reg_rtx (CCEQmode
);
15251 case LE
: or1
= LT
; or2
= EQ
; break;
15252 case GE
: or1
= GT
; or2
= EQ
; break;
15253 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
15254 case LTGT
: or1
= LT
; or2
= GT
; break;
15255 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
15256 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
15257 default: gcc_unreachable ();
15259 validate_condition_mode (or1
, comp_mode
);
15260 validate_condition_mode (or2
, comp_mode
);
15261 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
15262 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
15263 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
15264 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
15266 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
15268 compare_result
= or_result
;
15272 validate_condition_mode (code
, GET_MODE (compare_result
));
15274 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
15278 /* Emit the RTL for an sCOND pattern. */
15281 rs6000_emit_sCOND (enum machine_mode mode
, rtx operands
[])
15284 enum machine_mode op_mode
;
15285 enum rtx_code cond_code
;
15286 rtx result
= operands
[0];
15288 condition_rtx
= rs6000_generate_compare (operands
[1], mode
);
15289 cond_code
= GET_CODE (condition_rtx
);
15291 if (FLOAT_MODE_P (mode
)
15292 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
15296 PUT_MODE (condition_rtx
, SImode
);
15297 t
= XEXP (condition_rtx
, 0);
15299 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
15301 if (cond_code
== NE
)
15302 emit_insn (gen_e500_flip_gt_bit (t
, t
));
15304 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
15308 if (cond_code
== NE
15309 || cond_code
== GE
|| cond_code
== LE
15310 || cond_code
== GEU
|| cond_code
== LEU
15311 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
15313 rtx not_result
= gen_reg_rtx (CCEQmode
);
15314 rtx not_op
, rev_cond_rtx
;
15315 enum machine_mode cc_mode
;
15317 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
15319 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
15320 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
15321 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
15322 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
15323 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
15326 op_mode
= GET_MODE (XEXP (operands
[1], 0));
15327 if (op_mode
== VOIDmode
)
15328 op_mode
= GET_MODE (XEXP (operands
[1], 1));
15330 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| FLOAT_MODE_P (mode
)))
15332 PUT_MODE (condition_rtx
, DImode
);
15333 convert_move (result
, condition_rtx
, 0);
15337 PUT_MODE (condition_rtx
, SImode
);
15338 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
15342 /* Emit a branch of kind CODE to location LOC. */
15345 rs6000_emit_cbranch (enum machine_mode mode
, rtx operands
[])
15347 rtx condition_rtx
, loc_ref
;
15349 condition_rtx
= rs6000_generate_compare (operands
[0], mode
);
15350 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
15351 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
15352 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
15353 loc_ref
, pc_rtx
)));
15356 /* Return the string to output a conditional branch to LABEL, which is
15357 the operand number of the label, or -1 if the branch is really a
15358 conditional return.
15360 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15361 condition code register and its mode specifies what kind of
15362 comparison we made.
15364 REVERSED is nonzero if we should reverse the sense of the comparison.
15366 INSN is the insn. */
15369 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
15371 static char string
[64];
15372 enum rtx_code code
= GET_CODE (op
);
15373 rtx cc_reg
= XEXP (op
, 0);
15374 enum machine_mode mode
= GET_MODE (cc_reg
);
15375 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
15376 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
15377 int really_reversed
= reversed
^ need_longbranch
;
15383 validate_condition_mode (code
, mode
);
15385 /* Work out which way this really branches. We could use
15386 reverse_condition_maybe_unordered here always but this
15387 makes the resulting assembler clearer. */
15388 if (really_reversed
)
15390 /* Reversal of FP compares takes care -- an ordered compare
15391 becomes an unordered compare and vice versa. */
15392 if (mode
== CCFPmode
)
15393 code
= reverse_condition_maybe_unordered (code
);
15395 code
= reverse_condition (code
);
15398 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
15400 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15405 /* Opposite of GT. */
15414 gcc_unreachable ();
15420 /* Not all of these are actually distinct opcodes, but
15421 we distinguish them for clarity of the resulting assembler. */
15422 case NE
: case LTGT
:
15423 ccode
= "ne"; break;
15424 case EQ
: case UNEQ
:
15425 ccode
= "eq"; break;
15427 ccode
= "ge"; break;
15428 case GT
: case GTU
: case UNGT
:
15429 ccode
= "gt"; break;
15431 ccode
= "le"; break;
15432 case LT
: case LTU
: case UNLT
:
15433 ccode
= "lt"; break;
15434 case UNORDERED
: ccode
= "un"; break;
15435 case ORDERED
: ccode
= "nu"; break;
15436 case UNGE
: ccode
= "nl"; break;
15437 case UNLE
: ccode
= "ng"; break;
15439 gcc_unreachable ();
15442 /* Maybe we have a guess as to how likely the branch is.
15443 The old mnemonics don't have a way to specify this information. */
15445 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
15446 if (note
!= NULL_RTX
)
15448 /* PROB is the difference from 50%. */
15449 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
15451 /* Only hint for highly probable/improbable branches on newer
15452 cpus as static prediction overrides processor dynamic
15453 prediction. For older cpus we may as well always hint, but
15454 assume not taken for branches that are very close to 50% as a
15455 mispredicted taken branch is more expensive than a
15456 mispredicted not-taken branch. */
15457 if (rs6000_always_hint
15458 || (abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48
15459 && br_prob_note_reliable_p (note
)))
15461 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
15462 && ((prob
> 0) ^ need_longbranch
))
15470 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
15472 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
15474 /* We need to escape any '%' characters in the reg_names string.
15475 Assume they'd only be the first character.... */
15476 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
15478 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
15482 /* If the branch distance was too far, we may have to use an
15483 unconditional branch to go the distance. */
15484 if (need_longbranch
)
15485 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
15487 s
+= sprintf (s
, ",%s", label
);
15493 /* Return the string to flip the GT bit on a CR. */
15495 output_e500_flip_gt_bit (rtx dst
, rtx src
)
15497 static char string
[64];
15500 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
15501 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
15504 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
15505 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
15507 sprintf (string
, "crnot %d,%d", a
, b
);
15511 /* Return insn for VSX or Altivec comparisons. */
15514 rs6000_emit_vector_compare_inner (enum rtx_code code
, rtx op0
, rtx op1
)
15517 enum machine_mode mode
= GET_MODE (op0
);
15525 if (GET_MODE_CLASS (mode
) == MODE_VECTOR_INT
)
15531 mask
= gen_reg_rtx (mode
);
15532 emit_insn (gen_rtx_SET (VOIDmode
,
15534 gen_rtx_fmt_ee (code
, mode
, op0
, op1
)));
15541 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
15542 DMODE is expected destination mode. This is a recursive function. */
15545 rs6000_emit_vector_compare (enum rtx_code rcode
,
15547 enum machine_mode dmode
)
15550 bool swap_operands
= false;
15551 bool try_again
= false;
15553 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode
));
15554 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
15556 /* See if the comparison works as is. */
15557 mask
= rs6000_emit_vector_compare_inner (rcode
, op0
, op1
);
15565 swap_operands
= true;
15570 swap_operands
= true;
15578 /* Invert condition and try again.
15579 e.g., A != B becomes ~(A==B). */
15581 enum rtx_code rev_code
;
15582 enum insn_code nor_code
;
15585 rev_code
= reverse_condition_maybe_unordered (rcode
);
15586 if (rev_code
== UNKNOWN
)
15589 nor_code
= optab_handler (one_cmpl_optab
, (int)dmode
)->insn_code
;
15590 if (nor_code
== CODE_FOR_nothing
)
15593 mask2
= rs6000_emit_vector_compare (rev_code
, op0
, op1
, dmode
);
15597 mask
= gen_reg_rtx (dmode
);
15598 emit_insn (GEN_FCN (nor_code
) (mask
, mask2
));
15606 /* Try GT/GTU/LT/LTU OR EQ */
15609 enum insn_code ior_code
;
15610 enum rtx_code new_code
;
15631 gcc_unreachable ();
15634 ior_code
= optab_handler (ior_optab
, (int)dmode
)->insn_code
;
15635 if (ior_code
== CODE_FOR_nothing
)
15638 c_rtx
= rs6000_emit_vector_compare (new_code
, op0
, op1
, dmode
);
15642 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
, dmode
);
15646 mask
= gen_reg_rtx (dmode
);
15647 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
15665 mask
= rs6000_emit_vector_compare_inner (rcode
, op0
, op1
);
15670 /* You only get two chances. */
15674 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
15675 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
15676 operands for the relation operation COND. */
15679 rs6000_emit_vector_cond_expr (rtx dest
, rtx op_true
, rtx op_false
,
15680 rtx cond
, rtx cc_op0
, rtx cc_op1
)
15682 enum machine_mode dest_mode
= GET_MODE (dest
);
15683 enum rtx_code rcode
= GET_CODE (cond
);
15684 enum machine_mode cc_mode
= CCmode
;
15688 bool invert_move
= false;
15690 if (VECTOR_UNIT_NONE_P (dest_mode
))
15695 /* Swap operands if we can, and fall back to doing the operation as
15696 specified, and doing a NOR to invert the test. */
15702 /* Invert condition and try again.
15703 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
15704 invert_move
= true;
15705 rcode
= reverse_condition_maybe_unordered (rcode
);
15706 if (rcode
== UNKNOWN
)
15710 /* Mark unsigned tests with CCUNSmode. */
15715 cc_mode
= CCUNSmode
;
15722 /* Get the vector mask for the given relational operations. */
15723 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
15731 op_true
= op_false
;
15735 cond2
= gen_rtx_fmt_ee (NE
, cc_mode
, mask
, const0_rtx
);
15736 emit_insn (gen_rtx_SET (VOIDmode
,
15738 gen_rtx_IF_THEN_ELSE (dest_mode
,
15745 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
15746 operands of the last comparison is nonzero/true, FALSE_COND if it
15747 is zero/false. Return 0 if the hardware has no such operation. */
15750 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
15752 enum rtx_code code
= GET_CODE (op
);
15753 rtx op0
= XEXP (op
, 0);
15754 rtx op1
= XEXP (op
, 1);
15755 REAL_VALUE_TYPE c1
;
15756 enum machine_mode compare_mode
= GET_MODE (op0
);
15757 enum machine_mode result_mode
= GET_MODE (dest
);
15759 bool is_against_zero
;
15761 /* These modes should always match. */
15762 if (GET_MODE (op1
) != compare_mode
15763 /* In the isel case however, we can use a compare immediate, so
15764 op1 may be a small constant. */
15765 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
15767 if (GET_MODE (true_cond
) != result_mode
)
15769 if (GET_MODE (false_cond
) != result_mode
)
15772 /* First, work out if the hardware can do this at all, or
15773 if it's too slow.... */
15774 if (!FLOAT_MODE_P (compare_mode
))
15777 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
15780 else if (TARGET_HARD_FLOAT
&& !TARGET_FPRS
15781 && SCALAR_FLOAT_MODE_P (compare_mode
))
15784 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
15786 /* A floating-point subtract might overflow, underflow, or produce
15787 an inexact result, thus changing the floating-point flags, so it
15788 can't be generated if we care about that. It's safe if one side
15789 of the construct is zero, since then no subtract will be
15791 if (SCALAR_FLOAT_MODE_P (compare_mode
)
15792 && flag_trapping_math
&& ! is_against_zero
)
15795 /* Eliminate half of the comparisons by switching operands, this
15796 makes the remaining code simpler. */
15797 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
15798 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
15800 code
= reverse_condition_maybe_unordered (code
);
15802 true_cond
= false_cond
;
15806 /* UNEQ and LTGT take four instructions for a comparison with zero,
15807 it'll probably be faster to use a branch here too. */
15808 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
15811 if (GET_CODE (op1
) == CONST_DOUBLE
)
15812 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
15814 /* We're going to try to implement comparisons by performing
15815 a subtract, then comparing against zero. Unfortunately,
15816 Inf - Inf is NaN which is not zero, and so if we don't
15817 know that the operand is finite and the comparison
15818 would treat EQ different to UNORDERED, we can't do it. */
15819 if (HONOR_INFINITIES (compare_mode
)
15820 && code
!= GT
&& code
!= UNGE
15821 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
15822 /* Constructs of the form (a OP b ? a : b) are safe. */
15823 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
15824 || (! rtx_equal_p (op0
, true_cond
)
15825 && ! rtx_equal_p (op1
, true_cond
))))
15828 /* At this point we know we can use fsel. */
15830 /* Reduce the comparison to a comparison against zero. */
15831 if (! is_against_zero
)
15833 temp
= gen_reg_rtx (compare_mode
);
15834 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
15835 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
15837 op1
= CONST0_RTX (compare_mode
);
15840 /* If we don't care about NaNs we can reduce some of the comparisons
15841 down to faster ones. */
15842 if (! HONOR_NANS (compare_mode
))
15848 true_cond
= false_cond
;
15861 /* Now, reduce everything down to a GE. */
15868 temp
= gen_reg_rtx (compare_mode
);
15869 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
15874 temp
= gen_reg_rtx (compare_mode
);
15875 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
15880 temp
= gen_reg_rtx (compare_mode
);
15881 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
15882 gen_rtx_NEG (compare_mode
,
15883 gen_rtx_ABS (compare_mode
, op0
))));
15888 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
15889 temp
= gen_reg_rtx (result_mode
);
15890 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
15891 gen_rtx_IF_THEN_ELSE (result_mode
,
15892 gen_rtx_GE (VOIDmode
,
15894 true_cond
, false_cond
)));
15895 false_cond
= true_cond
;
15898 temp
= gen_reg_rtx (compare_mode
);
15899 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
15904 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
15905 temp
= gen_reg_rtx (result_mode
);
15906 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
15907 gen_rtx_IF_THEN_ELSE (result_mode
,
15908 gen_rtx_GE (VOIDmode
,
15910 true_cond
, false_cond
)));
15911 true_cond
= false_cond
;
15914 temp
= gen_reg_rtx (compare_mode
);
15915 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
15920 gcc_unreachable ();
15923 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
15924 gen_rtx_IF_THEN_ELSE (result_mode
,
15925 gen_rtx_GE (VOIDmode
,
15927 true_cond
, false_cond
)));
15931 /* Same as above, but for ints (isel). */
15934 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
15936 rtx condition_rtx
, cr
;
15937 enum machine_mode mode
= GET_MODE (XEXP (op
, 0));
15939 if (mode
!= SImode
&& (!TARGET_POWERPC64
|| mode
!= DImode
))
15942 /* We still have to do the compare, because isel doesn't do a
15943 compare, it just looks at the CRx bits set by a previous compare
15945 condition_rtx
= rs6000_generate_compare (op
, SImode
);
15946 cr
= XEXP (condition_rtx
, 0);
15948 if (mode
== SImode
)
15950 if (GET_MODE (cr
) == CCmode
)
15951 emit_insn (gen_isel_signed_si (dest
, condition_rtx
,
15952 true_cond
, false_cond
, cr
));
15954 emit_insn (gen_isel_unsigned_si (dest
, condition_rtx
,
15955 true_cond
, false_cond
, cr
));
15959 if (GET_MODE (cr
) == CCmode
)
15960 emit_insn (gen_isel_signed_di (dest
, condition_rtx
,
15961 true_cond
, false_cond
, cr
));
15963 emit_insn (gen_isel_unsigned_di (dest
, condition_rtx
,
15964 true_cond
, false_cond
, cr
));
15971 output_isel (rtx
*operands
)
15973 enum rtx_code code
;
15975 code
= GET_CODE (operands
[1]);
15976 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
15978 PUT_CODE (operands
[1], reverse_condition (code
));
15979 return "isel %0,%3,%2,%j1";
15982 return "isel %0,%2,%3,%j1";
15986 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
15988 enum machine_mode mode
= GET_MODE (op0
);
15992 /* VSX/altivec have direct min/max insns. */
15993 if ((code
== SMAX
|| code
== SMIN
) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode
))
15995 emit_insn (gen_rtx_SET (VOIDmode
,
15997 gen_rtx_fmt_ee (code
, mode
, op0
, op1
)));
16001 if (code
== SMAX
|| code
== SMIN
)
16006 if (code
== SMAX
|| code
== UMAX
)
16007 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
16008 op0
, op1
, mode
, 0);
16010 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
16011 op1
, op0
, mode
, 0);
16012 gcc_assert (target
);
16013 if (target
!= dest
)
16014 emit_move_insn (dest
, target
);
16017 /* Emit instructions to perform a load-reserved/store-conditional operation.
16018 The operation performed is an atomic
16019 (set M (CODE:MODE M OP))
16020 If not NULL, BEFORE is atomically set to M before the operation, and
16021 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16022 If SYNC_P then a memory barrier is emitted before the operation.
16023 Either OP or M may be wrapped in a NOT operation. */
16026 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
16027 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
16030 enum machine_mode used_mode
;
16031 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
16034 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
16035 rtx shift
= NULL_RTX
;
16038 emit_insn (gen_lwsync ());
16042 /* If this is smaller than SImode, we'll have to use SImode with
16044 if (mode
== QImode
|| mode
== HImode
)
16048 if (MEM_ALIGN (used_m
) >= 32)
16051 if (BYTES_BIG_ENDIAN
)
16052 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
16054 shift
= GEN_INT (ishift
);
16055 used_m
= change_address (used_m
, SImode
, 0);
16059 rtx addrSI
, aligned_addr
;
16060 int shift_mask
= mode
== QImode
? 0x18 : 0x10;
16062 addrSI
= gen_lowpart_common (SImode
,
16063 force_reg (Pmode
, XEXP (used_m
, 0)));
16064 addrSI
= force_reg (SImode
, addrSI
);
16065 shift
= gen_reg_rtx (SImode
);
16067 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
16068 GEN_INT (shift_mask
)));
16069 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
16071 aligned_addr
= expand_binop (Pmode
, and_optab
,
16073 GEN_INT (-4), NULL_RTX
,
16074 1, OPTAB_LIB_WIDEN
);
16075 used_m
= change_address (used_m
, SImode
, aligned_addr
);
16076 set_mem_align (used_m
, 32);
16078 /* It's safe to keep the old alias set of USED_M, because
16079 the operation is atomic and only affects the original
16083 if (GET_CODE (op
) == NOT
)
16085 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
16086 oldop
= gen_rtx_NOT (SImode
, oldop
);
16089 oldop
= lowpart_subreg (SImode
, op
, mode
);
16095 newop
= expand_binop (SImode
, and_optab
,
16096 oldop
, GEN_INT (imask
), NULL_RTX
,
16097 1, OPTAB_LIB_WIDEN
);
16098 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
16101 case NOT
: /* NAND */
16102 newop
= expand_binop (SImode
, ior_optab
,
16103 oldop
, GEN_INT (~imask
), NULL_RTX
,
16104 1, OPTAB_LIB_WIDEN
);
16105 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
16109 newop
= expand_binop (SImode
, ior_optab
,
16110 oldop
, GEN_INT (~imask
), NULL_RTX
,
16111 1, OPTAB_LIB_WIDEN
);
16112 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
16120 newop
= expand_binop (SImode
, and_optab
,
16121 oldop
, GEN_INT (imask
), NULL_RTX
,
16122 1, OPTAB_LIB_WIDEN
);
16123 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
16125 mask
= gen_reg_rtx (SImode
);
16126 emit_move_insn (mask
, GEN_INT (imask
));
16127 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
16130 newop
= gen_rtx_PLUS (SImode
, m
, newop
);
16132 newop
= gen_rtx_MINUS (SImode
, m
, newop
);
16133 newop
= gen_rtx_AND (SImode
, newop
, mask
);
16134 newop
= gen_rtx_IOR (SImode
, newop
,
16135 gen_rtx_AND (SImode
,
16136 gen_rtx_NOT (SImode
, mask
),
16142 gcc_unreachable ();
16146 used_mode
= SImode
;
16147 before
= gen_reg_rtx (used_mode
);
16148 after
= gen_reg_rtx (used_mode
);
16153 before
= before_param
;
16154 after
= after_param
;
16156 if (before
== NULL_RTX
)
16157 before
= gen_reg_rtx (used_mode
);
16158 if (after
== NULL_RTX
)
16159 after
= gen_reg_rtx (used_mode
);
16162 if ((code
== PLUS
|| code
== MINUS
)
16163 && used_mode
!= mode
)
16164 the_op
= op
; /* Computed above. */
16165 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
16166 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
16167 else if (code
== NOT
)
16168 the_op
= gen_rtx_fmt_ee (IOR
, used_mode
,
16169 gen_rtx_NOT (used_mode
, m
),
16170 gen_rtx_NOT (used_mode
, op
));
16172 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
16174 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
16175 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
16176 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
16177 gen_rtx_UNSPEC (used_mode
,
16178 gen_rtvec (1, the_op
),
16180 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
16182 if ((code
== PLUS
|| code
== MINUS
) && used_mode
!= mode
)
16183 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
16184 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
16186 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
16187 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
16189 /* Shift and mask the return values properly. */
16190 if (used_mode
!= mode
&& before_param
)
16192 emit_insn (gen_lshrsi3 (before
, before
, shift
));
16193 convert_move (before_param
, before
, 1);
16196 if (used_mode
!= mode
&& after_param
)
16198 emit_insn (gen_lshrsi3 (after
, after
, shift
));
16199 convert_move (after_param
, after
, 1);
16202 /* The previous sequence will end with a branch that's dependent on
16203 the conditional store, so placing an isync will ensure that no
16204 other instructions (especially, no load or store instructions)
16205 can start before the atomic operation completes. */
16207 emit_insn (gen_isync ());
16210 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16211 COND is true. Mark the jump as unlikely to be taken. */
16214 emit_unlikely_jump (rtx cond
, rtx label
)
16216 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
16219 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
16220 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
16221 add_reg_note (x
, REG_BR_PROB
, very_unlikely
);
16224 /* A subroutine of the atomic operation splitters. Emit a load-locked
16225 instruction in MODE. */
16228 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
16230 rtx (*fn
) (rtx
, rtx
) = NULL
;
16231 if (mode
== SImode
)
16232 fn
= gen_load_locked_si
;
16233 else if (mode
== DImode
)
16234 fn
= gen_load_locked_di
;
16235 emit_insn (fn (reg
, mem
));
16238 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16239 instruction in MODE. */
16242 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
16244 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
16245 if (mode
== SImode
)
16246 fn
= gen_store_conditional_si
;
16247 else if (mode
== DImode
)
16248 fn
= gen_store_conditional_di
;
16250 /* Emit sync before stwcx. to address PPC405 Erratum. */
16251 if (PPC405_ERRATUM77
)
16252 emit_insn (gen_memory_barrier ());
16254 emit_insn (fn (res
, mem
, val
));
16257 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16258 to perform. MEM is the memory on which to operate. VAL is the second
16259 operand of the binary operator. BEFORE and AFTER are optional locations to
16260 return the value of MEM either before of after the operation. SCRATCH is
16261 a scratch register. */
16264 rs6000_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
16265 rtx before
, rtx after
, rtx scratch
)
16267 enum machine_mode mode
= GET_MODE (mem
);
16268 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
16270 emit_insn (gen_lwsync ());
16272 label
= gen_label_rtx ();
16273 emit_label (label
);
16274 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
16276 if (before
== NULL_RTX
)
16278 emit_load_locked (mode
, before
, mem
);
16281 x
= gen_rtx_IOR (mode
,
16282 gen_rtx_NOT (mode
, before
),
16283 gen_rtx_NOT (mode
, val
));
16284 else if (code
== AND
)
16285 x
= gen_rtx_UNSPEC (mode
, gen_rtvec (2, before
, val
), UNSPEC_AND
);
16287 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
16289 if (after
!= NULL_RTX
)
16290 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
16291 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
16293 emit_store_conditional (mode
, cond
, mem
, scratch
);
16295 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
16296 emit_unlikely_jump (x
, label
);
16298 emit_insn (gen_isync ());
16301 /* Expand an atomic compare and swap operation. MEM is the memory on which
16302 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16303 value to be stored. SCRATCH is a scratch GPR. */
16306 rs6000_split_compare_and_swap (rtx retval
, rtx mem
, rtx oldval
, rtx newval
,
16309 enum machine_mode mode
= GET_MODE (mem
);
16310 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
16312 emit_insn (gen_lwsync ());
16314 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
16315 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
16316 emit_label (XEXP (label1
, 0));
16318 emit_load_locked (mode
, retval
, mem
);
16320 x
= gen_rtx_COMPARE (CCmode
, retval
, oldval
);
16321 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
16323 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
16324 emit_unlikely_jump (x
, label2
);
16326 emit_move_insn (scratch
, newval
);
16327 emit_store_conditional (mode
, cond
, mem
, scratch
);
16329 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
16330 emit_unlikely_jump (x
, label1
);
16332 emit_insn (gen_isync ());
16333 emit_label (XEXP (label2
, 0));
16336 /* Expand an atomic test and set operation. MEM is the memory on which
16337 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16340 rs6000_split_lock_test_and_set (rtx retval
, rtx mem
, rtx val
, rtx scratch
)
16342 enum machine_mode mode
= GET_MODE (mem
);
16343 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
16345 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
16346 emit_label (XEXP (label
, 0));
16348 emit_load_locked (mode
, retval
, mem
);
16349 emit_move_insn (scratch
, val
);
16350 emit_store_conditional (mode
, cond
, mem
, scratch
);
16352 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
16353 emit_unlikely_jump (x
, label
);
16355 emit_insn (gen_isync ());
16359 rs6000_expand_compare_and_swapqhi (rtx dst
, rtx mem
, rtx oldval
, rtx newval
)
16361 enum machine_mode mode
= GET_MODE (mem
);
16362 rtx addrSI
, align
, wdst
, shift
, mask
;
16363 HOST_WIDE_INT shift_mask
= mode
== QImode
? 0x18 : 0x10;
16364 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
16366 /* Shift amount for subword relative to aligned word. */
16367 addrSI
= force_reg (GET_MODE (XEXP (mem
, 0)), XEXP (mem
, 0));
16368 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
, addrSI
));
16369 shift
= gen_reg_rtx (SImode
);
16370 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
16371 GEN_INT (shift_mask
)));
16372 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
16374 /* Shift and mask old value into position within word. */
16375 oldval
= convert_modes (SImode
, mode
, oldval
, 1);
16376 oldval
= expand_binop (SImode
, and_optab
,
16377 oldval
, GEN_INT (imask
), NULL_RTX
,
16378 1, OPTAB_LIB_WIDEN
);
16379 emit_insn (gen_ashlsi3 (oldval
, oldval
, shift
));
16381 /* Shift and mask new value into position within word. */
16382 newval
= convert_modes (SImode
, mode
, newval
, 1);
16383 newval
= expand_binop (SImode
, and_optab
,
16384 newval
, GEN_INT (imask
), NULL_RTX
,
16385 1, OPTAB_LIB_WIDEN
);
16386 emit_insn (gen_ashlsi3 (newval
, newval
, shift
));
16388 /* Mask for insertion. */
16389 mask
= gen_reg_rtx (SImode
);
16390 emit_move_insn (mask
, GEN_INT (imask
));
16391 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
16393 /* Address of aligned word containing subword. */
16394 align
= expand_binop (Pmode
, and_optab
, XEXP (mem
, 0), GEN_INT (-4),
16395 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
16396 mem
= change_address (mem
, SImode
, align
);
16397 set_mem_align (mem
, 32);
16398 MEM_VOLATILE_P (mem
) = 1;
16400 wdst
= gen_reg_rtx (SImode
);
16401 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst
, mask
,
16402 oldval
, newval
, mem
));
16404 /* Shift the result back. */
16405 emit_insn (gen_lshrsi3 (wdst
, wdst
, shift
));
16407 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
16411 rs6000_split_compare_and_swapqhi (rtx dest
, rtx mask
,
16412 rtx oldval
, rtx newval
, rtx mem
,
16415 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
16417 emit_insn (gen_lwsync ());
16418 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
16419 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
16420 emit_label (XEXP (label1
, 0));
16422 emit_load_locked (SImode
, scratch
, mem
);
16424 /* Mask subword within loaded value for comparison with oldval.
16425 Use UNSPEC_AND to avoid clobber.*/
16426 emit_insn (gen_rtx_SET (SImode
, dest
,
16427 gen_rtx_UNSPEC (SImode
,
16428 gen_rtvec (2, scratch
, mask
),
16431 x
= gen_rtx_COMPARE (CCmode
, dest
, oldval
);
16432 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
16434 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
16435 emit_unlikely_jump (x
, label2
);
16437 /* Clear subword within loaded value for insertion of new value. */
16438 emit_insn (gen_rtx_SET (SImode
, scratch
,
16439 gen_rtx_AND (SImode
,
16440 gen_rtx_NOT (SImode
, mask
), scratch
)));
16441 emit_insn (gen_iorsi3 (scratch
, scratch
, newval
));
16442 emit_store_conditional (SImode
, cond
, mem
, scratch
);
16444 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
16445 emit_unlikely_jump (x
, label1
);
16447 emit_insn (gen_isync ());
16448 emit_label (XEXP (label2
, 0));
16452 /* Emit instructions to move SRC to DST. Called by splitters for
16453 multi-register moves. It will emit at most one instruction for
16454 each register that is accessed; that is, it won't emit li/lis pairs
16455 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16459 rs6000_split_multireg_move (rtx dst
, rtx src
)
16461 /* The register number of the first register being moved. */
16463 /* The mode that is to be moved. */
16464 enum machine_mode mode
;
16465 /* The mode that the move is being done in, and its size. */
16466 enum machine_mode reg_mode
;
16468 /* The number of registers that will be moved. */
16471 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
16472 mode
= GET_MODE (dst
);
16473 nregs
= hard_regno_nregs
[reg
][mode
];
16474 if (FP_REGNO_P (reg
))
16475 reg_mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
:
16476 ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? DFmode
: SFmode
);
16477 else if (ALTIVEC_REGNO_P (reg
))
16478 reg_mode
= V16QImode
;
16479 else if (TARGET_E500_DOUBLE
&& mode
== TFmode
)
16482 reg_mode
= word_mode
;
16483 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
16485 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
16487 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
16489 /* Move register range backwards, if we might have destructive
16492 for (i
= nregs
- 1; i
>= 0; i
--)
16493 emit_insn (gen_rtx_SET (VOIDmode
,
16494 simplify_gen_subreg (reg_mode
, dst
, mode
,
16495 i
* reg_mode_size
),
16496 simplify_gen_subreg (reg_mode
, src
, mode
,
16497 i
* reg_mode_size
)));
16503 bool used_update
= false;
16505 if (MEM_P (src
) && INT_REGNO_P (reg
))
16509 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
16510 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
16513 breg
= XEXP (XEXP (src
, 0), 0);
16514 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
16515 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
16516 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
16517 emit_insn (gen_add3_insn (breg
, breg
, delta_rtx
));
16518 src
= replace_equiv_address (src
, breg
);
16520 else if (! rs6000_offsettable_memref_p (src
))
16523 basereg
= gen_rtx_REG (Pmode
, reg
);
16524 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
16525 src
= replace_equiv_address (src
, basereg
);
16528 breg
= XEXP (src
, 0);
16529 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
16530 breg
= XEXP (breg
, 0);
16532 /* If the base register we are using to address memory is
16533 also a destination reg, then change that register last. */
16535 && REGNO (breg
) >= REGNO (dst
)
16536 && REGNO (breg
) < REGNO (dst
) + nregs
)
16537 j
= REGNO (breg
) - REGNO (dst
);
16540 if (GET_CODE (dst
) == MEM
&& INT_REGNO_P (reg
))
16544 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
16545 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
16548 breg
= XEXP (XEXP (dst
, 0), 0);
16549 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
16550 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
16551 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
16553 /* We have to update the breg before doing the store.
16554 Use store with update, if available. */
16558 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
16559 emit_insn (TARGET_32BIT
16560 ? (TARGET_POWERPC64
16561 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
16562 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
16563 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
16564 used_update
= true;
16567 emit_insn (gen_add3_insn (breg
, breg
, delta_rtx
));
16568 dst
= replace_equiv_address (dst
, breg
);
16571 gcc_assert (rs6000_offsettable_memref_p (dst
));
16574 for (i
= 0; i
< nregs
; i
++)
16576 /* Calculate index to next subword. */
16581 /* If compiler already emitted move of first word by
16582 store with update, no need to do anything. */
16583 if (j
== 0 && used_update
)
16586 emit_insn (gen_rtx_SET (VOIDmode
,
16587 simplify_gen_subreg (reg_mode
, dst
, mode
,
16588 j
* reg_mode_size
),
16589 simplify_gen_subreg (reg_mode
, src
, mode
,
16590 j
* reg_mode_size
)));
16596 /* This page contains routines that are used to determine what the
16597 function prologue and epilogue code will do and write them out. */
16599 /* Return the first fixed-point register that is required to be
16600 saved. 32 if none. */
16603 first_reg_to_save (void)
16607 /* Find lowest numbered live register. */
16608 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
16609 if (df_regs_ever_live_p (first_reg
)
16610 && (! call_used_regs
[first_reg
]
16611 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
16612 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
16613 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
16614 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
16619 && crtl
->uses_pic_offset_table
16620 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
16621 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
16627 /* Similar, for FP regs. */
16630 first_fp_reg_to_save (void)
16634 /* Find lowest numbered live register. */
16635 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
16636 if (df_regs_ever_live_p (first_reg
))
16642 /* Similar, for AltiVec regs. */
16645 first_altivec_reg_to_save (void)
16649 /* Stack frame remains as is unless we are in AltiVec ABI. */
16650 if (! TARGET_ALTIVEC_ABI
)
16651 return LAST_ALTIVEC_REGNO
+ 1;
16653 /* On Darwin, the unwind routines are compiled without
16654 TARGET_ALTIVEC, and use save_world to save/restore the
16655 altivec registers when necessary. */
16656 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
16657 && ! TARGET_ALTIVEC
)
16658 return FIRST_ALTIVEC_REGNO
+ 20;
16660 /* Find lowest numbered live register. */
16661 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
16662 if (df_regs_ever_live_p (i
))
16668 /* Return a 32-bit mask of the AltiVec registers we need to set in
16669 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
16670 the 32-bit word is 0. */
16672 static unsigned int
16673 compute_vrsave_mask (void)
16675 unsigned int i
, mask
= 0;
16677 /* On Darwin, the unwind routines are compiled without
16678 TARGET_ALTIVEC, and use save_world to save/restore the
16679 call-saved altivec registers when necessary. */
16680 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
16681 && ! TARGET_ALTIVEC
)
16684 /* First, find out if we use _any_ altivec registers. */
16685 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
16686 if (df_regs_ever_live_p (i
))
16687 mask
|= ALTIVEC_REG_BIT (i
);
16692 /* Next, remove the argument registers from the set. These must
16693 be in the VRSAVE mask set by the caller, so we don't need to add
16694 them in again. More importantly, the mask we compute here is
16695 used to generate CLOBBERs in the set_vrsave insn, and we do not
16696 wish the argument registers to die. */
16697 for (i
= crtl
->args
.info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
16698 mask
&= ~ALTIVEC_REG_BIT (i
);
16700 /* Similarly, remove the return value from the set. */
16703 diddle_return_value (is_altivec_return_reg
, &yes
);
16705 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
16711 /* For a very restricted set of circumstances, we can cut down the
16712 size of prologues/epilogues by calling our own save/restore-the-world
16716 compute_save_world_info (rs6000_stack_t
*info_ptr
)
16718 info_ptr
->world_save_p
= 1;
16719 info_ptr
->world_save_p
16720 = (WORLD_SAVE_P (info_ptr
)
16721 && DEFAULT_ABI
== ABI_DARWIN
16722 && ! (cfun
->calls_setjmp
&& flag_exceptions
)
16723 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
16724 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
16725 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
16726 && info_ptr
->cr_save_p
);
16728 /* This will not work in conjunction with sibcalls. Make sure there
16729 are none. (This check is expensive, but seldom executed.) */
16730 if (WORLD_SAVE_P (info_ptr
))
16733 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
16734 if ( GET_CODE (insn
) == CALL_INSN
16735 && SIBLING_CALL_P (insn
))
16737 info_ptr
->world_save_p
= 0;
16742 if (WORLD_SAVE_P (info_ptr
))
16744 /* Even if we're not touching VRsave, make sure there's room on the
16745 stack for it, if it looks like we're calling SAVE_WORLD, which
16746 will attempt to save it. */
16747 info_ptr
->vrsave_size
= 4;
16749 /* If we are going to save the world, we need to save the link register too. */
16750 info_ptr
->lr_save_p
= 1;
16752 /* "Save" the VRsave register too if we're saving the world. */
16753 if (info_ptr
->vrsave_mask
== 0)
16754 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
16756 /* Because the Darwin register save/restore routines only handle
16757 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
16759 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
16760 && (info_ptr
->first_altivec_reg_save
16761 >= FIRST_SAVED_ALTIVEC_REGNO
));
16768 is_altivec_return_reg (rtx reg
, void *xyes
)
16770 bool *yes
= (bool *) xyes
;
16771 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
16776 /* Calculate the stack information for the current function. This is
16777 complicated by having two separate calling sequences, the AIX calling
16778 sequence and the V.4 calling sequence.
16780 AIX (and Darwin/Mac OS X) stack frames look like:
16782 SP----> +---------------------------------------+
16783 | back chain to caller | 0 0
16784 +---------------------------------------+
16785 | saved CR | 4 8 (8-11)
16786 +---------------------------------------+
16788 +---------------------------------------+
16789 | reserved for compilers | 12 24
16790 +---------------------------------------+
16791 | reserved for binders | 16 32
16792 +---------------------------------------+
16793 | saved TOC pointer | 20 40
16794 +---------------------------------------+
16795 | Parameter save area (P) | 24 48
16796 +---------------------------------------+
16797 | Alloca space (A) | 24+P etc.
16798 +---------------------------------------+
16799 | Local variable space (L) | 24+P+A
16800 +---------------------------------------+
16801 | Float/int conversion temporary (X) | 24+P+A+L
16802 +---------------------------------------+
16803 | Save area for AltiVec registers (W) | 24+P+A+L+X
16804 +---------------------------------------+
16805 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
16806 +---------------------------------------+
16807 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
16808 +---------------------------------------+
16809 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
16810 +---------------------------------------+
16811 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
16812 +---------------------------------------+
16813 old SP->| back chain to caller's caller |
16814 +---------------------------------------+
16816 The required alignment for AIX configurations is two words (i.e., 8
16820 V.4 stack frames look like:
16822 SP----> +---------------------------------------+
16823 | back chain to caller | 0
16824 +---------------------------------------+
16825 | caller's saved LR | 4
16826 +---------------------------------------+
16827 | Parameter save area (P) | 8
16828 +---------------------------------------+
16829 | Alloca space (A) | 8+P
16830 +---------------------------------------+
16831 | Varargs save area (V) | 8+P+A
16832 +---------------------------------------+
16833 | Local variable space (L) | 8+P+A+V
16834 +---------------------------------------+
16835 | Float/int conversion temporary (X) | 8+P+A+V+L
16836 +---------------------------------------+
16837 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
16838 +---------------------------------------+
16839 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
16840 +---------------------------------------+
16841 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
16842 +---------------------------------------+
16843 | SPE: area for 64-bit GP registers |
16844 +---------------------------------------+
16845 | SPE alignment padding |
16846 +---------------------------------------+
16847 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
16848 +---------------------------------------+
16849 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
16850 +---------------------------------------+
16851 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
16852 +---------------------------------------+
16853 old SP->| back chain to caller's caller |
16854 +---------------------------------------+
16856 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
16857 given. (But note below and in sysv4.h that we require only 8 and
16858 may round up the size of our stack frame anyways. The historical
16859 reason is early versions of powerpc-linux which didn't properly
16860 align the stack at program startup. A happy side-effect is that
16861 -mno-eabi libraries can be used with -meabi programs.)
16863 The EABI configuration defaults to the V.4 layout. However,
16864 the stack alignment requirements may differ. If -mno-eabi is not
16865 given, the required stack alignment is 8 bytes; if -mno-eabi is
16866 given, the required alignment is 16 bytes. (But see V.4 comment
16869 #ifndef ABI_STACK_BOUNDARY
16870 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
16873 static rs6000_stack_t
*
16874 rs6000_stack_info (void)
16876 static rs6000_stack_t info
;
16877 rs6000_stack_t
*info_ptr
= &info
;
16878 int reg_size
= TARGET_32BIT
? 4 : 8;
16882 HOST_WIDE_INT non_fixed_size
;
16884 memset (&info
, 0, sizeof (info
));
16888 /* Cache value so we don't rescan instruction chain over and over. */
16889 if (cfun
->machine
->insn_chain_scanned_p
== 0)
16890 cfun
->machine
->insn_chain_scanned_p
16891 = spe_func_has_64bit_regs_p () + 1;
16892 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
16895 /* Select which calling sequence. */
16896 info_ptr
->abi
= DEFAULT_ABI
;
16898 /* Calculate which registers need to be saved & save area size. */
16899 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
16900 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
16901 even if it currently looks like we won't. Reload may need it to
16902 get at a constant; if so, it will have already created a constant
16903 pool entry for it. */
16904 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
16905 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
16906 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
16907 && crtl
->uses_const_pool
16908 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
16909 first_gp
= RS6000_PIC_OFFSET_TABLE_REGNUM
;
16911 first_gp
= info_ptr
->first_gp_reg_save
;
16913 info_ptr
->gp_size
= reg_size
* (32 - first_gp
);
16915 /* For the SPE, we have an additional upper 32-bits on each GPR.
16916 Ideally we should save the entire 64-bits only when the upper
16917 half is used in SIMD instructions. Since we only record
16918 registers live (not the size they are used in), this proves
16919 difficult because we'd have to traverse the instruction chain at
16920 the right time, taking reload into account. This is a real pain,
16921 so we opt to save the GPRs in 64-bits always if but one register
16922 gets used in 64-bits. Otherwise, all the registers in the frame
16923 get saved in 32-bits.
16925 So... since when we save all GPRs (except the SP) in 64-bits, the
16926 traditional GP save area will be empty. */
16927 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
16928 info_ptr
->gp_size
= 0;
16930 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
16931 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
16933 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
16934 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
16935 - info_ptr
->first_altivec_reg_save
);
16937 /* Does this function call anything? */
16938 info_ptr
->calls_p
= (! current_function_is_leaf
16939 || cfun
->machine
->ra_needs_full_frame
);
16941 /* Determine if we need to save the link register. */
16942 if ((DEFAULT_ABI
== ABI_AIX
16944 && !TARGET_PROFILE_KERNEL
)
16945 #ifdef TARGET_RELOCATABLE
16946 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
16948 || (info_ptr
->first_fp_reg_save
!= 64
16949 && !FP_SAVE_INLINE (info_ptr
->first_fp_reg_save
))
16950 || (DEFAULT_ABI
== ABI_V4
&& cfun
->calls_alloca
)
16951 || info_ptr
->calls_p
16952 || rs6000_ra_ever_killed ())
16954 info_ptr
->lr_save_p
= 1;
16955 df_set_regs_ever_live (LR_REGNO
, true);
16958 /* Determine if we need to save the condition code registers. */
16959 if (df_regs_ever_live_p (CR2_REGNO
)
16960 || df_regs_ever_live_p (CR3_REGNO
)
16961 || df_regs_ever_live_p (CR4_REGNO
))
16963 info_ptr
->cr_save_p
= 1;
16964 if (DEFAULT_ABI
== ABI_V4
)
16965 info_ptr
->cr_size
= reg_size
;
16968 /* If the current function calls __builtin_eh_return, then we need
16969 to allocate stack space for registers that will hold data for
16970 the exception handler. */
16971 if (crtl
->calls_eh_return
)
16974 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
16977 /* SPE saves EH registers in 64-bits. */
16978 ehrd_size
= i
* (TARGET_SPE_ABI
16979 && info_ptr
->spe_64bit_regs_used
!= 0
16980 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
16985 /* Determine various sizes. */
16986 info_ptr
->reg_size
= reg_size
;
16987 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
16988 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
16989 info_ptr
->parm_size
= RS6000_ALIGN (crtl
->outgoing_args_size
,
16990 TARGET_ALTIVEC
? 16 : 8);
16991 if (FRAME_GROWS_DOWNWARD
)
16992 info_ptr
->vars_size
16993 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
16994 + info_ptr
->parm_size
,
16995 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
16996 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
16997 + info_ptr
->parm_size
);
16999 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
17000 info_ptr
->spe_gp_size
= 8 * (32 - first_gp
);
17002 info_ptr
->spe_gp_size
= 0;
17004 if (TARGET_ALTIVEC_ABI
)
17005 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
17007 info_ptr
->vrsave_mask
= 0;
17009 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
17010 info_ptr
->vrsave_size
= 4;
17012 info_ptr
->vrsave_size
= 0;
17014 compute_save_world_info (info_ptr
);
17016 /* Calculate the offsets. */
17017 switch (DEFAULT_ABI
)
17021 gcc_unreachable ();
17025 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
17026 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
17028 if (TARGET_ALTIVEC_ABI
)
17030 info_ptr
->vrsave_save_offset
17031 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
17033 /* Align stack so vector save area is on a quadword boundary.
17034 The padding goes above the vectors. */
17035 if (info_ptr
->altivec_size
!= 0)
17036 info_ptr
->altivec_padding_size
17037 = info_ptr
->vrsave_save_offset
& 0xF;
17039 info_ptr
->altivec_padding_size
= 0;
17041 info_ptr
->altivec_save_offset
17042 = info_ptr
->vrsave_save_offset
17043 - info_ptr
->altivec_padding_size
17044 - info_ptr
->altivec_size
;
17045 gcc_assert (info_ptr
->altivec_size
== 0
17046 || info_ptr
->altivec_save_offset
% 16 == 0);
17048 /* Adjust for AltiVec case. */
17049 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
17052 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
17053 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
17054 info_ptr
->lr_save_offset
= 2*reg_size
;
17058 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
17059 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
17060 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
17062 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
17064 /* Align stack so SPE GPR save area is aligned on a
17065 double-word boundary. */
17066 if (info_ptr
->spe_gp_size
!= 0 && info_ptr
->cr_save_offset
!= 0)
17067 info_ptr
->spe_padding_size
17068 = 8 - (-info_ptr
->cr_save_offset
% 8);
17070 info_ptr
->spe_padding_size
= 0;
17072 info_ptr
->spe_gp_save_offset
17073 = info_ptr
->cr_save_offset
17074 - info_ptr
->spe_padding_size
17075 - info_ptr
->spe_gp_size
;
17077 /* Adjust for SPE case. */
17078 info_ptr
->ehrd_offset
= info_ptr
->spe_gp_save_offset
;
17080 else if (TARGET_ALTIVEC_ABI
)
17082 info_ptr
->vrsave_save_offset
17083 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
17085 /* Align stack so vector save area is on a quadword boundary. */
17086 if (info_ptr
->altivec_size
!= 0)
17087 info_ptr
->altivec_padding_size
17088 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
17090 info_ptr
->altivec_padding_size
= 0;
17092 info_ptr
->altivec_save_offset
17093 = info_ptr
->vrsave_save_offset
17094 - info_ptr
->altivec_padding_size
17095 - info_ptr
->altivec_size
;
17097 /* Adjust for AltiVec case. */
17098 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
;
17101 info_ptr
->ehrd_offset
= info_ptr
->cr_save_offset
;
17102 info_ptr
->ehrd_offset
-= ehrd_size
;
17103 info_ptr
->lr_save_offset
= reg_size
;
17107 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
17108 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
17109 + info_ptr
->gp_size
17110 + info_ptr
->altivec_size
17111 + info_ptr
->altivec_padding_size
17112 + info_ptr
->spe_gp_size
17113 + info_ptr
->spe_padding_size
17115 + info_ptr
->cr_size
17116 + info_ptr
->vrsave_size
,
17119 non_fixed_size
= (info_ptr
->vars_size
17120 + info_ptr
->parm_size
17121 + info_ptr
->save_size
);
17123 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
17124 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
17126 /* Determine if we need to allocate any stack frame:
17128 For AIX we need to push the stack if a frame pointer is needed
17129 (because the stack might be dynamically adjusted), if we are
17130 debugging, if we make calls, or if the sum of fp_save, gp_save,
17131 and local variables are more than the space needed to save all
17132 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17133 + 18*8 = 288 (GPR13 reserved).
17135 For V.4 we don't have the stack cushion that AIX uses, but assume
17136 that the debugger can handle stackless frames. */
17138 if (info_ptr
->calls_p
)
17139 info_ptr
->push_p
= 1;
17141 else if (DEFAULT_ABI
== ABI_V4
)
17142 info_ptr
->push_p
= non_fixed_size
!= 0;
17144 else if (frame_pointer_needed
)
17145 info_ptr
->push_p
= 1;
17147 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
17148 info_ptr
->push_p
= 1;
17151 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
17153 /* Zero offsets if we're not saving those registers. */
17154 if (info_ptr
->fp_size
== 0)
17155 info_ptr
->fp_save_offset
= 0;
17157 if (info_ptr
->gp_size
== 0)
17158 info_ptr
->gp_save_offset
= 0;
17160 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
17161 info_ptr
->altivec_save_offset
= 0;
17163 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
17164 info_ptr
->vrsave_save_offset
= 0;
17166 if (! TARGET_SPE_ABI
17167 || info_ptr
->spe_64bit_regs_used
== 0
17168 || info_ptr
->spe_gp_size
== 0)
17169 info_ptr
->spe_gp_save_offset
= 0;
17171 if (! info_ptr
->lr_save_p
)
17172 info_ptr
->lr_save_offset
= 0;
17174 if (! info_ptr
->cr_save_p
)
17175 info_ptr
->cr_save_offset
= 0;
17180 /* Return true if the current function uses any GPRs in 64-bit SIMD
17184 spe_func_has_64bit_regs_p (void)
17188 /* Functions that save and restore all the call-saved registers will
17189 need to save/restore the registers in 64-bits. */
17190 if (crtl
->calls_eh_return
17191 || cfun
->calls_setjmp
17192 || crtl
->has_nonlocal_goto
)
17195 insns
= get_insns ();
17197 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
17203 /* FIXME: This should be implemented with attributes...
17205 (set_attr "spe64" "true")....then,
17206 if (get_spe64(insn)) return true;
17208 It's the only reliable way to do the stuff below. */
17210 i
= PATTERN (insn
);
17211 if (GET_CODE (i
) == SET
)
17213 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
17215 if (SPE_VECTOR_MODE (mode
))
17217 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
))
17227 debug_stack_info (rs6000_stack_t
*info
)
17229 const char *abi_string
;
17232 info
= rs6000_stack_info ();
17234 fprintf (stderr
, "\nStack information for function %s:\n",
17235 ((current_function_decl
&& DECL_NAME (current_function_decl
))
17236 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
17241 default: abi_string
= "Unknown"; break;
17242 case ABI_NONE
: abi_string
= "NONE"; break;
17243 case ABI_AIX
: abi_string
= "AIX"; break;
17244 case ABI_DARWIN
: abi_string
= "Darwin"; break;
17245 case ABI_V4
: abi_string
= "V.4"; break;
17248 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
17250 if (TARGET_ALTIVEC_ABI
)
17251 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
17253 if (TARGET_SPE_ABI
)
17254 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
17256 if (info
->first_gp_reg_save
!= 32)
17257 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
17259 if (info
->first_fp_reg_save
!= 64)
17260 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
17262 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
17263 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
17264 info
->first_altivec_reg_save
);
17266 if (info
->lr_save_p
)
17267 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
17269 if (info
->cr_save_p
)
17270 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
17272 if (info
->vrsave_mask
)
17273 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
17276 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
17279 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
17281 if (info
->gp_save_offset
)
17282 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
17284 if (info
->fp_save_offset
)
17285 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
17287 if (info
->altivec_save_offset
)
17288 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
17289 info
->altivec_save_offset
);
17291 if (info
->spe_gp_save_offset
)
17292 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
17293 info
->spe_gp_save_offset
);
17295 if (info
->vrsave_save_offset
)
17296 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
17297 info
->vrsave_save_offset
);
17299 if (info
->lr_save_offset
)
17300 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
17302 if (info
->cr_save_offset
)
17303 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
17305 if (info
->varargs_save_offset
)
17306 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
17308 if (info
->total_size
)
17309 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
17312 if (info
->vars_size
)
17313 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
17316 if (info
->parm_size
)
17317 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
17319 if (info
->fixed_size
)
17320 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
17323 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
17325 if (info
->spe_gp_size
)
17326 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
17329 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
17331 if (info
->altivec_size
)
17332 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
17334 if (info
->vrsave_size
)
17335 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
17337 if (info
->altivec_padding_size
)
17338 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
17339 info
->altivec_padding_size
);
17341 if (info
->spe_padding_size
)
17342 fprintf (stderr
, "\tspe_padding_size = %5d\n",
17343 info
->spe_padding_size
);
17346 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
17348 if (info
->save_size
)
17349 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
17351 if (info
->reg_size
!= 4)
17352 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
17354 fprintf (stderr
, "\n");
17358 rs6000_return_addr (int count
, rtx frame
)
17360 /* Currently we don't optimize very well between prolog and body
17361 code and for PIC code the code can be actually quite bad, so
17362 don't try to be too clever here. */
17363 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
17365 cfun
->machine
->ra_needs_full_frame
= 1;
17372 plus_constant (copy_to_reg
17373 (gen_rtx_MEM (Pmode
,
17374 memory_address (Pmode
, frame
))),
17375 RETURN_ADDRESS_OFFSET
)));
17378 cfun
->machine
->ra_need_lr
= 1;
17379 return get_hard_reg_initial_val (Pmode
, LR_REGNO
);
17382 /* Say whether a function is a candidate for sibcall handling or not.
17383 We do not allow indirect calls to be optimized into sibling calls.
17384 Also, we can't do it if there are any vector parameters; there's
17385 nowhere to put the VRsave code so it works; note that functions with
17386 vector parameters are required to have a prototype, so the argument
17387 type info must be available here. (The tail recursion case can work
17388 with vector parameters, but there's no way to distinguish here.) */
17390 rs6000_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
17395 if (TARGET_ALTIVEC_VRSAVE
)
17397 for (type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
17398 type
; type
= TREE_CHAIN (type
))
17400 if (TREE_CODE (TREE_VALUE (type
)) == VECTOR_TYPE
)
17404 if (DEFAULT_ABI
== ABI_DARWIN
17405 || ((*targetm
.binds_local_p
) (decl
)
17406 && (DEFAULT_ABI
!= ABI_AIX
|| !DECL_EXTERNAL (decl
))))
17408 tree attr_list
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
17410 if (!lookup_attribute ("longcall", attr_list
)
17411 || lookup_attribute ("shortcall", attr_list
))
17418 /* NULL if INSN insn is valid within a low-overhead loop.
17419 Otherwise return why doloop cannot be applied.
17420 PowerPC uses the COUNT register for branch on table instructions. */
17422 static const char *
17423 rs6000_invalid_within_doloop (const_rtx insn
)
17426 return "Function call in the loop.";
17429 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
17430 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
17431 return "Computed branch in the loop.";
17437 rs6000_ra_ever_killed (void)
17443 if (cfun
->is_thunk
)
17446 /* regs_ever_live has LR marked as used if any sibcalls are present,
17447 but this should not force saving and restoring in the
17448 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
17449 clobbers LR, so that is inappropriate. */
17451 /* Also, the prologue can generate a store into LR that
17452 doesn't really count, like this:
17455 bcl to set PIC register
17459 When we're called from the epilogue, we need to avoid counting
17460 this as a store. */
17462 push_topmost_sequence ();
17463 top
= get_insns ();
17464 pop_topmost_sequence ();
17465 reg
= gen_rtx_REG (Pmode
, LR_REGNO
);
17467 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
17473 if (!SIBLING_CALL_P (insn
))
17476 else if (find_regno_note (insn
, REG_INC
, LR_REGNO
))
17478 else if (set_of (reg
, insn
) != NULL_RTX
17479 && !prologue_epilogue_contains (insn
))
17486 /* Emit instructions needed to load the TOC register.
17487 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
17488 a constant pool; or for SVR4 -fpic. */
17491 rs6000_emit_load_toc_table (int fromprolog
)
17494 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
17496 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
17499 rtx lab
, tmp1
, tmp2
, got
;
17501 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
17502 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
17504 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
17506 got
= rs6000_got_sym ();
17507 tmp1
= tmp2
= dest
;
17510 tmp1
= gen_reg_rtx (Pmode
);
17511 tmp2
= gen_reg_rtx (Pmode
);
17513 emit_insn (gen_load_toc_v4_PIC_1 (lab
));
17514 emit_move_insn (tmp1
,
17515 gen_rtx_REG (Pmode
, LR_REGNO
));
17516 emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
17517 emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
17519 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
17521 emit_insn (gen_load_toc_v4_pic_si ());
17522 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
17524 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
17527 rtx temp0
= (fromprolog
17528 ? gen_rtx_REG (Pmode
, 0)
17529 : gen_reg_rtx (Pmode
));
17535 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
17536 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
17538 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
17539 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
17541 emit_insn (gen_load_toc_v4_PIC_1 (symF
));
17542 emit_move_insn (dest
,
17543 gen_rtx_REG (Pmode
, LR_REGNO
));
17544 emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
, symL
, symF
));
17550 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
17551 emit_insn (gen_load_toc_v4_PIC_1b (tocsym
));
17552 emit_move_insn (dest
,
17553 gen_rtx_REG (Pmode
, LR_REGNO
));
17554 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
17556 emit_insn (gen_addsi3 (dest
, temp0
, dest
));
17558 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
17560 /* This is for AIX code running in non-PIC ELF32. */
17563 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
17564 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
17566 emit_insn (gen_elf_high (dest
, realsym
));
17567 emit_insn (gen_elf_low (dest
, dest
, realsym
));
17571 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
17574 emit_insn (gen_load_toc_aix_si (dest
));
17576 emit_insn (gen_load_toc_aix_di (dest
));
17580 /* Emit instructions to restore the link register after determining where
17581 its value has been stored. */
17584 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
17586 rs6000_stack_t
*info
= rs6000_stack_info ();
17589 operands
[0] = source
;
17590 operands
[1] = scratch
;
17592 if (info
->lr_save_p
)
17594 rtx frame_rtx
= stack_pointer_rtx
;
17595 HOST_WIDE_INT sp_offset
= 0;
17598 if (frame_pointer_needed
17599 || cfun
->calls_alloca
17600 || info
->total_size
> 32767)
17602 tmp
= gen_frame_mem (Pmode
, frame_rtx
);
17603 emit_move_insn (operands
[1], tmp
);
17604 frame_rtx
= operands
[1];
17606 else if (info
->push_p
)
17607 sp_offset
= info
->total_size
;
17609 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
17610 tmp
= gen_frame_mem (Pmode
, tmp
);
17611 emit_move_insn (tmp
, operands
[0]);
17614 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
), operands
[0]);
17617 static GTY(()) alias_set_type set
= -1;
17620 get_TOC_alias_set (void)
17623 set
= new_alias_set ();
17627 /* This returns nonzero if the current function uses the TOC. This is
17628 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
17629 is generated by the ABI_V4 load_toc_* patterns. */
17636 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
17639 rtx pat
= PATTERN (insn
);
17642 if (GET_CODE (pat
) == PARALLEL
)
17643 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
17645 rtx sub
= XVECEXP (pat
, 0, i
);
17646 if (GET_CODE (sub
) == USE
)
17648 sub
= XEXP (sub
, 0);
17649 if (GET_CODE (sub
) == UNSPEC
17650 && XINT (sub
, 1) == UNSPEC_TOC
)
17660 create_TOC_reference (rtx symbol
)
17662 if (TARGET_DEBUG_ADDR
)
17664 if (GET_CODE (symbol
) == SYMBOL_REF
)
17665 fprintf (stderr
, "\ncreate_TOC_reference, (symbol_ref %s)\n",
17669 fprintf (stderr
, "\ncreate_TOC_reference, code %s:\n",
17670 GET_RTX_NAME (GET_CODE (symbol
)));
17671 debug_rtx (symbol
);
17675 if (!can_create_pseudo_p ())
17676 df_set_regs_ever_live (TOC_REGISTER
, true);
17677 return gen_rtx_PLUS (Pmode
,
17678 gen_rtx_REG (Pmode
, TOC_REGISTER
),
17679 gen_rtx_CONST (Pmode
,
17680 gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, symbol
), UNSPEC_TOCREL
)));
17683 /* Issue assembly directives that create a reference to the given DWARF
17684 FRAME_TABLE_LABEL from the current function section. */
17686 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label
)
17688 fprintf (asm_out_file
, "\t.ref %s\n",
17689 TARGET_STRIP_NAME_ENCODING (frame_table_label
));
17692 /* If _Unwind_* has been called from within the same module,
17693 toc register is not guaranteed to be saved to 40(1) on function
17694 entry. Save it there in that case. */
17697 rs6000_aix_emit_builtin_unwind_init (void)
17700 rtx stack_top
= gen_reg_rtx (Pmode
);
17701 rtx opcode_addr
= gen_reg_rtx (Pmode
);
17702 rtx opcode
= gen_reg_rtx (SImode
);
17703 rtx tocompare
= gen_reg_rtx (SImode
);
17704 rtx no_toc_save_needed
= gen_label_rtx ();
17706 mem
= gen_frame_mem (Pmode
, hard_frame_pointer_rtx
);
17707 emit_move_insn (stack_top
, mem
);
17709 mem
= gen_frame_mem (Pmode
,
17710 gen_rtx_PLUS (Pmode
, stack_top
,
17711 GEN_INT (2 * GET_MODE_SIZE (Pmode
))));
17712 emit_move_insn (opcode_addr
, mem
);
17713 emit_move_insn (opcode
, gen_rtx_MEM (SImode
, opcode_addr
));
17714 emit_move_insn (tocompare
, gen_int_mode (TARGET_32BIT
? 0x80410014
17715 : 0xE8410028, SImode
));
17717 do_compare_rtx_and_jump (opcode
, tocompare
, EQ
, 1,
17718 SImode
, NULL_RTX
, NULL_RTX
,
17719 no_toc_save_needed
);
17721 mem
= gen_frame_mem (Pmode
,
17722 gen_rtx_PLUS (Pmode
, stack_top
,
17723 GEN_INT (5 * GET_MODE_SIZE (Pmode
))));
17724 emit_move_insn (mem
, gen_rtx_REG (Pmode
, 2));
17725 emit_label (no_toc_save_needed
);
17728 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
17729 and the change to the stack pointer. */
17732 rs6000_emit_stack_tie (void)
17734 rtx mem
= gen_frame_mem (BLKmode
,
17735 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
17737 emit_insn (gen_stack_tie (mem
));
17740 /* Emit the correct code for allocating stack space, as insns.
17741 If COPY_R12, make sure a copy of the old frame is left in r12.
17742 If COPY_R11, make sure a copy of the old frame is left in r11,
17743 in preference to r12 if COPY_R12.
17744 The generated code may use hard register 0 as a temporary. */
17747 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, int copy_r12
, int copy_r11
)
17750 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
17751 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
17752 rtx todec
= gen_int_mode (-size
, Pmode
);
17755 if (INTVAL (todec
) != -size
)
17757 warning (0, "stack frame too large");
17758 emit_insn (gen_trap ());
17762 if (crtl
->limit_stack
)
17764 if (REG_P (stack_limit_rtx
)
17765 && REGNO (stack_limit_rtx
) > 1
17766 && REGNO (stack_limit_rtx
) <= 31)
17768 emit_insn (gen_add3_insn (tmp_reg
, stack_limit_rtx
, GEN_INT (size
)));
17769 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
17772 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
17774 && DEFAULT_ABI
== ABI_V4
)
17776 rtx toload
= gen_rtx_CONST (VOIDmode
,
17777 gen_rtx_PLUS (Pmode
,
17781 emit_insn (gen_elf_high (tmp_reg
, toload
));
17782 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
17783 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
17787 warning (0, "stack limit expression is not supported");
17790 if (copy_r12
|| copy_r11
)
17791 emit_move_insn (copy_r11
17792 ? gen_rtx_REG (Pmode
, 11)
17793 : gen_rtx_REG (Pmode
, 12),
17798 /* Need a note here so that try_split doesn't get confused. */
17799 if (get_last_insn () == NULL_RTX
)
17800 emit_note (NOTE_INSN_DELETED
);
17801 insn
= emit_move_insn (tmp_reg
, todec
);
17802 try_split (PATTERN (insn
), insn
, 0);
17806 insn
= emit_insn (TARGET_32BIT
17807 ? gen_movsi_update_stack (stack_reg
, stack_reg
,
17809 : gen_movdi_di_update_stack (stack_reg
, stack_reg
,
17810 todec
, stack_reg
));
17811 /* Since we didn't use gen_frame_mem to generate the MEM, grab
17812 it now and set the alias set/attributes. The above gen_*_update
17813 calls will generate a PARALLEL with the MEM set being the first
17815 par
= PATTERN (insn
);
17816 gcc_assert (GET_CODE (par
) == PARALLEL
);
17817 set
= XVECEXP (par
, 0, 0);
17818 gcc_assert (GET_CODE (set
) == SET
);
17819 mem
= SET_DEST (set
);
17820 gcc_assert (MEM_P (mem
));
17821 MEM_NOTRAP_P (mem
) = 1;
17822 set_mem_alias_set (mem
, get_frame_alias_set ());
17824 RTX_FRAME_RELATED_P (insn
) = 1;
17825 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
17826 gen_rtx_SET (VOIDmode
, stack_reg
,
17827 gen_rtx_PLUS (Pmode
, stack_reg
,
17828 GEN_INT (-size
))));
17831 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
17832 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
17833 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
17834 deduce these equivalences by itself so it wasn't necessary to hold
17835 its hand so much. */
17838 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
17839 rtx reg2
, rtx rreg
)
17843 /* copy_rtx will not make unique copies of registers, so we need to
17844 ensure we don't have unwanted sharing here. */
17846 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
17849 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
17851 real
= copy_rtx (PATTERN (insn
));
17853 if (reg2
!= NULL_RTX
)
17854 real
= replace_rtx (real
, reg2
, rreg
);
17856 real
= replace_rtx (real
, reg
,
17857 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
17858 STACK_POINTER_REGNUM
),
17861 /* We expect that 'real' is either a SET or a PARALLEL containing
17862 SETs (and possibly other stuff). In a PARALLEL, all the SETs
17863 are important so they all have to be marked RTX_FRAME_RELATED_P. */
17865 if (GET_CODE (real
) == SET
)
17869 temp
= simplify_rtx (SET_SRC (set
));
17871 SET_SRC (set
) = temp
;
17872 temp
= simplify_rtx (SET_DEST (set
));
17874 SET_DEST (set
) = temp
;
17875 if (GET_CODE (SET_DEST (set
)) == MEM
)
17877 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
17879 XEXP (SET_DEST (set
), 0) = temp
;
17886 gcc_assert (GET_CODE (real
) == PARALLEL
);
17887 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
17888 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
17890 rtx set
= XVECEXP (real
, 0, i
);
17892 temp
= simplify_rtx (SET_SRC (set
));
17894 SET_SRC (set
) = temp
;
17895 temp
= simplify_rtx (SET_DEST (set
));
17897 SET_DEST (set
) = temp
;
17898 if (GET_CODE (SET_DEST (set
)) == MEM
)
17900 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
17902 XEXP (SET_DEST (set
), 0) = temp
;
17904 RTX_FRAME_RELATED_P (set
) = 1;
17908 RTX_FRAME_RELATED_P (insn
) = 1;
17909 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, real
);
17912 /* Returns an insn that has a vrsave set operation with the
17913 appropriate CLOBBERs. */
17916 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
17919 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
17920 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
17923 = gen_rtx_SET (VOIDmode
,
17925 gen_rtx_UNSPEC_VOLATILE (SImode
,
17926 gen_rtvec (2, reg
, vrsave
),
17927 UNSPECV_SET_VRSAVE
));
17931 /* We need to clobber the registers in the mask so the scheduler
17932 does not move sets to VRSAVE before sets of AltiVec registers.
17934 However, if the function receives nonlocal gotos, reload will set
17935 all call saved registers live. We will end up with:
17937 (set (reg 999) (mem))
17938 (parallel [ (set (reg vrsave) (unspec blah))
17939 (clobber (reg 999))])
17941 The clobber will cause the store into reg 999 to be dead, and
17942 flow will attempt to delete an epilogue insn. In this case, we
17943 need an unspec use/set of the register. */
17945 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
17946 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
17948 if (!epiloguep
|| call_used_regs
[i
])
17949 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
17950 gen_rtx_REG (V4SImode
, i
));
17953 rtx reg
= gen_rtx_REG (V4SImode
, i
);
17956 = gen_rtx_SET (VOIDmode
,
17958 gen_rtx_UNSPEC (V4SImode
,
17959 gen_rtvec (1, reg
), 27));
17963 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
17965 for (i
= 0; i
< nclobs
; ++i
)
17966 XVECEXP (insn
, 0, i
) = clobs
[i
];
17971 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
17972 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
17975 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
17976 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
17978 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
17979 rtx replacea
, replaceb
;
17981 int_rtx
= GEN_INT (offset
);
17983 /* Some cases that need register indexed addressing. */
17984 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
17985 || (TARGET_VSX
&& VSX_VECTOR_MODE (mode
))
17986 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
17988 && SPE_VECTOR_MODE (mode
)
17989 && !SPE_CONST_OFFSET_OK (offset
)))
17991 /* Whomever calls us must make sure r11 is available in the
17992 flow path of instructions in the prologue. */
17993 offset_rtx
= gen_rtx_REG (Pmode
, 11);
17994 emit_move_insn (offset_rtx
, int_rtx
);
17996 replacea
= offset_rtx
;
17997 replaceb
= int_rtx
;
18001 offset_rtx
= int_rtx
;
18002 replacea
= NULL_RTX
;
18003 replaceb
= NULL_RTX
;
18006 reg
= gen_rtx_REG (mode
, regno
);
18007 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
18008 mem
= gen_frame_mem (mode
, addr
);
18010 insn
= emit_move_insn (mem
, reg
);
18012 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
18015 /* Emit an offset memory reference suitable for a frame store, while
18016 converting to a valid addressing mode. */
18019 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
18021 rtx int_rtx
, offset_rtx
;
18023 int_rtx
= GEN_INT (offset
);
18025 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
18026 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
18028 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
18029 emit_move_insn (offset_rtx
, int_rtx
);
18032 offset_rtx
= int_rtx
;
18034 return gen_frame_mem (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
18037 /* Look for user-defined global regs. We should not save and restore these,
18038 and cannot use stmw/lmw if there are any in its range. */
18041 no_global_regs_above (int first
, bool gpr
)
18044 int last
= gpr
? 32 : 64;
18045 for (i
= first
; i
< last
; i
++)
18046 if (global_regs
[i
])
18051 #ifndef TARGET_FIX_AND_CONTINUE
18052 #define TARGET_FIX_AND_CONTINUE 0
18055 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18056 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18057 #define LAST_SAVRES_REGISTER 31
18058 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18060 static GTY(()) rtx savres_routine_syms
[N_SAVRES_REGISTERS
][8];
18062 /* Temporary holding space for an out-of-line register save/restore
18064 static char savres_routine_name
[30];
18066 /* Return the name for an out-of-line register save/restore routine.
18067 We are saving/restoring GPRs if GPR is true. */
18070 rs6000_savres_routine_name (rs6000_stack_t
*info
, int regno
,
18071 bool savep
, bool gpr
, bool lr
)
18073 const char *prefix
= "";
18074 const char *suffix
= "";
18076 /* Different targets are supposed to define
18077 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18078 routine name could be defined with:
18080 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18082 This is a nice idea in practice, but in reality, things are
18083 complicated in several ways:
18085 - ELF targets have save/restore routines for GPRs.
18087 - SPE targets use different prefixes for 32/64-bit registers, and
18088 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18090 - PPC64 ELF targets have routines for save/restore of GPRs that
18091 differ in what they do with the link register, so having a set
18092 prefix doesn't work. (We only use one of the save routines at
18093 the moment, though.)
18095 - PPC32 elf targets have "exit" versions of the restore routines
18096 that restore the link register and can save some extra space.
18097 These require an extra suffix. (There are also "tail" versions
18098 of the restore routines and "GOT" versions of the save routines,
18099 but we don't generate those at present. Same problems apply,
18102 We deal with all this by synthesizing our own prefix/suffix and
18103 using that for the simple sprintf call shown above. */
18106 /* No floating point saves on the SPE. */
18110 prefix
= info
->spe_64bit_regs_used
? "_save64gpr_" : "_save32gpr_";
18112 prefix
= info
->spe_64bit_regs_used
? "_rest64gpr_" : "_rest32gpr_";
18117 else if (DEFAULT_ABI
== ABI_V4
)
18123 prefix
= savep
? "_savegpr_" : "_restgpr_";
18125 prefix
= savep
? "_savefpr_" : "_restfpr_";
18130 else if (DEFAULT_ABI
== ABI_AIX
)
18132 #ifndef POWERPC_LINUX
18133 /* No out-of-line save/restore routines for GPRs on AIX. */
18134 gcc_assert (!TARGET_AIX
|| !gpr
);
18140 ? (lr
? "_savegpr0_" : "_savegpr1_")
18141 : (lr
? "_restgpr0_" : "_restgpr1_"));
18142 #ifdef POWERPC_LINUX
18144 prefix
= (savep
? "_savefpr_" : "_restfpr_");
18148 prefix
= savep
? SAVE_FP_PREFIX
: RESTORE_FP_PREFIX
;
18149 suffix
= savep
? SAVE_FP_SUFFIX
: RESTORE_FP_SUFFIX
;
18152 else if (DEFAULT_ABI
== ABI_DARWIN
)
18153 sorry ("Out-of-line save/restore routines not supported on Darwin");
18155 sprintf (savres_routine_name
, "%s%d%s", prefix
, regno
, suffix
);
18157 return savres_routine_name
;
18160 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18161 We are saving/restoring GPRs if GPR is true. */
18164 rs6000_savres_routine_sym (rs6000_stack_t
*info
, bool savep
,
18167 int regno
= gpr
? info
->first_gp_reg_save
: (info
->first_fp_reg_save
- 32);
18169 int select
= ((savep
? 1 : 0) << 2
18171 /* On the SPE, we never have any FPRs, but we do have
18172 32/64-bit versions of the routines. */
18173 ? (info
->spe_64bit_regs_used
? 1 : 0)
18174 : (gpr
? 1 : 0)) << 1)
18177 /* Don't generate bogus routine names. */
18178 gcc_assert (FIRST_SAVRES_REGISTER
<= regno
18179 && regno
<= LAST_SAVRES_REGISTER
);
18181 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
];
18187 name
= rs6000_savres_routine_name (info
, regno
, savep
, gpr
, lr
);
18189 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
]
18190 = gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (name
));
18191 SYMBOL_REF_FLAGS (sym
) |= SYMBOL_FLAG_FUNCTION
;
18197 /* Emit a sequence of insns, including a stack tie if needed, for
18198 resetting the stack pointer. If SAVRES is true, then don't reset the
18199 stack pointer, but move the base of the frame into r11 for use by
18200 out-of-line register restore routines. */
18203 rs6000_emit_stack_reset (rs6000_stack_t
*info
,
18204 rtx sp_reg_rtx
, rtx frame_reg_rtx
,
18205 int sp_offset
, bool savres
)
18207 /* This blockage is needed so that sched doesn't decide to move
18208 the sp change before the register restores. */
18209 if (frame_reg_rtx
!= sp_reg_rtx
18211 && info
->spe_64bit_regs_used
!= 0
18212 && info
->first_gp_reg_save
!= 32))
18213 rs6000_emit_stack_tie ();
18215 if (frame_reg_rtx
!= sp_reg_rtx
)
18217 if (sp_offset
!= 0)
18219 rtx dest_reg
= savres
? gen_rtx_REG (Pmode
, 11) : sp_reg_rtx
;
18220 return emit_insn (gen_add3_insn (dest_reg
, frame_reg_rtx
,
18221 GEN_INT (sp_offset
)));
18224 return emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
18226 else if (sp_offset
!= 0)
18228 /* If we are restoring registers out-of-line, we will be using the
18229 "exit" variants of the restore routines, which will reset the
18230 stack for us. But we do need to point r11 into the right place
18231 for those routines. */
18232 rtx dest_reg
= (savres
18233 ? gen_rtx_REG (Pmode
, 11)
18236 rtx insn
= emit_insn (gen_add3_insn (dest_reg
, sp_reg_rtx
,
18237 GEN_INT (sp_offset
)));
18244 /* Construct a parallel rtx describing the effect of a call to an
18245 out-of-line register save/restore routine. */
18248 rs6000_make_savres_rtx (rs6000_stack_t
*info
,
18249 rtx frame_reg_rtx
, int save_area_offset
,
18250 enum machine_mode reg_mode
,
18251 bool savep
, bool gpr
, bool lr
)
18254 int offset
, start_reg
, end_reg
, n_regs
;
18255 int reg_size
= GET_MODE_SIZE (reg_mode
);
18261 ? info
->first_gp_reg_save
18262 : info
->first_fp_reg_save
);
18263 end_reg
= gpr
? 32 : 64;
18264 n_regs
= end_reg
- start_reg
;
18265 p
= rtvec_alloc ((lr
? 4 : 3) + n_regs
);
18268 RTVEC_ELT (p
, offset
++) = gen_rtx_RETURN (VOIDmode
);
18270 RTVEC_ELT (p
, offset
++)
18271 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 65));
18273 sym
= rs6000_savres_routine_sym (info
, savep
, gpr
, lr
);
18274 RTVEC_ELT (p
, offset
++) = gen_rtx_USE (VOIDmode
, sym
);
18275 RTVEC_ELT (p
, offset
++)
18276 = gen_rtx_USE (VOIDmode
,
18277 gen_rtx_REG (Pmode
, DEFAULT_ABI
!= ABI_AIX
? 11
18281 for (i
= 0; i
< end_reg
- start_reg
; i
++)
18283 rtx addr
, reg
, mem
;
18284 reg
= gen_rtx_REG (reg_mode
, start_reg
+ i
);
18285 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
18286 GEN_INT (save_area_offset
+ reg_size
*i
));
18287 mem
= gen_frame_mem (reg_mode
, addr
);
18289 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
,
18291 savep
? reg
: mem
);
18296 rtx addr
, reg
, mem
;
18297 reg
= gen_rtx_REG (Pmode
, 0);
18298 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
18299 GEN_INT (info
->lr_save_offset
));
18300 mem
= gen_frame_mem (Pmode
, addr
);
18301 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
18304 return gen_rtx_PARALLEL (VOIDmode
, p
);
18307 /* Determine whether the gp REG is really used. */
18310 rs6000_reg_live_or_pic_offset_p (int reg
)
18312 return ((df_regs_ever_live_p (reg
)
18313 && (!call_used_regs
[reg
]
18314 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
18315 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
18316 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
18317 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
18318 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))));
18322 SAVRES_MULTIPLE
= 0x1,
18323 SAVRES_INLINE_FPRS
= 0x2,
18324 SAVRES_INLINE_GPRS
= 0x4,
18325 SAVRES_NOINLINE_GPRS_SAVES_LR
= 0x8,
18326 SAVRES_NOINLINE_FPRS_SAVES_LR
= 0x10,
18327 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR
= 0x20
18330 /* Determine the strategy for savings/restoring registers. */
18333 rs6000_savres_strategy (rs6000_stack_t
*info
, bool savep
,
18334 int using_static_chain_p
, int sibcall
)
18336 bool using_multiple_p
;
18338 bool savres_fprs_inline
;
18339 bool savres_gprs_inline
;
18340 bool noclobber_global_gprs
18341 = no_global_regs_above (info
->first_gp_reg_save
, /*gpr=*/true);
18344 using_multiple_p
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
18345 && (!TARGET_SPE_ABI
18346 || info
->spe_64bit_regs_used
== 0)
18347 && info
->first_gp_reg_save
< 31
18348 && noclobber_global_gprs
);
18349 /* Don't bother to try to save things out-of-line if r11 is occupied
18350 by the static chain. It would require too much fiddling and the
18351 static chain is rarely used anyway. */
18352 common
= (using_static_chain_p
18354 || crtl
->calls_eh_return
18355 || !info
->lr_save_p
18356 || cfun
->machine
->ra_need_lr
18357 || info
->total_size
> 32767);
18358 savres_fprs_inline
= (common
18359 || info
->first_fp_reg_save
== 64
18360 || !no_global_regs_above (info
->first_fp_reg_save
,
18362 /* The out-of-line FP routines use
18363 double-precision stores; we can't use those
18364 routines if we don't have such stores. */
18365 || (TARGET_HARD_FLOAT
&& !TARGET_DOUBLE_FLOAT
)
18366 || FP_SAVE_INLINE (info
->first_fp_reg_save
));
18367 savres_gprs_inline
= (common
18368 /* Saving CR interferes with the exit routines
18369 used on the SPE, so just punt here. */
18372 && info
->spe_64bit_regs_used
!= 0
18373 && info
->cr_save_p
!= 0)
18374 || info
->first_gp_reg_save
== 32
18375 || !noclobber_global_gprs
18376 || GP_SAVE_INLINE (info
->first_gp_reg_save
));
18379 /* If we are going to use store multiple, then don't even bother
18380 with the out-of-line routines, since the store-multiple instruction
18381 will always be smaller. */
18382 savres_gprs_inline
= savres_gprs_inline
|| using_multiple_p
;
18385 /* The situation is more complicated with load multiple. We'd
18386 prefer to use the out-of-line routines for restores, since the
18387 "exit" out-of-line routines can handle the restore of LR and
18388 the frame teardown. But we can only use the out-of-line
18389 routines if we know that we've used store multiple or
18390 out-of-line routines in the prologue, i.e. if we've saved all
18391 the registers from first_gp_reg_save. Otherwise, we risk
18392 loading garbage from the stack. Furthermore, we can only use
18393 the "exit" out-of-line gpr restore if we haven't saved any
18395 bool saved_all
= !savres_gprs_inline
|| using_multiple_p
;
18397 if (saved_all
&& info
->first_fp_reg_save
!= 64)
18398 /* We can't use the exit routine; use load multiple if it's
18400 savres_gprs_inline
= savres_gprs_inline
|| using_multiple_p
;
18403 strategy
= (using_multiple_p
18404 | (savres_fprs_inline
<< 1)
18405 | (savres_gprs_inline
<< 2));
18406 #ifdef POWERPC_LINUX
18409 if (!savres_fprs_inline
)
18410 strategy
|= SAVRES_NOINLINE_FPRS_SAVES_LR
;
18411 else if (!savres_gprs_inline
&& info
->first_fp_reg_save
== 64)
18412 strategy
|= SAVRES_NOINLINE_GPRS_SAVES_LR
;
18415 if (TARGET_AIX
&& !savres_fprs_inline
)
18416 strategy
|= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR
;
18421 /* Emit function prologue as insns. */
18424 rs6000_emit_prologue (void)
18426 rs6000_stack_t
*info
= rs6000_stack_info ();
18427 enum machine_mode reg_mode
= Pmode
;
18428 int reg_size
= TARGET_32BIT
? 4 : 8;
18429 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
18430 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
18431 rtx frame_reg_rtx
= sp_reg_rtx
;
18432 rtx cr_save_rtx
= NULL_RTX
;
18435 int saving_FPRs_inline
;
18436 int saving_GPRs_inline
;
18437 int using_store_multiple
;
18438 int using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
18439 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
18440 && call_used_regs
[STATIC_CHAIN_REGNUM
]);
18441 HOST_WIDE_INT sp_offset
= 0;
18443 if (TARGET_FIX_AND_CONTINUE
)
18445 /* gdb on darwin arranges to forward a function from the old
18446 address by modifying the first 5 instructions of the function
18447 to branch to the overriding function. This is necessary to
18448 permit function pointers that point to the old function to
18449 actually forward to the new function. */
18450 emit_insn (gen_nop ());
18451 emit_insn (gen_nop ());
18452 emit_insn (gen_nop ());
18453 emit_insn (gen_nop ());
18454 emit_insn (gen_nop ());
18457 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
18459 reg_mode
= V2SImode
;
18463 strategy
= rs6000_savres_strategy (info
, /*savep=*/true,
18464 /*static_chain_p=*/using_static_chain_p
,
18466 using_store_multiple
= strategy
& SAVRES_MULTIPLE
;
18467 saving_FPRs_inline
= strategy
& SAVRES_INLINE_FPRS
;
18468 saving_GPRs_inline
= strategy
& SAVRES_INLINE_GPRS
;
18470 /* For V.4, update stack before we do any saving and set back pointer. */
18471 if (! WORLD_SAVE_P (info
)
18473 && (DEFAULT_ABI
== ABI_V4
18474 || crtl
->calls_eh_return
))
18476 bool need_r11
= (TARGET_SPE
18477 ? (!saving_GPRs_inline
18478 && info
->spe_64bit_regs_used
== 0)
18479 : (!saving_FPRs_inline
|| !saving_GPRs_inline
));
18480 if (info
->total_size
< 32767)
18481 sp_offset
= info
->total_size
;
18483 frame_reg_rtx
= (need_r11
18484 ? gen_rtx_REG (Pmode
, 11)
18486 rs6000_emit_allocate_stack (info
->total_size
,
18487 (frame_reg_rtx
!= sp_reg_rtx
18488 && (info
->cr_save_p
18490 || info
->first_fp_reg_save
< 64
18491 || info
->first_gp_reg_save
< 32
18494 if (frame_reg_rtx
!= sp_reg_rtx
)
18495 rs6000_emit_stack_tie ();
18498 /* Handle world saves specially here. */
18499 if (WORLD_SAVE_P (info
))
18506 /* save_world expects lr in r0. */
18507 reg0
= gen_rtx_REG (Pmode
, 0);
18508 if (info
->lr_save_p
)
18510 insn
= emit_move_insn (reg0
,
18511 gen_rtx_REG (Pmode
, LR_REGNO
));
18512 RTX_FRAME_RELATED_P (insn
) = 1;
18515 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
18516 assumptions about the offsets of various bits of the stack
18518 gcc_assert (info
->gp_save_offset
== -220
18519 && info
->fp_save_offset
== -144
18520 && info
->lr_save_offset
== 8
18521 && info
->cr_save_offset
== 4
18524 && (!crtl
->calls_eh_return
18525 || info
->ehrd_offset
== -432)
18526 && info
->vrsave_save_offset
== -224
18527 && info
->altivec_save_offset
== -416);
18529 treg
= gen_rtx_REG (SImode
, 11);
18530 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
18532 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
18533 in R11. It also clobbers R12, so beware! */
18535 /* Preserve CR2 for save_world prologues */
18537 sz
+= 32 - info
->first_gp_reg_save
;
18538 sz
+= 64 - info
->first_fp_reg_save
;
18539 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
18540 p
= rtvec_alloc (sz
);
18542 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
18543 gen_rtx_REG (SImode
,
18545 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
18546 gen_rtx_SYMBOL_REF (Pmode
,
18548 /* We do floats first so that the instruction pattern matches
18550 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
18552 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
18553 ? DFmode
: SFmode
),
18554 info
->first_fp_reg_save
+ i
);
18555 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
18556 GEN_INT (info
->fp_save_offset
18557 + sp_offset
+ 8 * i
));
18558 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
18559 ? DFmode
: SFmode
), addr
);
18561 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
18563 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
18565 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
18566 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
18567 GEN_INT (info
->altivec_save_offset
18568 + sp_offset
+ 16 * i
));
18569 rtx mem
= gen_frame_mem (V4SImode
, addr
);
18571 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
18573 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
18575 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
18576 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
18577 GEN_INT (info
->gp_save_offset
18578 + sp_offset
+ reg_size
* i
));
18579 rtx mem
= gen_frame_mem (reg_mode
, addr
);
18581 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
18585 /* CR register traditionally saved as CR2. */
18586 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
18587 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
18588 GEN_INT (info
->cr_save_offset
18590 rtx mem
= gen_frame_mem (reg_mode
, addr
);
18592 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
18594 /* Explain about use of R0. */
18595 if (info
->lr_save_p
)
18597 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
18598 GEN_INT (info
->lr_save_offset
18600 rtx mem
= gen_frame_mem (reg_mode
, addr
);
18602 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg0
);
18604 /* Explain what happens to the stack pointer. */
18606 rtx newval
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
, treg
);
18607 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, sp_reg_rtx
, newval
);
18610 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
18611 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
18612 treg
, GEN_INT (-info
->total_size
));
18613 sp_offset
= info
->total_size
;
18616 /* If we use the link register, get it into r0. */
18617 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
18619 rtx addr
, reg
, mem
;
18621 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
18622 gen_rtx_REG (Pmode
, LR_REGNO
));
18623 RTX_FRAME_RELATED_P (insn
) = 1;
18625 if (!(strategy
& (SAVRES_NOINLINE_GPRS_SAVES_LR
18626 | SAVRES_NOINLINE_FPRS_SAVES_LR
)))
18628 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
18629 GEN_INT (info
->lr_save_offset
+ sp_offset
));
18630 reg
= gen_rtx_REG (Pmode
, 0);
18631 mem
= gen_rtx_MEM (Pmode
, addr
);
18632 /* This should not be of rs6000_sr_alias_set, because of
18633 __builtin_return_address. */
18635 insn
= emit_move_insn (mem
, reg
);
18636 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
18637 NULL_RTX
, NULL_RTX
);
18641 /* If we need to save CR, put it into r12 or r11. */
18642 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
18647 = gen_rtx_REG (SImode
, DEFAULT_ABI
== ABI_AIX
&& !saving_GPRs_inline
18649 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
18650 RTX_FRAME_RELATED_P (insn
) = 1;
18651 /* Now, there's no way that dwarf2out_frame_debug_expr is going
18652 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
18653 But that's OK. All we have to do is specify that _one_ condition
18654 code register is saved in this stack slot. The thrower's epilogue
18655 will then restore all the call-saved registers.
18656 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
18657 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
18658 gen_rtx_REG (SImode
, CR2_REGNO
));
18659 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
18662 /* Do any required saving of fpr's. If only one or two to save, do
18663 it ourselves. Otherwise, call function. */
18664 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
18667 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
18668 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
18669 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
18670 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
,
18671 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
18673 info
->first_fp_reg_save
+ i
,
18674 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
18677 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
18681 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
18682 info
->fp_save_offset
+ sp_offset
,
18684 /*savep=*/true, /*gpr=*/false,
18686 & SAVRES_NOINLINE_FPRS_SAVES_LR
)
18688 insn
= emit_insn (par
);
18689 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
18690 NULL_RTX
, NULL_RTX
);
18693 /* Save GPRs. This is done as a PARALLEL if we are using
18694 the store-multiple instructions. */
18695 if (!WORLD_SAVE_P (info
)
18697 && info
->spe_64bit_regs_used
!= 0
18698 && info
->first_gp_reg_save
!= 32)
18701 rtx spe_save_area_ptr
;
18703 /* Determine whether we can address all of the registers that need
18704 to be saved with an offset from the stack pointer that fits in
18705 the small const field for SPE memory instructions. */
18706 int spe_regs_addressable_via_sp
18707 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
18708 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
18709 && saving_GPRs_inline
);
18712 if (spe_regs_addressable_via_sp
)
18714 spe_save_area_ptr
= frame_reg_rtx
;
18715 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
18719 /* Make r11 point to the start of the SPE save area. We need
18720 to be careful here if r11 is holding the static chain. If
18721 it is, then temporarily save it in r0. We would use r0 as
18722 our base register here, but using r0 as a base register in
18723 loads and stores means something different from what we
18725 int ool_adjust
= (saving_GPRs_inline
18727 : (info
->first_gp_reg_save
18728 - (FIRST_SAVRES_REGISTER
+1))*8);
18729 HOST_WIDE_INT offset
= (info
->spe_gp_save_offset
18730 + sp_offset
- ool_adjust
);
18732 if (using_static_chain_p
)
18734 rtx r0
= gen_rtx_REG (Pmode
, 0);
18735 gcc_assert (info
->first_gp_reg_save
> 11);
18737 emit_move_insn (r0
, gen_rtx_REG (Pmode
, 11));
18740 spe_save_area_ptr
= gen_rtx_REG (Pmode
, 11);
18741 insn
= emit_insn (gen_addsi3 (spe_save_area_ptr
,
18743 GEN_INT (offset
)));
18744 /* We need to make sure the move to r11 gets noted for
18745 properly outputting unwind information. */
18746 if (!saving_GPRs_inline
)
18747 rs6000_frame_related (insn
, frame_reg_rtx
, offset
,
18748 NULL_RTX
, NULL_RTX
);
18752 if (saving_GPRs_inline
)
18754 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
18755 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
18757 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
18758 rtx offset
, addr
, mem
;
18760 /* We're doing all this to ensure that the offset fits into
18761 the immediate offset of 'evstdd'. */
18762 gcc_assert (SPE_CONST_OFFSET_OK (reg_size
* i
+ spe_offset
));
18764 offset
= GEN_INT (reg_size
* i
+ spe_offset
);
18765 addr
= gen_rtx_PLUS (Pmode
, spe_save_area_ptr
, offset
);
18766 mem
= gen_rtx_MEM (V2SImode
, addr
);
18768 insn
= emit_move_insn (mem
, reg
);
18770 rs6000_frame_related (insn
, spe_save_area_ptr
,
18771 info
->spe_gp_save_offset
18772 + sp_offset
+ reg_size
* i
,
18773 offset
, const0_rtx
);
18780 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
18782 /*savep=*/true, /*gpr=*/true,
18784 insn
= emit_insn (par
);
18785 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
18786 NULL_RTX
, NULL_RTX
);
18790 /* Move the static chain pointer back. */
18791 if (using_static_chain_p
&& !spe_regs_addressable_via_sp
)
18792 emit_move_insn (gen_rtx_REG (Pmode
, 11), gen_rtx_REG (Pmode
, 0));
18794 else if (!WORLD_SAVE_P (info
) && !saving_GPRs_inline
)
18798 /* Need to adjust r11 (r12) if we saved any FPRs. */
18799 if (info
->first_fp_reg_save
!= 64)
18801 rtx dest_reg
= gen_rtx_REG (reg_mode
, DEFAULT_ABI
== ABI_AIX
18803 rtx offset
= GEN_INT (sp_offset
18804 + (-8 * (64-info
->first_fp_reg_save
)));
18805 emit_insn (gen_add3_insn (dest_reg
, frame_reg_rtx
, offset
));
18808 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
18809 info
->gp_save_offset
+ sp_offset
,
18811 /*savep=*/true, /*gpr=*/true,
18813 & SAVRES_NOINLINE_GPRS_SAVES_LR
)
18815 insn
= emit_insn (par
);
18816 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
18817 NULL_RTX
, NULL_RTX
);
18819 else if (!WORLD_SAVE_P (info
) && using_store_multiple
)
18823 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
18824 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
18826 rtx addr
, reg
, mem
;
18827 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
18828 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
18829 GEN_INT (info
->gp_save_offset
18832 mem
= gen_frame_mem (reg_mode
, addr
);
18834 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
18836 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
18837 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
18838 NULL_RTX
, NULL_RTX
);
18840 else if (!WORLD_SAVE_P (info
))
18843 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
18844 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
18846 rtx addr
, reg
, mem
;
18847 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
18849 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
18850 GEN_INT (info
->gp_save_offset
18853 mem
= gen_frame_mem (reg_mode
, addr
);
18855 insn
= emit_move_insn (mem
, reg
);
18856 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
18857 NULL_RTX
, NULL_RTX
);
18861 /* ??? There's no need to emit actual instructions here, but it's the
18862 easiest way to get the frame unwind information emitted. */
18863 if (crtl
->calls_eh_return
)
18865 unsigned int i
, regno
;
18867 /* In AIX ABI we need to pretend we save r2 here. */
18870 rtx addr
, reg
, mem
;
18872 reg
= gen_rtx_REG (reg_mode
, 2);
18873 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
18874 GEN_INT (sp_offset
+ 5 * reg_size
));
18875 mem
= gen_frame_mem (reg_mode
, addr
);
18877 insn
= emit_move_insn (mem
, reg
);
18878 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
18879 NULL_RTX
, NULL_RTX
);
18880 PATTERN (insn
) = gen_blockage ();
18885 regno
= EH_RETURN_DATA_REGNO (i
);
18886 if (regno
== INVALID_REGNUM
)
18889 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
18890 info
->ehrd_offset
+ sp_offset
18891 + reg_size
* (int) i
,
18896 /* Save CR if we use any that must be preserved. */
18897 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
18899 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
18900 GEN_INT (info
->cr_save_offset
+ sp_offset
));
18901 rtx mem
= gen_frame_mem (SImode
, addr
);
18902 /* See the large comment above about why CR2_REGNO is used. */
18903 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
18905 /* If r12 was used to hold the original sp, copy cr into r0 now
18907 if (REGNO (frame_reg_rtx
) == 12)
18911 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
18912 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
18913 RTX_FRAME_RELATED_P (insn
) = 1;
18914 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
18915 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
18917 insn
= emit_move_insn (mem
, cr_save_rtx
);
18919 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
18920 NULL_RTX
, NULL_RTX
);
18923 /* Update stack and set back pointer unless this is V.4,
18924 for which it was done previously. */
18925 if (!WORLD_SAVE_P (info
) && info
->push_p
18926 && !(DEFAULT_ABI
== ABI_V4
|| crtl
->calls_eh_return
))
18928 if (info
->total_size
< 32767)
18929 sp_offset
= info
->total_size
;
18931 frame_reg_rtx
= frame_ptr_rtx
;
18932 rs6000_emit_allocate_stack (info
->total_size
,
18933 (frame_reg_rtx
!= sp_reg_rtx
18934 && ((info
->altivec_size
!= 0)
18935 || (info
->vrsave_mask
!= 0)
18938 if (frame_reg_rtx
!= sp_reg_rtx
)
18939 rs6000_emit_stack_tie ();
18942 /* Set frame pointer, if needed. */
18943 if (frame_pointer_needed
)
18945 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
18947 RTX_FRAME_RELATED_P (insn
) = 1;
18950 /* Save AltiVec registers if needed. Save here because the red zone does
18951 not include AltiVec registers. */
18952 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
18956 /* There should be a non inline version of this, for when we
18957 are saving lots of vector registers. */
18958 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
18959 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
18961 rtx areg
, savereg
, mem
;
18964 offset
= info
->altivec_save_offset
+ sp_offset
18965 + 16 * (i
- info
->first_altivec_reg_save
);
18967 savereg
= gen_rtx_REG (V4SImode
, i
);
18969 areg
= gen_rtx_REG (Pmode
, 0);
18970 emit_move_insn (areg
, GEN_INT (offset
));
18972 /* AltiVec addressing mode is [reg+reg]. */
18973 mem
= gen_frame_mem (V4SImode
,
18974 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
18976 insn
= emit_move_insn (mem
, savereg
);
18978 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
18979 areg
, GEN_INT (offset
));
18983 /* VRSAVE is a bit vector representing which AltiVec registers
18984 are used. The OS uses this to determine which vector
18985 registers to save on a context switch. We need to save
18986 VRSAVE on the stack frame, add whatever AltiVec registers we
18987 used in this function, and do the corresponding magic in the
18990 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
18991 && info
->vrsave_mask
!= 0)
18993 rtx reg
, mem
, vrsave
;
18996 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
18997 as frame_reg_rtx and r11 as the static chain pointer for
18998 nested functions. */
18999 reg
= gen_rtx_REG (SImode
, 0);
19000 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
19002 emit_insn (gen_get_vrsave_internal (reg
));
19004 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
19006 if (!WORLD_SAVE_P (info
))
19009 offset
= info
->vrsave_save_offset
+ sp_offset
;
19010 mem
= gen_frame_mem (SImode
,
19011 gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19012 GEN_INT (offset
)));
19013 insn
= emit_move_insn (mem
, reg
);
19016 /* Include the registers in the mask. */
19017 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
19019 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
19022 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19023 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
19024 || (DEFAULT_ABI
== ABI_V4
19025 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
19026 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
)))
19028 /* If emit_load_toc_table will use the link register, we need to save
19029 it. We use R12 for this purpose because emit_load_toc_table
19030 can use register 0. This allows us to use a plain 'blr' to return
19031 from the procedure more often. */
19032 int save_LR_around_toc_setup
= (TARGET_ELF
19033 && DEFAULT_ABI
!= ABI_AIX
19035 && ! info
->lr_save_p
19036 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
19037 if (save_LR_around_toc_setup
)
19039 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
19041 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
19042 RTX_FRAME_RELATED_P (insn
) = 1;
19044 rs6000_emit_load_toc_table (TRUE
);
19046 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
19047 RTX_FRAME_RELATED_P (insn
) = 1;
19050 rs6000_emit_load_toc_table (TRUE
);
19054 if (DEFAULT_ABI
== ABI_DARWIN
19055 && flag_pic
&& crtl
->uses_pic_offset_table
)
19057 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
19058 rtx src
= gen_rtx_SYMBOL_REF (Pmode
, MACHOPIC_FUNCTION_BASE_NAME
);
19060 /* Save and restore LR locally around this call (in R0). */
19061 if (!info
->lr_save_p
)
19062 emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
);
19064 emit_insn (gen_load_macho_picbase (src
));
19066 emit_move_insn (gen_rtx_REG (Pmode
,
19067 RS6000_PIC_OFFSET_TABLE_REGNUM
),
19070 if (!info
->lr_save_p
)
19071 emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0));
19076 /* Write function prologue. */
19079 rs6000_output_function_prologue (FILE *file
,
19080 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
19082 rs6000_stack_t
*info
= rs6000_stack_info ();
19084 if (TARGET_DEBUG_STACK
)
19085 debug_stack_info (info
);
19087 /* Write .extern for any function we will call to save and restore
19089 if (info
->first_fp_reg_save
< 64
19090 && !FP_SAVE_INLINE (info
->first_fp_reg_save
))
19093 int regno
= info
->first_fp_reg_save
- 32;
19095 name
= rs6000_savres_routine_name (info
, regno
, /*savep=*/true,
19096 /*gpr=*/false, /*lr=*/false);
19097 fprintf (file
, "\t.extern %s\n", name
);
19099 name
= rs6000_savres_routine_name (info
, regno
, /*savep=*/false,
19100 /*gpr=*/false, /*lr=*/true);
19101 fprintf (file
, "\t.extern %s\n", name
);
19104 /* Write .extern for AIX common mode routines, if needed. */
19105 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
19107 fputs ("\t.extern __mulh\n", file
);
19108 fputs ("\t.extern __mull\n", file
);
19109 fputs ("\t.extern __divss\n", file
);
19110 fputs ("\t.extern __divus\n", file
);
19111 fputs ("\t.extern __quoss\n", file
);
19112 fputs ("\t.extern __quous\n", file
);
19113 common_mode_defined
= 1;
19116 if (! HAVE_prologue
)
19122 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19123 the "toplevel" insn chain. */
19124 emit_note (NOTE_INSN_DELETED
);
19125 rs6000_emit_prologue ();
19126 emit_note (NOTE_INSN_DELETED
);
19128 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19132 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
19134 INSN_ADDRESSES_NEW (insn
, addr
);
19139 prologue
= get_insns ();
19142 if (TARGET_DEBUG_STACK
)
19143 debug_rtx_list (prologue
, 100);
19145 emit_insn_before_noloc (prologue
, BB_HEAD (ENTRY_BLOCK_PTR
->next_bb
),
19149 rs6000_pic_labelno
++;
19152 /* Non-zero if vmx regs are restored before the frame pop, zero if
19153 we restore after the pop when possible. */
19154 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19156 /* Reload CR from REG. */
19159 rs6000_restore_saved_cr (rtx reg
, int using_mfcr_multiple
)
19164 if (using_mfcr_multiple
)
19166 for (i
= 0; i
< 8; i
++)
19167 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
19169 gcc_assert (count
);
19172 if (using_mfcr_multiple
&& count
> 1)
19177 p
= rtvec_alloc (count
);
19180 for (i
= 0; i
< 8; i
++)
19181 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
19183 rtvec r
= rtvec_alloc (2);
19184 RTVEC_ELT (r
, 0) = reg
;
19185 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
19186 RTVEC_ELT (p
, ndx
) =
19187 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
19188 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
19191 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
19192 gcc_assert (ndx
== count
);
19195 for (i
= 0; i
< 8; i
++)
19196 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
19198 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
19204 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19205 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19206 below stack pointer not cloberred by signals. */
19209 offset_below_red_zone_p (HOST_WIDE_INT offset
)
19211 return offset
< (DEFAULT_ABI
== ABI_V4
19213 : TARGET_32BIT
? -220 : -288);
19216 /* Emit function epilogue as insns. */
19219 rs6000_emit_epilogue (int sibcall
)
19221 rs6000_stack_t
*info
;
19222 int restoring_GPRs_inline
;
19223 int restoring_FPRs_inline
;
19224 int using_load_multiple
;
19225 int using_mtcr_multiple
;
19226 int use_backchain_to_restore_sp
;
19230 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
19231 rtx frame_reg_rtx
= sp_reg_rtx
;
19232 rtx cfa_restores
= NULL_RTX
;
19234 rtx cr_save_reg
= NULL_RTX
;
19235 enum machine_mode reg_mode
= Pmode
;
19236 int reg_size
= TARGET_32BIT
? 4 : 8;
19239 info
= rs6000_stack_info ();
19241 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
19243 reg_mode
= V2SImode
;
19247 strategy
= rs6000_savres_strategy (info
, /*savep=*/false,
19248 /*static_chain_p=*/0, sibcall
);
19249 using_load_multiple
= strategy
& SAVRES_MULTIPLE
;
19250 restoring_FPRs_inline
= strategy
& SAVRES_INLINE_FPRS
;
19251 restoring_GPRs_inline
= strategy
& SAVRES_INLINE_GPRS
;
19252 using_mtcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
19253 || rs6000_cpu
== PROCESSOR_PPC603
19254 || rs6000_cpu
== PROCESSOR_PPC750
19256 /* Restore via the backchain when we have a large frame, since this
19257 is more efficient than an addis, addi pair. The second condition
19258 here will not trigger at the moment; We don't actually need a
19259 frame pointer for alloca, but the generic parts of the compiler
19260 give us one anyway. */
19261 use_backchain_to_restore_sp
= (info
->total_size
> 32767
19262 || info
->total_size
19263 + (info
->lr_save_p
? info
->lr_save_offset
: 0)
19265 || (cfun
->calls_alloca
19266 && !frame_pointer_needed
));
19267 restore_lr
= (info
->lr_save_p
19268 && (restoring_FPRs_inline
19269 || (strategy
& SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR
))
19270 && (restoring_GPRs_inline
19271 || info
->first_fp_reg_save
< 64));
19273 if (WORLD_SAVE_P (info
))
19277 const char *alloc_rname
;
19280 /* eh_rest_world_r10 will return to the location saved in the LR
19281 stack slot (which is not likely to be our caller.)
19282 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19283 rest_world is similar, except any R10 parameter is ignored.
19284 The exception-handling stuff that was here in 2.95 is no
19285 longer necessary. */
19289 + 32 - info
->first_gp_reg_save
19290 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
19291 + 63 + 1 - info
->first_fp_reg_save
);
19293 strcpy (rname
, ((crtl
->calls_eh_return
) ?
19294 "*eh_rest_world_r10" : "*rest_world"));
19295 alloc_rname
= ggc_strdup (rname
);
19298 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
19299 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
19300 gen_rtx_REG (Pmode
,
19303 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
19304 /* The instruction pattern requires a clobber here;
19305 it is shared with the restVEC helper. */
19307 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
19310 /* CR register traditionally saved as CR2. */
19311 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
19312 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19313 GEN_INT (info
->cr_save_offset
));
19314 rtx mem
= gen_frame_mem (reg_mode
, addr
);
19316 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
19319 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
19321 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
19322 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19323 GEN_INT (info
->gp_save_offset
19325 rtx mem
= gen_frame_mem (reg_mode
, addr
);
19327 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
19329 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
19331 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
19332 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19333 GEN_INT (info
->altivec_save_offset
19335 rtx mem
= gen_frame_mem (V4SImode
, addr
);
19337 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
19339 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
19341 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
19342 ? DFmode
: SFmode
),
19343 info
->first_fp_reg_save
+ i
);
19344 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19345 GEN_INT (info
->fp_save_offset
19347 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
19348 ? DFmode
: SFmode
), addr
);
19350 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
19353 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
19355 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
19357 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
19359 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
19361 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
19362 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
19367 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19369 sp_offset
= info
->total_size
;
19371 /* Restore AltiVec registers if we must do so before adjusting the
19373 if (TARGET_ALTIVEC_ABI
19374 && info
->altivec_size
!= 0
19375 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19376 || (DEFAULT_ABI
!= ABI_V4
19377 && offset_below_red_zone_p (info
->altivec_save_offset
))))
19381 if (use_backchain_to_restore_sp
)
19383 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
19384 emit_move_insn (frame_reg_rtx
,
19385 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
19388 else if (frame_pointer_needed
)
19389 frame_reg_rtx
= hard_frame_pointer_rtx
;
19391 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
19392 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
19394 rtx addr
, areg
, mem
, reg
;
19396 areg
= gen_rtx_REG (Pmode
, 0);
19398 (areg
, GEN_INT (info
->altivec_save_offset
19400 + 16 * (i
- info
->first_altivec_reg_save
)));
19402 /* AltiVec addressing mode is [reg+reg]. */
19403 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
19404 mem
= gen_frame_mem (V4SImode
, addr
);
19406 reg
= gen_rtx_REG (V4SImode
, i
);
19407 emit_move_insn (reg
, mem
);
19408 if (offset_below_red_zone_p (info
->altivec_save_offset
19409 + (i
- info
->first_altivec_reg_save
)
19411 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
19416 /* Restore VRSAVE if we must do so before adjusting the stack. */
19418 && TARGET_ALTIVEC_VRSAVE
19419 && info
->vrsave_mask
!= 0
19420 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19421 || (DEFAULT_ABI
!= ABI_V4
19422 && offset_below_red_zone_p (info
->vrsave_save_offset
))))
19424 rtx addr
, mem
, reg
;
19426 if (frame_reg_rtx
== sp_reg_rtx
)
19428 if (use_backchain_to_restore_sp
)
19430 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
19431 emit_move_insn (frame_reg_rtx
,
19432 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
19435 else if (frame_pointer_needed
)
19436 frame_reg_rtx
= hard_frame_pointer_rtx
;
19439 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19440 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
19441 mem
= gen_frame_mem (SImode
, addr
);
19442 reg
= gen_rtx_REG (SImode
, 12);
19443 emit_move_insn (reg
, mem
);
19445 emit_insn (generate_set_vrsave (reg
, info
, 1));
19449 /* If we have a large stack frame, restore the old stack pointer
19450 using the backchain. */
19451 if (use_backchain_to_restore_sp
)
19453 if (frame_reg_rtx
== sp_reg_rtx
)
19455 /* Under V.4, don't reset the stack pointer until after we're done
19456 loading the saved registers. */
19457 if (DEFAULT_ABI
== ABI_V4
)
19458 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
19460 insn
= emit_move_insn (frame_reg_rtx
,
19461 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
19464 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19465 && DEFAULT_ABI
== ABI_V4
)
19466 /* frame_reg_rtx has been set up by the altivec restore. */
19470 insn
= emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
19471 frame_reg_rtx
= sp_reg_rtx
;
19474 /* If we have a frame pointer, we can restore the old stack pointer
19476 else if (frame_pointer_needed
)
19478 frame_reg_rtx
= sp_reg_rtx
;
19479 if (DEFAULT_ABI
== ABI_V4
)
19480 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
19482 insn
= emit_insn (gen_add3_insn (frame_reg_rtx
, hard_frame_pointer_rtx
,
19483 GEN_INT (info
->total_size
)));
19486 else if (info
->push_p
19487 && DEFAULT_ABI
!= ABI_V4
19488 && !crtl
->calls_eh_return
)
19490 insn
= emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
,
19491 GEN_INT (info
->total_size
)));
19494 if (insn
&& frame_reg_rtx
== sp_reg_rtx
)
19498 REG_NOTES (insn
) = cfa_restores
;
19499 cfa_restores
= NULL_RTX
;
19501 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
19502 RTX_FRAME_RELATED_P (insn
) = 1;
19505 /* Restore AltiVec registers if we have not done so already. */
19506 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19507 && TARGET_ALTIVEC_ABI
19508 && info
->altivec_size
!= 0
19509 && (DEFAULT_ABI
== ABI_V4
19510 || !offset_below_red_zone_p (info
->altivec_save_offset
)))
19514 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
19515 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
19517 rtx addr
, areg
, mem
, reg
;
19519 areg
= gen_rtx_REG (Pmode
, 0);
19521 (areg
, GEN_INT (info
->altivec_save_offset
19523 + 16 * (i
- info
->first_altivec_reg_save
)));
19525 /* AltiVec addressing mode is [reg+reg]. */
19526 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
19527 mem
= gen_frame_mem (V4SImode
, addr
);
19529 reg
= gen_rtx_REG (V4SImode
, i
);
19530 emit_move_insn (reg
, mem
);
19531 if (DEFAULT_ABI
== ABI_V4
)
19532 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
19537 /* Restore VRSAVE if we have not done so already. */
19538 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19540 && TARGET_ALTIVEC_VRSAVE
19541 && info
->vrsave_mask
!= 0
19542 && (DEFAULT_ABI
== ABI_V4
19543 || !offset_below_red_zone_p (info
->vrsave_save_offset
)))
19545 rtx addr
, mem
, reg
;
19547 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19548 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
19549 mem
= gen_frame_mem (SImode
, addr
);
19550 reg
= gen_rtx_REG (SImode
, 12);
19551 emit_move_insn (reg
, mem
);
19553 emit_insn (generate_set_vrsave (reg
, info
, 1));
19556 /* Get the old lr if we saved it. If we are restoring registers
19557 out-of-line, then the out-of-line routines can do this for us. */
19558 if (restore_lr
&& restoring_GPRs_inline
)
19560 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
19561 info
->lr_save_offset
+ sp_offset
);
19563 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
19566 /* Get the old cr if we saved it. */
19567 if (info
->cr_save_p
)
19569 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19570 GEN_INT (info
->cr_save_offset
+ sp_offset
));
19571 rtx mem
= gen_frame_mem (SImode
, addr
);
19573 cr_save_reg
= gen_rtx_REG (SImode
,
19574 DEFAULT_ABI
== ABI_AIX
19575 && !restoring_GPRs_inline
19576 && info
->first_fp_reg_save
< 64
19578 emit_move_insn (cr_save_reg
, mem
);
19581 /* Set LR here to try to overlap restores below. LR is always saved
19582 above incoming stack, so it never needs REG_CFA_RESTORE. */
19583 if (restore_lr
&& restoring_GPRs_inline
)
19584 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
19585 gen_rtx_REG (Pmode
, 0));
19587 /* Load exception handler data registers, if needed. */
19588 if (crtl
->calls_eh_return
)
19590 unsigned int i
, regno
;
19594 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19595 GEN_INT (sp_offset
+ 5 * reg_size
));
19596 rtx mem
= gen_frame_mem (reg_mode
, addr
);
19598 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
19605 regno
= EH_RETURN_DATA_REGNO (i
);
19606 if (regno
== INVALID_REGNUM
)
19609 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
19610 info
->ehrd_offset
+ sp_offset
19611 + reg_size
* (int) i
);
19613 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
19617 /* Restore GPRs. This is done as a PARALLEL if we are using
19618 the load-multiple instructions. */
19620 && info
->spe_64bit_regs_used
!= 0
19621 && info
->first_gp_reg_save
!= 32)
19623 /* Determine whether we can address all of the registers that need
19624 to be saved with an offset from the stack pointer that fits in
19625 the small const field for SPE memory instructions. */
19626 int spe_regs_addressable_via_sp
19627 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
19628 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
19629 && restoring_GPRs_inline
);
19632 if (spe_regs_addressable_via_sp
)
19633 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
19636 rtx old_frame_reg_rtx
= frame_reg_rtx
;
19637 /* Make r11 point to the start of the SPE save area. We worried about
19638 not clobbering it when we were saving registers in the prologue.
19639 There's no need to worry here because the static chain is passed
19640 anew to every function. */
19641 int ool_adjust
= (restoring_GPRs_inline
19643 : (info
->first_gp_reg_save
19644 - (FIRST_SAVRES_REGISTER
+1))*8);
19646 if (frame_reg_rtx
== sp_reg_rtx
)
19647 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
19648 emit_insn (gen_addsi3 (frame_reg_rtx
, old_frame_reg_rtx
,
19649 GEN_INT (info
->spe_gp_save_offset
19652 /* Keep the invariant that frame_reg_rtx + sp_offset points
19653 at the top of the stack frame. */
19654 sp_offset
= -info
->spe_gp_save_offset
;
19659 if (restoring_GPRs_inline
)
19661 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
19662 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
19664 rtx offset
, addr
, mem
, reg
;
19666 /* We're doing all this to ensure that the immediate offset
19667 fits into the immediate field of 'evldd'. */
19668 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset
+ reg_size
* i
));
19670 offset
= GEN_INT (spe_offset
+ reg_size
* i
);
19671 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, offset
);
19672 mem
= gen_rtx_MEM (V2SImode
, addr
);
19673 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
19675 insn
= emit_move_insn (reg
, mem
);
19676 if (DEFAULT_ABI
== ABI_V4
)
19678 if (frame_pointer_needed
19679 && info
->first_gp_reg_save
+ i
19680 == HARD_FRAME_POINTER_REGNUM
)
19682 add_reg_note (insn
, REG_CFA_DEF_CFA
,
19683 plus_constant (frame_reg_rtx
,
19685 RTX_FRAME_RELATED_P (insn
) = 1;
19688 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
19697 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
19699 /*savep=*/false, /*gpr=*/true,
19701 emit_jump_insn (par
);
19702 /* We don't want anybody else emitting things after we jumped
19707 else if (!restoring_GPRs_inline
)
19709 /* We are jumping to an out-of-line function. */
19710 bool can_use_exit
= info
->first_fp_reg_save
== 64;
19713 /* Emit stack reset code if we need it. */
19715 rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
19716 sp_offset
, can_use_exit
);
19719 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode
, DEFAULT_ABI
== ABI_AIX
19722 GEN_INT (sp_offset
- info
->fp_size
)));
19723 if (REGNO (frame_reg_rtx
) == 11)
19724 sp_offset
+= info
->fp_size
;
19727 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
19728 info
->gp_save_offset
, reg_mode
,
19729 /*savep=*/false, /*gpr=*/true,
19730 /*lr=*/can_use_exit
);
19734 if (info
->cr_save_p
)
19736 rs6000_restore_saved_cr (cr_save_reg
, using_mtcr_multiple
);
19737 if (DEFAULT_ABI
== ABI_V4
)
19739 = alloc_reg_note (REG_CFA_RESTORE
,
19740 gen_rtx_REG (SImode
, CR2_REGNO
),
19744 emit_jump_insn (par
);
19746 /* We don't want anybody else emitting things after we jumped
19751 insn
= emit_insn (par
);
19752 if (DEFAULT_ABI
== ABI_V4
)
19754 if (frame_pointer_needed
)
19756 add_reg_note (insn
, REG_CFA_DEF_CFA
,
19757 plus_constant (frame_reg_rtx
, sp_offset
));
19758 RTX_FRAME_RELATED_P (insn
) = 1;
19761 for (i
= info
->first_gp_reg_save
; i
< 32; i
++)
19763 = alloc_reg_note (REG_CFA_RESTORE
,
19764 gen_rtx_REG (reg_mode
, i
), cfa_restores
);
19767 else if (using_load_multiple
)
19770 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
19771 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
19773 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19774 GEN_INT (info
->gp_save_offset
19777 rtx mem
= gen_frame_mem (reg_mode
, addr
);
19778 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
19780 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, reg
, mem
);
19781 if (DEFAULT_ABI
== ABI_V4
)
19782 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
19785 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
19786 if (DEFAULT_ABI
== ABI_V4
&& frame_pointer_needed
)
19788 add_reg_note (insn
, REG_CFA_DEF_CFA
,
19789 plus_constant (frame_reg_rtx
, sp_offset
));
19790 RTX_FRAME_RELATED_P (insn
) = 1;
19795 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
19796 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
19798 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19799 GEN_INT (info
->gp_save_offset
19802 rtx mem
= gen_frame_mem (reg_mode
, addr
);
19803 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
19805 insn
= emit_move_insn (reg
, mem
);
19806 if (DEFAULT_ABI
== ABI_V4
)
19808 if (frame_pointer_needed
19809 && info
->first_gp_reg_save
+ i
19810 == HARD_FRAME_POINTER_REGNUM
)
19812 add_reg_note (insn
, REG_CFA_DEF_CFA
,
19813 plus_constant (frame_reg_rtx
, sp_offset
));
19814 RTX_FRAME_RELATED_P (insn
) = 1;
19817 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
19823 if (restore_lr
&& !restoring_GPRs_inline
)
19825 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
19826 info
->lr_save_offset
+ sp_offset
);
19828 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
19829 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
19830 gen_rtx_REG (Pmode
, 0));
19833 /* Restore fpr's if we need to do it without calling a function. */
19834 if (restoring_FPRs_inline
)
19835 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
19836 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
19837 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
19839 rtx addr
, mem
, reg
;
19840 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
19841 GEN_INT (info
->fp_save_offset
19844 mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
19845 ? DFmode
: SFmode
), addr
);
19846 reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
19847 ? DFmode
: SFmode
),
19848 info
->first_fp_reg_save
+ i
);
19850 emit_move_insn (reg
, mem
);
19851 if (DEFAULT_ABI
== ABI_V4
)
19852 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
19856 /* If we saved cr, restore it here. Just those that were used. */
19857 if (info
->cr_save_p
)
19859 rs6000_restore_saved_cr (cr_save_reg
, using_mtcr_multiple
);
19860 if (DEFAULT_ABI
== ABI_V4
)
19862 = alloc_reg_note (REG_CFA_RESTORE
, gen_rtx_REG (SImode
, CR2_REGNO
),
19866 /* If this is V.4, unwind the stack pointer after all of the loads
19868 insn
= rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
19869 sp_offset
, !restoring_FPRs_inline
);
19874 REG_NOTES (insn
) = cfa_restores
;
19875 cfa_restores
= NULL_RTX
;
19877 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
19878 RTX_FRAME_RELATED_P (insn
) = 1;
19881 if (crtl
->calls_eh_return
)
19883 rtx sa
= EH_RETURN_STACKADJ_RTX
;
19884 emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
, sa
));
19890 bool lr
= (strategy
& SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR
) == 0;
19891 if (! restoring_FPRs_inline
)
19892 p
= rtvec_alloc (4 + 64 - info
->first_fp_reg_save
);
19894 p
= rtvec_alloc (2);
19896 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
19897 RTVEC_ELT (p
, 1) = ((restoring_FPRs_inline
|| !lr
)
19898 ? gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 65))
19899 : gen_rtx_CLOBBER (VOIDmode
,
19900 gen_rtx_REG (Pmode
, 65)));
19902 /* If we have to restore more than two FP registers, branch to the
19903 restore function. It will return to our caller. */
19904 if (! restoring_FPRs_inline
)
19909 sym
= rs6000_savres_routine_sym (info
,
19913 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
, sym
);
19914 RTVEC_ELT (p
, 3) = gen_rtx_USE (VOIDmode
,
19915 gen_rtx_REG (Pmode
,
19916 DEFAULT_ABI
== ABI_AIX
19918 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
19921 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
19922 GEN_INT (info
->fp_save_offset
+ 8*i
));
19923 mem
= gen_frame_mem (DFmode
, addr
);
19925 RTVEC_ELT (p
, i
+4) =
19926 gen_rtx_SET (VOIDmode
,
19927 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
19932 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
19936 /* Write function epilogue. */
19939 rs6000_output_function_epilogue (FILE *file
,
19940 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
19942 if (! HAVE_epilogue
)
19944 rtx insn
= get_last_insn ();
19945 /* If the last insn was a BARRIER, we don't have to write anything except
19946 the trace table. */
19947 if (GET_CODE (insn
) == NOTE
)
19948 insn
= prev_nonnote_insn (insn
);
19949 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
19951 /* This is slightly ugly, but at least we don't have two
19952 copies of the epilogue-emitting code. */
19955 /* A NOTE_INSN_DELETED is supposed to be at the start
19956 and end of the "toplevel" insn chain. */
19957 emit_note (NOTE_INSN_DELETED
);
19958 rs6000_emit_epilogue (FALSE
);
19959 emit_note (NOTE_INSN_DELETED
);
19961 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19965 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
19967 INSN_ADDRESSES_NEW (insn
, addr
);
19972 if (TARGET_DEBUG_STACK
)
19973 debug_rtx_list (get_insns (), 100);
19974 final (get_insns (), file
, FALSE
);
19980 macho_branch_islands ();
19981 /* Mach-O doesn't support labels at the end of objects, so if
19982 it looks like we might want one, insert a NOP. */
19984 rtx insn
= get_last_insn ();
19987 && NOTE_KIND (insn
) != NOTE_INSN_DELETED_LABEL
)
19988 insn
= PREV_INSN (insn
);
19992 && NOTE_KIND (insn
) == NOTE_INSN_DELETED_LABEL
)))
19993 fputs ("\tnop\n", file
);
19997 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20000 We don't output a traceback table if -finhibit-size-directive was
20001 used. The documentation for -finhibit-size-directive reads
20002 ``don't output a @code{.size} assembler directive, or anything
20003 else that would cause trouble if the function is split in the
20004 middle, and the two halves are placed at locations far apart in
20005 memory.'' The traceback table has this property, since it
20006 includes the offset from the start of the function to the
20007 traceback table itself.
20009 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20010 different traceback table. */
20011 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
20012 && rs6000_traceback
!= traceback_none
&& !cfun
->is_thunk
)
20014 const char *fname
= NULL
;
20015 const char *language_string
= lang_hooks
.name
;
20016 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
20018 int optional_tbtab
;
20019 rs6000_stack_t
*info
= rs6000_stack_info ();
20021 if (rs6000_traceback
== traceback_full
)
20022 optional_tbtab
= 1;
20023 else if (rs6000_traceback
== traceback_part
)
20024 optional_tbtab
= 0;
20026 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
20028 if (optional_tbtab
)
20030 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
20031 while (*fname
== '.') /* V.4 encodes . in the name */
20034 /* Need label immediately before tbtab, so we can compute
20035 its offset from the function start. */
20036 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
20037 ASM_OUTPUT_LABEL (file
, fname
);
20040 /* The .tbtab pseudo-op can only be used for the first eight
20041 expressions, since it can't handle the possibly variable
20042 length fields that follow. However, if you omit the optional
20043 fields, the assembler outputs zeros for all optional fields
20044 anyways, giving each variable length field is minimum length
20045 (as defined in sys/debug.h). Thus we can not use the .tbtab
20046 pseudo-op at all. */
20048 /* An all-zero word flags the start of the tbtab, for debuggers
20049 that have to find it by searching forward from the entry
20050 point or from the current pc. */
20051 fputs ("\t.long 0\n", file
);
20053 /* Tbtab format type. Use format type 0. */
20054 fputs ("\t.byte 0,", file
);
20056 /* Language type. Unfortunately, there does not seem to be any
20057 official way to discover the language being compiled, so we
20058 use language_string.
20059 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20060 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20061 a number, so for now use 9. */
20062 if (! strcmp (language_string
, "GNU C"))
20064 else if (! strcmp (language_string
, "GNU F77")
20065 || ! strcmp (language_string
, "GNU Fortran"))
20067 else if (! strcmp (language_string
, "GNU Pascal"))
20069 else if (! strcmp (language_string
, "GNU Ada"))
20071 else if (! strcmp (language_string
, "GNU C++")
20072 || ! strcmp (language_string
, "GNU Objective-C++"))
20074 else if (! strcmp (language_string
, "GNU Java"))
20076 else if (! strcmp (language_string
, "GNU Objective-C"))
20079 gcc_unreachable ();
20080 fprintf (file
, "%d,", i
);
20082 /* 8 single bit fields: global linkage (not set for C extern linkage,
20083 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20084 from start of procedure stored in tbtab, internal function, function
20085 has controlled storage, function has no toc, function uses fp,
20086 function logs/aborts fp operations. */
20087 /* Assume that fp operations are used if any fp reg must be saved. */
20088 fprintf (file
, "%d,",
20089 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
20091 /* 6 bitfields: function is interrupt handler, name present in
20092 proc table, function calls alloca, on condition directives
20093 (controls stack walks, 3 bits), saves condition reg, saves
20095 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20096 set up as a frame pointer, even when there is no alloca call. */
20097 fprintf (file
, "%d,",
20098 ((optional_tbtab
<< 6)
20099 | ((optional_tbtab
& frame_pointer_needed
) << 5)
20100 | (info
->cr_save_p
<< 1)
20101 | (info
->lr_save_p
)));
20103 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20105 fprintf (file
, "%d,",
20106 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
20108 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20109 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
20111 if (optional_tbtab
)
20113 /* Compute the parameter info from the function decl argument
20116 int next_parm_info_bit
= 31;
20118 for (decl
= DECL_ARGUMENTS (current_function_decl
);
20119 decl
; decl
= TREE_CHAIN (decl
))
20121 rtx parameter
= DECL_INCOMING_RTL (decl
);
20122 enum machine_mode mode
= GET_MODE (parameter
);
20124 if (GET_CODE (parameter
) == REG
)
20126 if (SCALAR_FLOAT_MODE_P (mode
))
20147 gcc_unreachable ();
20150 /* If only one bit will fit, don't or in this entry. */
20151 if (next_parm_info_bit
> 0)
20152 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
20153 next_parm_info_bit
-= 2;
20157 fixed_parms
+= ((GET_MODE_SIZE (mode
)
20158 + (UNITS_PER_WORD
- 1))
20160 next_parm_info_bit
-= 1;
20166 /* Number of fixed point parameters. */
20167 /* This is actually the number of words of fixed point parameters; thus
20168 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20169 fprintf (file
, "%d,", fixed_parms
);
20171 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20173 /* This is actually the number of fp registers that hold parameters;
20174 and thus the maximum value is 13. */
20175 /* Set parameters on stack bit if parameters are not in their original
20176 registers, regardless of whether they are on the stack? Xlc
20177 seems to set the bit when not optimizing. */
20178 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
20180 if (! optional_tbtab
)
20183 /* Optional fields follow. Some are variable length. */
20185 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20186 11 double float. */
20187 /* There is an entry for each parameter in a register, in the order that
20188 they occur in the parameter list. Any intervening arguments on the
20189 stack are ignored. If the list overflows a long (max possible length
20190 34 bits) then completely leave off all elements that don't fit. */
20191 /* Only emit this long if there was at least one parameter. */
20192 if (fixed_parms
|| float_parms
)
20193 fprintf (file
, "\t.long %d\n", parm_info
);
20195 /* Offset from start of code to tb table. */
20196 fputs ("\t.long ", file
);
20197 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
20199 RS6000_OUTPUT_BASENAME (file
, fname
);
20201 assemble_name (file
, fname
);
20203 rs6000_output_function_entry (file
, fname
);
20206 /* Interrupt handler mask. */
20207 /* Omit this long, since we never set the interrupt handler bit
20210 /* Number of CTL (controlled storage) anchors. */
20211 /* Omit this long, since the has_ctl bit is never set above. */
20213 /* Displacement into stack of each CTL anchor. */
20214 /* Omit this list of longs, because there are no CTL anchors. */
20216 /* Length of function name. */
20219 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
20221 /* Function name. */
20222 assemble_string (fname
, strlen (fname
));
20224 /* Register for alloca automatic storage; this is always reg 31.
20225 Only emit this if the alloca bit was set above. */
20226 if (frame_pointer_needed
)
20227 fputs ("\t.byte 31\n", file
);
20229 fputs ("\t.align 2\n", file
);
20233 /* A C compound statement that outputs the assembler code for a thunk
20234 function, used to implement C++ virtual function calls with
20235 multiple inheritance. The thunk acts as a wrapper around a virtual
20236 function, adjusting the implicit object parameter before handing
20237 control off to the real function.
20239 First, emit code to add the integer DELTA to the location that
20240 contains the incoming first argument. Assume that this argument
20241 contains a pointer, and is the one used to pass the `this' pointer
20242 in C++. This is the incoming argument *before* the function
20243 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20244 values of all other incoming arguments.
20246 After the addition, emit code to jump to FUNCTION, which is a
20247 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20248 not touch the return address. Hence returning from FUNCTION will
20249 return to whoever called the current `thunk'.
20251 The effect must be as if FUNCTION had been called directly with the
20252 adjusted first argument. This macro is responsible for emitting
20253 all of the code for a thunk function; output_function_prologue()
20254 and output_function_epilogue() are not invoked.
20256 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20257 been extracted from it.) It might possibly be useful on some
20258 targets, but probably not.
20260 If you do not define this macro, the target-independent code in the
20261 C++ frontend will generate a less efficient heavyweight thunk that
20262 calls FUNCTION instead of jumping to it. The generic approach does
20263 not support varargs. */
20266 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
20267 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
20270 rtx this_rtx
, insn
, funexp
;
20272 reload_completed
= 1;
20273 epilogue_completed
= 1;
20275 /* Mark the end of the (empty) prologue. */
20276 emit_note (NOTE_INSN_PROLOGUE_END
);
20278 /* Find the "this" pointer. If the function returns a structure,
20279 the structure return pointer is in r3. */
20280 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
20281 this_rtx
= gen_rtx_REG (Pmode
, 4);
20283 this_rtx
= gen_rtx_REG (Pmode
, 3);
20285 /* Apply the constant offset, if required. */
20287 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, GEN_INT (delta
)));
20289 /* Apply the offset from the vtable, if required. */
20292 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
20293 rtx tmp
= gen_rtx_REG (Pmode
, 12);
20295 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this_rtx
));
20296 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
20298 emit_insn (gen_add3_insn (tmp
, tmp
, vcall_offset_rtx
));
20299 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
20303 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
20305 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
20307 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, tmp
));
20310 /* Generate a tail call to the target function. */
20311 if (!TREE_USED (function
))
20313 assemble_external (function
);
20314 TREE_USED (function
) = 1;
20316 funexp
= XEXP (DECL_RTL (function
), 0);
20317 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
20320 if (MACHOPIC_INDIRECT
)
20321 funexp
= machopic_indirect_call_target (funexp
);
20324 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20325 generate sibcall RTL explicitly. */
20326 insn
= emit_call_insn (
20327 gen_rtx_PARALLEL (VOIDmode
,
20329 gen_rtx_CALL (VOIDmode
,
20330 funexp
, const0_rtx
),
20331 gen_rtx_USE (VOIDmode
, const0_rtx
),
20332 gen_rtx_USE (VOIDmode
,
20333 gen_rtx_REG (SImode
,
20335 gen_rtx_RETURN (VOIDmode
))));
20336 SIBLING_CALL_P (insn
) = 1;
20339 /* Run just enough of rest_of_compilation to get the insns emitted.
20340 There's not really enough bulk here to make other passes such as
20341 instruction scheduling worth while. Note that use_thunk calls
20342 assemble_start_function and assemble_end_function. */
20343 insn
= get_insns ();
20344 insn_locators_alloc ();
20345 shorten_branches (insn
);
20346 final_start_function (insn
, file
, 1);
20347 final (insn
, file
, 1);
20348 final_end_function ();
20350 reload_completed
= 0;
20351 epilogue_completed
= 0;
20354 /* A quick summary of the various types of 'constant-pool tables'
20357 Target Flags Name One table per
20358 AIX (none) AIX TOC object file
20359 AIX -mfull-toc AIX TOC object file
20360 AIX -mminimal-toc AIX minimal TOC translation unit
20361 SVR4/EABI (none) SVR4 SDATA object file
20362 SVR4/EABI -fpic SVR4 pic object file
20363 SVR4/EABI -fPIC SVR4 PIC translation unit
20364 SVR4/EABI -mrelocatable EABI TOC function
20365 SVR4/EABI -maix AIX TOC object file
20366 SVR4/EABI -maix -mminimal-toc
20367 AIX minimal TOC translation unit
20369 Name Reg. Set by entries contains:
20370 made by addrs? fp? sum?
20372 AIX TOC 2 crt0 as Y option option
20373 AIX minimal TOC 30 prolog gcc Y Y option
20374 SVR4 SDATA 13 crt0 gcc N Y N
20375 SVR4 pic 30 prolog ld Y not yet N
20376 SVR4 PIC 30 prolog gcc Y option option
20377 EABI TOC 30 prolog gcc Y option option
20381 /* Hash functions for the hash table. */
20384 rs6000_hash_constant (rtx k
)
20386 enum rtx_code code
= GET_CODE (k
);
20387 enum machine_mode mode
= GET_MODE (k
);
20388 unsigned result
= (code
<< 3) ^ mode
;
20389 const char *format
;
20392 format
= GET_RTX_FORMAT (code
);
20393 flen
= strlen (format
);
20399 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
20402 if (mode
!= VOIDmode
)
20403 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
20415 for (; fidx
< flen
; fidx
++)
20416 switch (format
[fidx
])
20421 const char *str
= XSTR (k
, fidx
);
20422 len
= strlen (str
);
20423 result
= result
* 613 + len
;
20424 for (i
= 0; i
< len
; i
++)
20425 result
= result
* 613 + (unsigned) str
[i
];
20430 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
20434 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
20437 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
20438 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
20442 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
20443 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
20450 gcc_unreachable ();
20457 toc_hash_function (const void *hash_entry
)
20459 const struct toc_hash_struct
*thc
=
20460 (const struct toc_hash_struct
*) hash_entry
;
20461 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
20464 /* Compare H1 and H2 for equivalence. */
20467 toc_hash_eq (const void *h1
, const void *h2
)
20469 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
20470 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
20472 if (((const struct toc_hash_struct
*) h1
)->key_mode
20473 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
20476 return rtx_equal_p (r1
, r2
);
20479 /* These are the names given by the C++ front-end to vtables, and
20480 vtable-like objects. Ideally, this logic should not be here;
20481 instead, there should be some programmatic way of inquiring as
20482 to whether or not an object is a vtable. */
20484 #define VTABLE_NAME_P(NAME) \
20485 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
20486 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
20487 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
20488 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
20489 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
20491 #ifdef NO_DOLLAR_IN_LABEL
20492 /* Return a GGC-allocated character string translating dollar signs in
20493 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
20496 rs6000_xcoff_strip_dollar (const char *name
)
20501 p
= strchr (name
, '$');
20503 if (p
== 0 || p
== name
)
20506 len
= strlen (name
);
20507 strip
= (char *) alloca (len
+ 1);
20508 strcpy (strip
, name
);
20509 p
= strchr (strip
, '$');
20513 p
= strchr (p
+ 1, '$');
20516 return ggc_alloc_string (strip
, len
);
20521 rs6000_output_symbol_ref (FILE *file
, rtx x
)
20523 /* Currently C++ toc references to vtables can be emitted before it
20524 is decided whether the vtable is public or private. If this is
20525 the case, then the linker will eventually complain that there is
20526 a reference to an unknown section. Thus, for vtables only,
20527 we emit the TOC reference to reference the symbol and not the
20529 const char *name
= XSTR (x
, 0);
20531 if (VTABLE_NAME_P (name
))
20533 RS6000_OUTPUT_BASENAME (file
, name
);
20536 assemble_name (file
, name
);
20539 /* Output a TOC entry. We derive the entry name from what is being
20543 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
20546 const char *name
= buf
;
20548 HOST_WIDE_INT offset
= 0;
20550 gcc_assert (!TARGET_NO_TOC
);
20552 /* When the linker won't eliminate them, don't output duplicate
20553 TOC entries (this happens on AIX if there is any kind of TOC,
20554 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
20556 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
20558 struct toc_hash_struct
*h
;
20561 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
20562 time because GGC is not initialized at that point. */
20563 if (toc_hash_table
== NULL
)
20564 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
20565 toc_hash_eq
, NULL
);
20567 h
= GGC_NEW (struct toc_hash_struct
);
20569 h
->key_mode
= mode
;
20570 h
->labelno
= labelno
;
20572 found
= htab_find_slot (toc_hash_table
, h
, INSERT
);
20573 if (*found
== NULL
)
20575 else /* This is indeed a duplicate.
20576 Set this label equal to that label. */
20578 fputs ("\t.set ", file
);
20579 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
20580 fprintf (file
, "%d,", labelno
);
20581 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
20582 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
20588 /* If we're going to put a double constant in the TOC, make sure it's
20589 aligned properly when strict alignment is on. */
20590 if (GET_CODE (x
) == CONST_DOUBLE
20591 && STRICT_ALIGNMENT
20592 && GET_MODE_BITSIZE (mode
) >= 64
20593 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
20594 ASM_OUTPUT_ALIGN (file
, 3);
20597 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
20599 /* Handle FP constants specially. Note that if we have a minimal
20600 TOC, things we put here aren't actually in the TOC, so we can allow
20602 if (GET_CODE (x
) == CONST_DOUBLE
&&
20603 (GET_MODE (x
) == TFmode
|| GET_MODE (x
) == TDmode
))
20605 REAL_VALUE_TYPE rv
;
20608 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
20609 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
20610 REAL_VALUE_TO_TARGET_DECIMAL128 (rv
, k
);
20612 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
20616 if (TARGET_MINIMAL_TOC
)
20617 fputs (DOUBLE_INT_ASM_OP
, file
);
20619 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20620 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
20621 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
20622 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
20623 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
20624 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
20629 if (TARGET_MINIMAL_TOC
)
20630 fputs ("\t.long ", file
);
20632 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
20633 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
20634 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
20635 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
20636 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
20637 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
20641 else if (GET_CODE (x
) == CONST_DOUBLE
&&
20642 (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DDmode
))
20644 REAL_VALUE_TYPE rv
;
20647 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
20649 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
20650 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, k
);
20652 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
20656 if (TARGET_MINIMAL_TOC
)
20657 fputs (DOUBLE_INT_ASM_OP
, file
);
20659 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
20660 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
20661 fprintf (file
, "0x%lx%08lx\n",
20662 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
20667 if (TARGET_MINIMAL_TOC
)
20668 fputs ("\t.long ", file
);
20670 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
20671 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
20672 fprintf (file
, "0x%lx,0x%lx\n",
20673 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
20677 else if (GET_CODE (x
) == CONST_DOUBLE
&&
20678 (GET_MODE (x
) == SFmode
|| GET_MODE (x
) == SDmode
))
20680 REAL_VALUE_TYPE rv
;
20683 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
20684 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
20685 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
20687 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
20691 if (TARGET_MINIMAL_TOC
)
20692 fputs (DOUBLE_INT_ASM_OP
, file
);
20694 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
20695 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
20700 if (TARGET_MINIMAL_TOC
)
20701 fputs ("\t.long ", file
);
20703 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
20704 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
20708 else if (GET_MODE (x
) == VOIDmode
20709 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
20711 unsigned HOST_WIDE_INT low
;
20712 HOST_WIDE_INT high
;
20714 if (GET_CODE (x
) == CONST_DOUBLE
)
20716 low
= CONST_DOUBLE_LOW (x
);
20717 high
= CONST_DOUBLE_HIGH (x
);
20720 #if HOST_BITS_PER_WIDE_INT == 32
20723 high
= (low
& 0x80000000) ? ~0 : 0;
20727 low
= INTVAL (x
) & 0xffffffff;
20728 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
20732 /* TOC entries are always Pmode-sized, but since this
20733 is a bigendian machine then if we're putting smaller
20734 integer constants in the TOC we have to pad them.
20735 (This is still a win over putting the constants in
20736 a separate constant pool, because then we'd have
20737 to have both a TOC entry _and_ the actual constant.)
20739 For a 32-bit target, CONST_INT values are loaded and shifted
20740 entirely within `low' and can be stored in one TOC entry. */
20742 /* It would be easy to make this work, but it doesn't now. */
20743 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
20745 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
20747 #if HOST_BITS_PER_WIDE_INT == 32
20748 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
20749 POINTER_SIZE
, &low
, &high
, 0);
20752 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
20753 high
= (HOST_WIDE_INT
) low
>> 32;
20760 if (TARGET_MINIMAL_TOC
)
20761 fputs (DOUBLE_INT_ASM_OP
, file
);
20763 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
20764 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
20765 fprintf (file
, "0x%lx%08lx\n",
20766 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
20771 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
20773 if (TARGET_MINIMAL_TOC
)
20774 fputs ("\t.long ", file
);
20776 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
20777 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
20778 fprintf (file
, "0x%lx,0x%lx\n",
20779 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
20783 if (TARGET_MINIMAL_TOC
)
20784 fputs ("\t.long ", file
);
20786 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
20787 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
20793 if (GET_CODE (x
) == CONST
)
20795 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
20796 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
);
20798 base
= XEXP (XEXP (x
, 0), 0);
20799 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
20802 switch (GET_CODE (base
))
20805 name
= XSTR (base
, 0);
20809 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
20810 CODE_LABEL_NUMBER (XEXP (base
, 0)));
20814 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
20818 gcc_unreachable ();
20821 if (TARGET_MINIMAL_TOC
)
20822 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
20825 fputs ("\t.tc ", file
);
20826 RS6000_OUTPUT_BASENAME (file
, name
);
20829 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
20831 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
20833 fputs ("[TC],", file
);
20836 /* Currently C++ toc references to vtables can be emitted before it
20837 is decided whether the vtable is public or private. If this is
20838 the case, then the linker will eventually complain that there is
20839 a TOC reference to an unknown section. Thus, for vtables only,
20840 we emit the TOC reference to reference the symbol and not the
20842 if (VTABLE_NAME_P (name
))
20844 RS6000_OUTPUT_BASENAME (file
, name
);
20846 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
20847 else if (offset
> 0)
20848 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
20851 output_addr_const (file
, x
);
20855 /* Output an assembler pseudo-op to write an ASCII string of N characters
20856 starting at P to FILE.
20858 On the RS/6000, we have to do this using the .byte operation and
20859 write out special characters outside the quoted string.
20860 Also, the assembler is broken; very long strings are truncated,
20861 so we must artificially break them up early. */
20864 output_ascii (FILE *file
, const char *p
, int n
)
20867 int i
, count_string
;
20868 const char *for_string
= "\t.byte \"";
20869 const char *for_decimal
= "\t.byte ";
20870 const char *to_close
= NULL
;
20873 for (i
= 0; i
< n
; i
++)
20876 if (c
>= ' ' && c
< 0177)
20879 fputs (for_string
, file
);
20882 /* Write two quotes to get one. */
20890 for_decimal
= "\"\n\t.byte ";
20894 if (count_string
>= 512)
20896 fputs (to_close
, file
);
20898 for_string
= "\t.byte \"";
20899 for_decimal
= "\t.byte ";
20907 fputs (for_decimal
, file
);
20908 fprintf (file
, "%d", c
);
20910 for_string
= "\n\t.byte \"";
20911 for_decimal
= ", ";
20917 /* Now close the string if we have written one. Then end the line. */
20919 fputs (to_close
, file
);
20922 /* Generate a unique section name for FILENAME for a section type
20923 represented by SECTION_DESC. Output goes into BUF.
20925 SECTION_DESC can be any string, as long as it is different for each
20926 possible section type.
20928 We name the section in the same manner as xlc. The name begins with an
20929 underscore followed by the filename (after stripping any leading directory
20930 names) with the last period replaced by the string SECTION_DESC. If
20931 FILENAME does not contain a period, SECTION_DESC is appended to the end of
20935 rs6000_gen_section_name (char **buf
, const char *filename
,
20936 const char *section_desc
)
20938 const char *q
, *after_last_slash
, *last_period
= 0;
20942 after_last_slash
= filename
;
20943 for (q
= filename
; *q
; q
++)
20946 after_last_slash
= q
+ 1;
20947 else if (*q
== '.')
20951 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
20952 *buf
= (char *) xmalloc (len
);
20957 for (q
= after_last_slash
; *q
; q
++)
20959 if (q
== last_period
)
20961 strcpy (p
, section_desc
);
20962 p
+= strlen (section_desc
);
20966 else if (ISALNUM (*q
))
20970 if (last_period
== 0)
20971 strcpy (p
, section_desc
);
20976 /* Emit profile function. */
20979 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
20981 /* Non-standard profiling for kernels, which just saves LR then calls
20982 _mcount without worrying about arg saves. The idea is to change
20983 the function prologue as little as possible as it isn't easy to
20984 account for arg save/restore code added just for _mcount. */
20985 if (TARGET_PROFILE_KERNEL
)
20988 if (DEFAULT_ABI
== ABI_AIX
)
20990 #ifndef NO_PROFILE_COUNTERS
20991 # define NO_PROFILE_COUNTERS 0
20993 if (NO_PROFILE_COUNTERS
)
20994 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
20995 LCT_NORMAL
, VOIDmode
, 0);
20999 const char *label_name
;
21002 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
21003 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
21004 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
21006 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
21007 LCT_NORMAL
, VOIDmode
, 1, fun
, Pmode
);
21010 else if (DEFAULT_ABI
== ABI_DARWIN
)
21012 const char *mcount_name
= RS6000_MCOUNT
;
21013 int caller_addr_regno
= LR_REGNO
;
21015 /* Be conservative and always set this, at least for now. */
21016 crtl
->uses_pic_offset_table
= 1;
21019 /* For PIC code, set up a stub and collect the caller's address
21020 from r0, which is where the prologue puts it. */
21021 if (MACHOPIC_INDIRECT
21022 && crtl
->uses_pic_offset_table
)
21023 caller_addr_regno
= 0;
21025 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
21026 LCT_NORMAL
, VOIDmode
, 1,
21027 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
21031 /* Write function profiler code. */
21034 output_function_profiler (FILE *file
, int labelno
)
21038 switch (DEFAULT_ABI
)
21041 gcc_unreachable ();
21046 warning (0, "no profiling of 64-bit code for this ABI");
21049 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
21050 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
21051 if (NO_PROFILE_COUNTERS
)
21053 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
21054 reg_names
[0], reg_names
[1]);
21056 else if (TARGET_SECURE_PLT
&& flag_pic
)
21058 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21059 reg_names
[0], reg_names
[1]);
21060 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
21061 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
21062 reg_names
[12], reg_names
[12]);
21063 assemble_name (file
, buf
);
21064 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
21065 assemble_name (file
, buf
);
21066 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
21068 else if (flag_pic
== 1)
21070 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
21071 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
21072 reg_names
[0], reg_names
[1]);
21073 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
21074 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
21075 assemble_name (file
, buf
);
21076 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
21078 else if (flag_pic
> 1)
21080 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
21081 reg_names
[0], reg_names
[1]);
21082 /* Now, we need to get the address of the label. */
21083 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
21084 assemble_name (file
, buf
);
21085 fputs ("-.\n1:", file
);
21086 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
21087 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
21088 reg_names
[0], reg_names
[11]);
21089 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
21090 reg_names
[0], reg_names
[0], reg_names
[11]);
21094 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
21095 assemble_name (file
, buf
);
21096 fputs ("@ha\n", file
);
21097 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
21098 reg_names
[0], reg_names
[1]);
21099 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
21100 assemble_name (file
, buf
);
21101 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
21104 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21105 fprintf (file
, "\tbl %s%s\n",
21106 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
21111 if (!TARGET_PROFILE_KERNEL
)
21113 /* Don't do anything, done in output_profile_hook (). */
21117 gcc_assert (!TARGET_32BIT
);
21119 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
21120 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
21122 if (cfun
->static_chain_decl
!= NULL
)
21124 asm_fprintf (file
, "\tstd %s,24(%s)\n",
21125 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
21126 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
21127 asm_fprintf (file
, "\tld %s,24(%s)\n",
21128 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
21131 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
21139 /* The following variable value is the last issued insn. */
21141 static rtx last_scheduled_insn
;
21143 /* The following variable helps to balance issuing of load and
21144 store instructions */
21146 static int load_store_pendulum
;
21148 /* Power4 load update and store update instructions are cracked into a
21149 load or store and an integer insn which are executed in the same cycle.
21150 Branches have their own dispatch slot which does not count against the
21151 GCC issue rate, but it changes the program flow so there are no other
21152 instructions to issue in this cycle. */
21155 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED
,
21156 int verbose ATTRIBUTE_UNUSED
,
21157 rtx insn
, int more
)
21159 last_scheduled_insn
= insn
;
21160 if (GET_CODE (PATTERN (insn
)) == USE
21161 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
21163 cached_can_issue_more
= more
;
21164 return cached_can_issue_more
;
21167 if (insn_terminates_group_p (insn
, current_group
))
21169 cached_can_issue_more
= 0;
21170 return cached_can_issue_more
;
21173 /* If no reservation, but reach here */
21174 if (recog_memoized (insn
) < 0)
21177 if (rs6000_sched_groups
)
21179 if (is_microcoded_insn (insn
))
21180 cached_can_issue_more
= 0;
21181 else if (is_cracked_insn (insn
))
21182 cached_can_issue_more
= more
> 2 ? more
- 2 : 0;
21184 cached_can_issue_more
= more
- 1;
21186 return cached_can_issue_more
;
21189 if (rs6000_cpu_attr
== CPU_CELL
&& is_nonpipeline_insn (insn
))
21192 cached_can_issue_more
= more
- 1;
21193 return cached_can_issue_more
;
21196 /* Adjust the cost of a scheduling dependency. Return the new cost of
21197 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21200 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
21202 enum attr_type attr_type
;
21204 if (! recog_memoized (insn
))
21207 switch (REG_NOTE_KIND (link
))
21211 /* Data dependency; DEP_INSN writes a register that INSN reads
21212 some cycles later. */
21214 /* Separate a load from a narrower, dependent store. */
21215 if (rs6000_sched_groups
21216 && GET_CODE (PATTERN (insn
)) == SET
21217 && GET_CODE (PATTERN (dep_insn
)) == SET
21218 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
21219 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
21220 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
21221 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
21224 attr_type
= get_attr_type (insn
);
21229 /* Tell the first scheduling pass about the latency between
21230 a mtctr and bctr (and mtlr and br/blr). The first
21231 scheduling pass will not know about this latency since
21232 the mtctr instruction, which has the latency associated
21233 to it, will be generated by reload. */
21234 return TARGET_POWER
? 5 : 4;
21236 /* Leave some extra cycles between a compare and its
21237 dependent branch, to inhibit expensive mispredicts. */
21238 if ((rs6000_cpu_attr
== CPU_PPC603
21239 || rs6000_cpu_attr
== CPU_PPC604
21240 || rs6000_cpu_attr
== CPU_PPC604E
21241 || rs6000_cpu_attr
== CPU_PPC620
21242 || rs6000_cpu_attr
== CPU_PPC630
21243 || rs6000_cpu_attr
== CPU_PPC750
21244 || rs6000_cpu_attr
== CPU_PPC7400
21245 || rs6000_cpu_attr
== CPU_PPC7450
21246 || rs6000_cpu_attr
== CPU_POWER4
21247 || rs6000_cpu_attr
== CPU_POWER5
21248 || rs6000_cpu_attr
== CPU_POWER7
21249 || rs6000_cpu_attr
== CPU_CELL
)
21250 && recog_memoized (dep_insn
)
21251 && (INSN_CODE (dep_insn
) >= 0))
21253 switch (get_attr_type (dep_insn
))
21257 case TYPE_DELAYED_COMPARE
:
21258 case TYPE_IMUL_COMPARE
:
21259 case TYPE_LMUL_COMPARE
:
21260 case TYPE_FPCOMPARE
:
21261 case TYPE_CR_LOGICAL
:
21262 case TYPE_DELAYED_CR
:
21271 case TYPE_STORE_UX
:
21273 case TYPE_FPSTORE_U
:
21274 case TYPE_FPSTORE_UX
:
21275 if ((rs6000_cpu
== PROCESSOR_POWER6
)
21276 && recog_memoized (dep_insn
)
21277 && (INSN_CODE (dep_insn
) >= 0))
21280 if (GET_CODE (PATTERN (insn
)) != SET
)
21281 /* If this happens, we have to extend this to schedule
21282 optimally. Return default for now. */
21285 /* Adjust the cost for the case where the value written
21286 by a fixed point operation is used as the address
21287 gen value on a store. */
21288 switch (get_attr_type (dep_insn
))
21295 if (! store_data_bypass_p (dep_insn
, insn
))
21299 case TYPE_LOAD_EXT
:
21300 case TYPE_LOAD_EXT_U
:
21301 case TYPE_LOAD_EXT_UX
:
21302 case TYPE_VAR_SHIFT_ROTATE
:
21303 case TYPE_VAR_DELAYED_COMPARE
:
21305 if (! store_data_bypass_p (dep_insn
, insn
))
21311 case TYPE_FAST_COMPARE
:
21314 case TYPE_INSERT_WORD
:
21315 case TYPE_INSERT_DWORD
:
21316 case TYPE_FPLOAD_U
:
21317 case TYPE_FPLOAD_UX
:
21319 case TYPE_STORE_UX
:
21320 case TYPE_FPSTORE_U
:
21321 case TYPE_FPSTORE_UX
:
21323 if (! store_data_bypass_p (dep_insn
, insn
))
21331 case TYPE_IMUL_COMPARE
:
21332 case TYPE_LMUL_COMPARE
:
21334 if (! store_data_bypass_p (dep_insn
, insn
))
21340 if (! store_data_bypass_p (dep_insn
, insn
))
21346 if (! store_data_bypass_p (dep_insn
, insn
))
21359 case TYPE_LOAD_EXT
:
21360 case TYPE_LOAD_EXT_U
:
21361 case TYPE_LOAD_EXT_UX
:
21362 if ((rs6000_cpu
== PROCESSOR_POWER6
)
21363 && recog_memoized (dep_insn
)
21364 && (INSN_CODE (dep_insn
) >= 0))
21367 /* Adjust the cost for the case where the value written
21368 by a fixed point instruction is used within the address
21369 gen portion of a subsequent load(u)(x) */
21370 switch (get_attr_type (dep_insn
))
21377 if (set_to_load_agen (dep_insn
, insn
))
21381 case TYPE_LOAD_EXT
:
21382 case TYPE_LOAD_EXT_U
:
21383 case TYPE_LOAD_EXT_UX
:
21384 case TYPE_VAR_SHIFT_ROTATE
:
21385 case TYPE_VAR_DELAYED_COMPARE
:
21387 if (set_to_load_agen (dep_insn
, insn
))
21393 case TYPE_FAST_COMPARE
:
21396 case TYPE_INSERT_WORD
:
21397 case TYPE_INSERT_DWORD
:
21398 case TYPE_FPLOAD_U
:
21399 case TYPE_FPLOAD_UX
:
21401 case TYPE_STORE_UX
:
21402 case TYPE_FPSTORE_U
:
21403 case TYPE_FPSTORE_UX
:
21405 if (set_to_load_agen (dep_insn
, insn
))
21413 case TYPE_IMUL_COMPARE
:
21414 case TYPE_LMUL_COMPARE
:
21416 if (set_to_load_agen (dep_insn
, insn
))
21422 if (set_to_load_agen (dep_insn
, insn
))
21428 if (set_to_load_agen (dep_insn
, insn
))
21439 if ((rs6000_cpu
== PROCESSOR_POWER6
)
21440 && recog_memoized (dep_insn
)
21441 && (INSN_CODE (dep_insn
) >= 0)
21442 && (get_attr_type (dep_insn
) == TYPE_MFFGPR
))
21449 /* Fall out to return default cost. */
21453 case REG_DEP_OUTPUT
:
21454 /* Output dependency; DEP_INSN writes a register that INSN writes some
21456 if ((rs6000_cpu
== PROCESSOR_POWER6
)
21457 && recog_memoized (dep_insn
)
21458 && (INSN_CODE (dep_insn
) >= 0))
21460 attr_type
= get_attr_type (insn
);
21465 if (get_attr_type (dep_insn
) == TYPE_FP
)
21469 if (get_attr_type (dep_insn
) == TYPE_MFFGPR
)
21477 /* Anti dependency; DEP_INSN reads a register that INSN writes some
21482 gcc_unreachable ();
21488 /* Debug version of rs6000_adjust_cost. */
21491 rs6000_debug_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
21493 int ret
= rs6000_adjust_cost (insn
, link
, dep_insn
, cost
);
21499 switch (REG_NOTE_KIND (link
))
21501 default: dep
= "unknown depencency"; break;
21502 case REG_DEP_TRUE
: dep
= "data dependency"; break;
21503 case REG_DEP_OUTPUT
: dep
= "output dependency"; break;
21504 case REG_DEP_ANTI
: dep
= "anti depencency"; break;
21508 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
21509 "%s, insn:\n", ret
, cost
, dep
);
21517 /* The function returns a true if INSN is microcoded.
21518 Return false otherwise. */
21521 is_microcoded_insn (rtx insn
)
21523 if (!insn
|| !NONDEBUG_INSN_P (insn
)
21524 || GET_CODE (PATTERN (insn
)) == USE
21525 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
21528 if (rs6000_cpu_attr
== CPU_CELL
)
21529 return get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
;
21531 if (rs6000_sched_groups
)
21533 enum attr_type type
= get_attr_type (insn
);
21534 if (type
== TYPE_LOAD_EXT_U
21535 || type
== TYPE_LOAD_EXT_UX
21536 || type
== TYPE_LOAD_UX
21537 || type
== TYPE_STORE_UX
21538 || type
== TYPE_MFCR
)
21545 /* The function returns true if INSN is cracked into 2 instructions
21546 by the processor (and therefore occupies 2 issue slots). */
21549 is_cracked_insn (rtx insn
)
21551 if (!insn
|| !NONDEBUG_INSN_P (insn
)
21552 || GET_CODE (PATTERN (insn
)) == USE
21553 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
21556 if (rs6000_sched_groups
)
21558 enum attr_type type
= get_attr_type (insn
);
21559 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
21560 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
21561 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
21562 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
21563 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
21564 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
21565 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
21566 || type
== TYPE_INSERT_WORD
)
21573 /* The function returns true if INSN can be issued only from
21574 the branch slot. */
21577 is_branch_slot_insn (rtx insn
)
21579 if (!insn
|| !NONDEBUG_INSN_P (insn
)
21580 || GET_CODE (PATTERN (insn
)) == USE
21581 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
21584 if (rs6000_sched_groups
)
21586 enum attr_type type
= get_attr_type (insn
);
21587 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
21595 /* The function returns true if out_inst sets a value that is
21596 used in the address generation computation of in_insn */
21598 set_to_load_agen (rtx out_insn
, rtx in_insn
)
21600 rtx out_set
, in_set
;
21602 /* For performance reasons, only handle the simple case where
21603 both loads are a single_set. */
21604 out_set
= single_set (out_insn
);
21607 in_set
= single_set (in_insn
);
21609 return reg_mentioned_p (SET_DEST (out_set
), SET_SRC (in_set
));
21615 /* The function returns true if the target storage location of
21616 out_insn is adjacent to the target storage location of in_insn */
21617 /* Return 1 if memory locations are adjacent. */
21620 adjacent_mem_locations (rtx insn1
, rtx insn2
)
21623 rtx a
= get_store_dest (PATTERN (insn1
));
21624 rtx b
= get_store_dest (PATTERN (insn2
));
21626 if ((GET_CODE (XEXP (a
, 0)) == REG
21627 || (GET_CODE (XEXP (a
, 0)) == PLUS
21628 && GET_CODE (XEXP (XEXP (a
, 0), 1)) == CONST_INT
))
21629 && (GET_CODE (XEXP (b
, 0)) == REG
21630 || (GET_CODE (XEXP (b
, 0)) == PLUS
21631 && GET_CODE (XEXP (XEXP (b
, 0), 1)) == CONST_INT
)))
21633 HOST_WIDE_INT val0
= 0, val1
= 0, val_diff
;
21636 if (GET_CODE (XEXP (a
, 0)) == PLUS
)
21638 reg0
= XEXP (XEXP (a
, 0), 0);
21639 val0
= INTVAL (XEXP (XEXP (a
, 0), 1));
21642 reg0
= XEXP (a
, 0);
21644 if (GET_CODE (XEXP (b
, 0)) == PLUS
)
21646 reg1
= XEXP (XEXP (b
, 0), 0);
21647 val1
= INTVAL (XEXP (XEXP (b
, 0), 1));
21650 reg1
= XEXP (b
, 0);
21652 val_diff
= val1
- val0
;
21654 return ((REGNO (reg0
) == REGNO (reg1
))
21655 && ((MEM_SIZE (a
) && val_diff
== INTVAL (MEM_SIZE (a
)))
21656 || (MEM_SIZE (b
) && val_diff
== -INTVAL (MEM_SIZE (b
)))));
21662 /* A C statement (sans semicolon) to update the integer scheduling
21663 priority INSN_PRIORITY (INSN). Increase the priority to execute the
21664 INSN earlier, reduce the priority to execute INSN later. Do not
21665 define this macro if you do not need to adjust the scheduling
21666 priorities of insns. */
21669 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
21671 /* On machines (like the 750) which have asymmetric integer units,
21672 where one integer unit can do multiply and divides and the other
21673 can't, reduce the priority of multiply/divide so it is scheduled
21674 before other integer operations. */
21677 if (! INSN_P (insn
))
21680 if (GET_CODE (PATTERN (insn
)) == USE
)
21683 switch (rs6000_cpu_attr
) {
21685 switch (get_attr_type (insn
))
21692 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
21693 priority
, priority
);
21694 if (priority
>= 0 && priority
< 0x01000000)
21701 if (insn_must_be_first_in_group (insn
)
21702 && reload_completed
21703 && current_sched_info
->sched_max_insns_priority
21704 && rs6000_sched_restricted_insns_priority
)
21707 /* Prioritize insns that can be dispatched only in the first
21709 if (rs6000_sched_restricted_insns_priority
== 1)
21710 /* Attach highest priority to insn. This means that in
21711 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
21712 precede 'priority' (critical path) considerations. */
21713 return current_sched_info
->sched_max_insns_priority
;
21714 else if (rs6000_sched_restricted_insns_priority
== 2)
21715 /* Increase priority of insn by a minimal amount. This means that in
21716 haifa-sched.c:ready_sort(), only 'priority' (critical path)
21717 considerations precede dispatch-slot restriction considerations. */
21718 return (priority
+ 1);
21721 if (rs6000_cpu
== PROCESSOR_POWER6
21722 && ((load_store_pendulum
== -2 && is_load_insn (insn
))
21723 || (load_store_pendulum
== 2 && is_store_insn (insn
))))
21724 /* Attach highest priority to insn if the scheduler has just issued two
21725 stores and this instruction is a load, or two loads and this instruction
21726 is a store. Power6 wants loads and stores scheduled alternately
21728 return current_sched_info
->sched_max_insns_priority
;
21733 /* Return true if the instruction is nonpipelined on the Cell. */
21735 is_nonpipeline_insn (rtx insn
)
21737 enum attr_type type
;
21738 if (!insn
|| !NONDEBUG_INSN_P (insn
)
21739 || GET_CODE (PATTERN (insn
)) == USE
21740 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
21743 type
= get_attr_type (insn
);
21744 if (type
== TYPE_IMUL
21745 || type
== TYPE_IMUL2
21746 || type
== TYPE_IMUL3
21747 || type
== TYPE_LMUL
21748 || type
== TYPE_IDIV
21749 || type
== TYPE_LDIV
21750 || type
== TYPE_SDIV
21751 || type
== TYPE_DDIV
21752 || type
== TYPE_SSQRT
21753 || type
== TYPE_DSQRT
21754 || type
== TYPE_MFCR
21755 || type
== TYPE_MFCRF
21756 || type
== TYPE_MFJMPR
)
21764 /* Return how many instructions the machine can issue per cycle. */
21767 rs6000_issue_rate (void)
21769 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
21770 if (!reload_completed
)
21773 switch (rs6000_cpu_attr
) {
21774 case CPU_RIOS1
: /* ? */
21776 case CPU_PPC601
: /* ? */
21785 case CPU_PPCE300C2
:
21786 case CPU_PPCE300C3
:
21787 case CPU_PPCE500MC
:
21805 /* Return how many instructions to look ahead for better insn
21809 rs6000_use_sched_lookahead (void)
21811 if (rs6000_cpu_attr
== CPU_PPC8540
)
21813 if (rs6000_cpu_attr
== CPU_CELL
)
21814 return (reload_completed
? 8 : 0);
21818 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
21820 rs6000_use_sched_lookahead_guard (rtx insn
)
21822 if (rs6000_cpu_attr
!= CPU_CELL
)
21825 if (insn
== NULL_RTX
|| !INSN_P (insn
))
21828 if (!reload_completed
21829 || is_nonpipeline_insn (insn
)
21830 || is_microcoded_insn (insn
))
21836 /* Determine is PAT refers to memory. */
21839 is_mem_ref (rtx pat
)
21845 /* stack_tie does not produce any real memory traffic. */
21846 if (GET_CODE (pat
) == UNSPEC
21847 && XINT (pat
, 1) == UNSPEC_TIE
)
21850 if (GET_CODE (pat
) == MEM
)
21853 /* Recursively process the pattern. */
21854 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
21856 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
21859 ret
|= is_mem_ref (XEXP (pat
, i
));
21860 else if (fmt
[i
] == 'E')
21861 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
21862 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
21868 /* Determine if PAT is a PATTERN of a load insn. */
21871 is_load_insn1 (rtx pat
)
21873 if (!pat
|| pat
== NULL_RTX
)
21876 if (GET_CODE (pat
) == SET
)
21877 return is_mem_ref (SET_SRC (pat
));
21879 if (GET_CODE (pat
) == PARALLEL
)
21883 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
21884 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
21891 /* Determine if INSN loads from memory. */
21894 is_load_insn (rtx insn
)
21896 if (!insn
|| !INSN_P (insn
))
21899 if (GET_CODE (insn
) == CALL_INSN
)
21902 return is_load_insn1 (PATTERN (insn
));
21905 /* Determine if PAT is a PATTERN of a store insn. */
21908 is_store_insn1 (rtx pat
)
21910 if (!pat
|| pat
== NULL_RTX
)
21913 if (GET_CODE (pat
) == SET
)
21914 return is_mem_ref (SET_DEST (pat
));
21916 if (GET_CODE (pat
) == PARALLEL
)
21920 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
21921 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
21928 /* Determine if INSN stores to memory. */
21931 is_store_insn (rtx insn
)
21933 if (!insn
|| !INSN_P (insn
))
21936 return is_store_insn1 (PATTERN (insn
));
21939 /* Return the dest of a store insn. */
21942 get_store_dest (rtx pat
)
21944 gcc_assert (is_store_insn1 (pat
));
21946 if (GET_CODE (pat
) == SET
)
21947 return SET_DEST (pat
);
21948 else if (GET_CODE (pat
) == PARALLEL
)
21952 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
21954 rtx inner_pat
= XVECEXP (pat
, 0, i
);
21955 if (GET_CODE (inner_pat
) == SET
21956 && is_mem_ref (SET_DEST (inner_pat
)))
21960 /* We shouldn't get here, because we should have either a simple
21961 store insn or a store with update which are covered above. */
21965 /* Returns whether the dependence between INSN and NEXT is considered
21966 costly by the given target. */
21969 rs6000_is_costly_dependence (dep_t dep
, int cost
, int distance
)
21974 /* If the flag is not enabled - no dependence is considered costly;
21975 allow all dependent insns in the same group.
21976 This is the most aggressive option. */
21977 if (rs6000_sched_costly_dep
== no_dep_costly
)
21980 /* If the flag is set to 1 - a dependence is always considered costly;
21981 do not allow dependent instructions in the same group.
21982 This is the most conservative option. */
21983 if (rs6000_sched_costly_dep
== all_deps_costly
)
21986 insn
= DEP_PRO (dep
);
21987 next
= DEP_CON (dep
);
21989 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
21990 && is_load_insn (next
)
21991 && is_store_insn (insn
))
21992 /* Prevent load after store in the same group. */
21995 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
21996 && is_load_insn (next
)
21997 && is_store_insn (insn
)
21998 && DEP_TYPE (dep
) == REG_DEP_TRUE
)
21999 /* Prevent load after store in the same group if it is a true
22003 /* The flag is set to X; dependences with latency >= X are considered costly,
22004 and will not be scheduled in the same group. */
22005 if (rs6000_sched_costly_dep
<= max_dep_latency
22006 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
22012 /* Return the next insn after INSN that is found before TAIL is reached,
22013 skipping any "non-active" insns - insns that will not actually occupy
22014 an issue slot. Return NULL_RTX if such an insn is not found. */
22017 get_next_active_insn (rtx insn
, rtx tail
)
22019 if (insn
== NULL_RTX
|| insn
== tail
)
22024 insn
= NEXT_INSN (insn
);
22025 if (insn
== NULL_RTX
|| insn
== tail
)
22030 || (NONJUMP_INSN_P (insn
)
22031 && GET_CODE (PATTERN (insn
)) != USE
22032 && GET_CODE (PATTERN (insn
)) != CLOBBER
22033 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
22039 /* We are about to begin issuing insns for this clock cycle. */
22042 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED
, int sched_verbose
,
22043 rtx
*ready ATTRIBUTE_UNUSED
,
22044 int *pn_ready ATTRIBUTE_UNUSED
,
22045 int clock_var ATTRIBUTE_UNUSED
)
22047 int n_ready
= *pn_ready
;
22050 fprintf (dump
, "// rs6000_sched_reorder :\n");
22052 /* Reorder the ready list, if the second to last ready insn
22053 is a nonepipeline insn. */
22054 if (rs6000_cpu_attr
== CPU_CELL
&& n_ready
> 1)
22056 if (is_nonpipeline_insn (ready
[n_ready
- 1])
22057 && (recog_memoized (ready
[n_ready
- 2]) > 0))
22058 /* Simply swap first two insns. */
22060 rtx tmp
= ready
[n_ready
- 1];
22061 ready
[n_ready
- 1] = ready
[n_ready
- 2];
22062 ready
[n_ready
- 2] = tmp
;
22066 if (rs6000_cpu
== PROCESSOR_POWER6
)
22067 load_store_pendulum
= 0;
22069 return rs6000_issue_rate ();
22072 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22075 rs6000_sched_reorder2 (FILE *dump
, int sched_verbose
, rtx
*ready
,
22076 int *pn_ready
, int clock_var ATTRIBUTE_UNUSED
)
22079 fprintf (dump
, "// rs6000_sched_reorder2 :\n");
22081 /* For Power6, we need to handle some special cases to try and keep the
22082 store queue from overflowing and triggering expensive flushes.
22084 This code monitors how load and store instructions are being issued
22085 and skews the ready list one way or the other to increase the likelihood
22086 that a desired instruction is issued at the proper time.
22088 A couple of things are done. First, we maintain a "load_store_pendulum"
22089 to track the current state of load/store issue.
22091 - If the pendulum is at zero, then no loads or stores have been
22092 issued in the current cycle so we do nothing.
22094 - If the pendulum is 1, then a single load has been issued in this
22095 cycle and we attempt to locate another load in the ready list to
22098 - If the pendulum is -2, then two stores have already been
22099 issued in this cycle, so we increase the priority of the first load
22100 in the ready list to increase it's likelihood of being chosen first
22103 - If the pendulum is -1, then a single store has been issued in this
22104 cycle and we attempt to locate another store in the ready list to
22105 issue with it, preferring a store to an adjacent memory location to
22106 facilitate store pairing in the store queue.
22108 - If the pendulum is 2, then two loads have already been
22109 issued in this cycle, so we increase the priority of the first store
22110 in the ready list to increase it's likelihood of being chosen first
22113 - If the pendulum < -2 or > 2, then do nothing.
22115 Note: This code covers the most common scenarios. There exist non
22116 load/store instructions which make use of the LSU and which
22117 would need to be accounted for to strictly model the behavior
22118 of the machine. Those instructions are currently unaccounted
22119 for to help minimize compile time overhead of this code.
22121 if (rs6000_cpu
== PROCESSOR_POWER6
&& last_scheduled_insn
)
22127 if (is_store_insn (last_scheduled_insn
))
22128 /* Issuing a store, swing the load_store_pendulum to the left */
22129 load_store_pendulum
--;
22130 else if (is_load_insn (last_scheduled_insn
))
22131 /* Issuing a load, swing the load_store_pendulum to the right */
22132 load_store_pendulum
++;
22134 return cached_can_issue_more
;
22136 /* If the pendulum is balanced, or there is only one instruction on
22137 the ready list, then all is well, so return. */
22138 if ((load_store_pendulum
== 0) || (*pn_ready
<= 1))
22139 return cached_can_issue_more
;
22141 if (load_store_pendulum
== 1)
22143 /* A load has been issued in this cycle. Scan the ready list
22144 for another load to issue with it */
22149 if (is_load_insn (ready
[pos
]))
22151 /* Found a load. Move it to the head of the ready list,
22152 and adjust it's priority so that it is more likely to
22155 for (i
=pos
; i
<*pn_ready
-1; i
++)
22156 ready
[i
] = ready
[i
+ 1];
22157 ready
[*pn_ready
-1] = tmp
;
22159 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
22160 INSN_PRIORITY (tmp
)++;
22166 else if (load_store_pendulum
== -2)
22168 /* Two stores have been issued in this cycle. Increase the
22169 priority of the first load in the ready list to favor it for
22170 issuing in the next cycle. */
22175 if (is_load_insn (ready
[pos
])
22177 && INSN_PRIORITY_KNOWN (ready
[pos
]))
22179 INSN_PRIORITY (ready
[pos
])++;
22181 /* Adjust the pendulum to account for the fact that a load
22182 was found and increased in priority. This is to prevent
22183 increasing the priority of multiple loads */
22184 load_store_pendulum
--;
22191 else if (load_store_pendulum
== -1)
22193 /* A store has been issued in this cycle. Scan the ready list for
22194 another store to issue with it, preferring a store to an adjacent
22196 int first_store_pos
= -1;
22202 if (is_store_insn (ready
[pos
]))
22204 /* Maintain the index of the first store found on the
22206 if (first_store_pos
== -1)
22207 first_store_pos
= pos
;
22209 if (is_store_insn (last_scheduled_insn
)
22210 && adjacent_mem_locations (last_scheduled_insn
,ready
[pos
]))
22212 /* Found an adjacent store. Move it to the head of the
22213 ready list, and adjust it's priority so that it is
22214 more likely to stay there */
22216 for (i
=pos
; i
<*pn_ready
-1; i
++)
22217 ready
[i
] = ready
[i
+ 1];
22218 ready
[*pn_ready
-1] = tmp
;
22220 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
22221 INSN_PRIORITY (tmp
)++;
22223 first_store_pos
= -1;
22231 if (first_store_pos
>= 0)
22233 /* An adjacent store wasn't found, but a non-adjacent store was,
22234 so move the non-adjacent store to the front of the ready
22235 list, and adjust its priority so that it is more likely to
22237 tmp
= ready
[first_store_pos
];
22238 for (i
=first_store_pos
; i
<*pn_ready
-1; i
++)
22239 ready
[i
] = ready
[i
+ 1];
22240 ready
[*pn_ready
-1] = tmp
;
22241 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
22242 INSN_PRIORITY (tmp
)++;
22245 else if (load_store_pendulum
== 2)
22247 /* Two loads have been issued in this cycle. Increase the priority
22248 of the first store in the ready list to favor it for issuing in
22254 if (is_store_insn (ready
[pos
])
22256 && INSN_PRIORITY_KNOWN (ready
[pos
]))
22258 INSN_PRIORITY (ready
[pos
])++;
22260 /* Adjust the pendulum to account for the fact that a store
22261 was found and increased in priority. This is to prevent
22262 increasing the priority of multiple stores */
22263 load_store_pendulum
++;
22272 return cached_can_issue_more
;
22275 /* Return whether the presence of INSN causes a dispatch group termination
22276 of group WHICH_GROUP.
22278 If WHICH_GROUP == current_group, this function will return true if INSN
22279 causes the termination of the current group (i.e, the dispatch group to
22280 which INSN belongs). This means that INSN will be the last insn in the
22281 group it belongs to.
22283 If WHICH_GROUP == previous_group, this function will return true if INSN
22284 causes the termination of the previous group (i.e, the dispatch group that
22285 precedes the group to which INSN belongs). This means that INSN will be
22286 the first insn in the group it belongs to). */
22289 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
22296 first
= insn_must_be_first_in_group (insn
);
22297 last
= insn_must_be_last_in_group (insn
);
22302 if (which_group
== current_group
)
22304 else if (which_group
== previous_group
)
22312 insn_must_be_first_in_group (rtx insn
)
22314 enum attr_type type
;
22317 || GET_CODE (insn
) == NOTE
22318 || DEBUG_INSN_P (insn
)
22319 || GET_CODE (PATTERN (insn
)) == USE
22320 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
22323 switch (rs6000_cpu
)
22325 case PROCESSOR_POWER5
:
22326 if (is_cracked_insn (insn
))
22328 case PROCESSOR_POWER4
:
22329 if (is_microcoded_insn (insn
))
22332 if (!rs6000_sched_groups
)
22335 type
= get_attr_type (insn
);
22342 case TYPE_DELAYED_CR
:
22343 case TYPE_CR_LOGICAL
:
22357 case PROCESSOR_POWER6
:
22358 type
= get_attr_type (insn
);
22362 case TYPE_INSERT_DWORD
:
22366 case TYPE_VAR_SHIFT_ROTATE
:
22373 case TYPE_INSERT_WORD
:
22374 case TYPE_DELAYED_COMPARE
:
22375 case TYPE_IMUL_COMPARE
:
22376 case TYPE_LMUL_COMPARE
:
22377 case TYPE_FPCOMPARE
:
22388 case TYPE_LOAD_EXT_UX
:
22390 case TYPE_STORE_UX
:
22391 case TYPE_FPLOAD_U
:
22392 case TYPE_FPLOAD_UX
:
22393 case TYPE_FPSTORE_U
:
22394 case TYPE_FPSTORE_UX
:
22400 case PROCESSOR_POWER7
:
22401 type
= get_attr_type (insn
);
22405 case TYPE_CR_LOGICAL
:
22412 case TYPE_DELAYED_COMPARE
:
22413 case TYPE_VAR_DELAYED_COMPARE
:
22419 case TYPE_LOAD_EXT
:
22420 case TYPE_LOAD_EXT_U
:
22421 case TYPE_LOAD_EXT_UX
:
22423 case TYPE_STORE_UX
:
22424 case TYPE_FPLOAD_U
:
22425 case TYPE_FPLOAD_UX
:
22426 case TYPE_FPSTORE_U
:
22427 case TYPE_FPSTORE_UX
:
22443 insn_must_be_last_in_group (rtx insn
)
22445 enum attr_type type
;
22448 || GET_CODE (insn
) == NOTE
22449 || DEBUG_INSN_P (insn
)
22450 || GET_CODE (PATTERN (insn
)) == USE
22451 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
22454 switch (rs6000_cpu
) {
22455 case PROCESSOR_POWER4
:
22456 case PROCESSOR_POWER5
:
22457 if (is_microcoded_insn (insn
))
22460 if (is_branch_slot_insn (insn
))
22464 case PROCESSOR_POWER6
:
22465 type
= get_attr_type (insn
);
22472 case TYPE_VAR_SHIFT_ROTATE
:
22479 case TYPE_DELAYED_COMPARE
:
22480 case TYPE_IMUL_COMPARE
:
22481 case TYPE_LMUL_COMPARE
:
22482 case TYPE_FPCOMPARE
:
22496 case PROCESSOR_POWER7
:
22497 type
= get_attr_type (insn
);
22505 case TYPE_LOAD_EXT_U
:
22506 case TYPE_LOAD_EXT_UX
:
22507 case TYPE_STORE_UX
:
22520 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
22521 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
22524 is_costly_group (rtx
*group_insns
, rtx next_insn
)
22527 int issue_rate
= rs6000_issue_rate ();
22529 for (i
= 0; i
< issue_rate
; i
++)
22531 sd_iterator_def sd_it
;
22533 rtx insn
= group_insns
[i
];
22538 FOR_EACH_DEP (insn
, SD_LIST_FORW
, sd_it
, dep
)
22540 rtx next
= DEP_CON (dep
);
22542 if (next
== next_insn
22543 && rs6000_is_costly_dependence (dep
, dep_cost (dep
), 0))
22551 /* Utility of the function redefine_groups.
22552 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
22553 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
22554 to keep it "far" (in a separate group) from GROUP_INSNS, following
22555 one of the following schemes, depending on the value of the flag
22556 -minsert_sched_nops = X:
22557 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
22558 in order to force NEXT_INSN into a separate group.
22559 (2) X < sched_finish_regroup_exact: insert exactly X nops.
22560 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
22561 insertion (has a group just ended, how many vacant issue slots remain in the
22562 last group, and how many dispatch groups were encountered so far). */
22565 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
22566 rtx next_insn
, bool *group_end
, int can_issue_more
,
22571 int issue_rate
= rs6000_issue_rate ();
22572 bool end
= *group_end
;
22575 if (next_insn
== NULL_RTX
|| DEBUG_INSN_P (next_insn
))
22576 return can_issue_more
;
22578 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
22579 return can_issue_more
;
22581 force
= is_costly_group (group_insns
, next_insn
);
22583 return can_issue_more
;
22585 if (sched_verbose
> 6)
22586 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
22587 *group_count
,can_issue_more
);
22589 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
22592 can_issue_more
= 0;
22594 /* Since only a branch can be issued in the last issue_slot, it is
22595 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
22596 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
22597 in this case the last nop will start a new group and the branch
22598 will be forced to the new group. */
22599 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
22602 while (can_issue_more
> 0)
22605 emit_insn_before (nop
, next_insn
);
22613 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
22615 int n_nops
= rs6000_sched_insert_nops
;
22617 /* Nops can't be issued from the branch slot, so the effective
22618 issue_rate for nops is 'issue_rate - 1'. */
22619 if (can_issue_more
== 0)
22620 can_issue_more
= issue_rate
;
22622 if (can_issue_more
== 0)
22624 can_issue_more
= issue_rate
- 1;
22627 for (i
= 0; i
< issue_rate
; i
++)
22629 group_insns
[i
] = 0;
22636 emit_insn_before (nop
, next_insn
);
22637 if (can_issue_more
== issue_rate
- 1) /* new group begins */
22640 if (can_issue_more
== 0)
22642 can_issue_more
= issue_rate
- 1;
22645 for (i
= 0; i
< issue_rate
; i
++)
22647 group_insns
[i
] = 0;
22653 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
22656 /* Is next_insn going to start a new group? */
22659 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
22660 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
22661 || (can_issue_more
< issue_rate
&&
22662 insn_terminates_group_p (next_insn
, previous_group
)));
22663 if (*group_end
&& end
)
22666 if (sched_verbose
> 6)
22667 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
22668 *group_count
, can_issue_more
);
22669 return can_issue_more
;
22672 return can_issue_more
;
22675 /* This function tries to synch the dispatch groups that the compiler "sees"
22676 with the dispatch groups that the processor dispatcher is expected to
22677 form in practice. It tries to achieve this synchronization by forcing the
22678 estimated processor grouping on the compiler (as opposed to the function
22679 'pad_goups' which tries to force the scheduler's grouping on the processor).
22681 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
22682 examines the (estimated) dispatch groups that will be formed by the processor
22683 dispatcher. It marks these group boundaries to reflect the estimated
22684 processor grouping, overriding the grouping that the scheduler had marked.
22685 Depending on the value of the flag '-minsert-sched-nops' this function can
22686 force certain insns into separate groups or force a certain distance between
22687 them by inserting nops, for example, if there exists a "costly dependence"
22690 The function estimates the group boundaries that the processor will form as
22691 follows: It keeps track of how many vacant issue slots are available after
22692 each insn. A subsequent insn will start a new group if one of the following
22694 - no more vacant issue slots remain in the current dispatch group.
22695 - only the last issue slot, which is the branch slot, is vacant, but the next
22696 insn is not a branch.
22697 - only the last 2 or less issue slots, including the branch slot, are vacant,
22698 which means that a cracked insn (which occupies two issue slots) can't be
22699 issued in this group.
22700 - less than 'issue_rate' slots are vacant, and the next insn always needs to
22701 start a new group. */
22704 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
22706 rtx insn
, next_insn
;
22708 int can_issue_more
;
22711 int group_count
= 0;
22715 issue_rate
= rs6000_issue_rate ();
22716 group_insns
= XALLOCAVEC (rtx
, issue_rate
);
22717 for (i
= 0; i
< issue_rate
; i
++)
22719 group_insns
[i
] = 0;
22721 can_issue_more
= issue_rate
;
22723 insn
= get_next_active_insn (prev_head_insn
, tail
);
22726 while (insn
!= NULL_RTX
)
22728 slot
= (issue_rate
- can_issue_more
);
22729 group_insns
[slot
] = insn
;
22731 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
22732 if (insn_terminates_group_p (insn
, current_group
))
22733 can_issue_more
= 0;
22735 next_insn
= get_next_active_insn (insn
, tail
);
22736 if (next_insn
== NULL_RTX
)
22737 return group_count
+ 1;
22739 /* Is next_insn going to start a new group? */
22741 = (can_issue_more
== 0
22742 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
22743 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
22744 || (can_issue_more
< issue_rate
&&
22745 insn_terminates_group_p (next_insn
, previous_group
)));
22747 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
22748 next_insn
, &group_end
, can_issue_more
,
22754 can_issue_more
= 0;
22755 for (i
= 0; i
< issue_rate
; i
++)
22757 group_insns
[i
] = 0;
22761 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
22762 PUT_MODE (next_insn
, VOIDmode
);
22763 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
22764 PUT_MODE (next_insn
, TImode
);
22767 if (can_issue_more
== 0)
22768 can_issue_more
= issue_rate
;
22771 return group_count
;
22774 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
22775 dispatch group boundaries that the scheduler had marked. Pad with nops
22776 any dispatch groups which have vacant issue slots, in order to force the
22777 scheduler's grouping on the processor dispatcher. The function
22778 returns the number of dispatch groups found. */
22781 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
22783 rtx insn
, next_insn
;
22786 int can_issue_more
;
22788 int group_count
= 0;
22790 /* Initialize issue_rate. */
22791 issue_rate
= rs6000_issue_rate ();
22792 can_issue_more
= issue_rate
;
22794 insn
= get_next_active_insn (prev_head_insn
, tail
);
22795 next_insn
= get_next_active_insn (insn
, tail
);
22797 while (insn
!= NULL_RTX
)
22800 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
22802 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
22804 if (next_insn
== NULL_RTX
)
22809 /* If the scheduler had marked group termination at this location
22810 (between insn and next_insn), and neither insn nor next_insn will
22811 force group termination, pad the group with nops to force group
22814 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
22815 && !insn_terminates_group_p (insn
, current_group
)
22816 && !insn_terminates_group_p (next_insn
, previous_group
))
22818 if (!is_branch_slot_insn (next_insn
))
22821 while (can_issue_more
)
22824 emit_insn_before (nop
, next_insn
);
22829 can_issue_more
= issue_rate
;
22834 next_insn
= get_next_active_insn (insn
, tail
);
22837 return group_count
;
22840 /* We're beginning a new block. Initialize data structures as necessary. */
22843 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED
,
22844 int sched_verbose ATTRIBUTE_UNUSED
,
22845 int max_ready ATTRIBUTE_UNUSED
)
22847 last_scheduled_insn
= NULL_RTX
;
22848 load_store_pendulum
= 0;
22851 /* The following function is called at the end of scheduling BB.
22852 After reload, it inserts nops at insn group bundling. */
22855 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
22860 fprintf (dump
, "=== Finishing schedule.\n");
22862 if (reload_completed
&& rs6000_sched_groups
)
22864 /* Do not run sched_finish hook when selective scheduling enabled. */
22865 if (sel_sched_p ())
22868 if (rs6000_sched_insert_nops
== sched_finish_none
)
22871 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
22872 n_groups
= pad_groups (dump
, sched_verbose
,
22873 current_sched_info
->prev_head
,
22874 current_sched_info
->next_tail
);
22876 n_groups
= redefine_groups (dump
, sched_verbose
,
22877 current_sched_info
->prev_head
,
22878 current_sched_info
->next_tail
);
22880 if (sched_verbose
>= 6)
22882 fprintf (dump
, "ngroups = %d\n", n_groups
);
22883 print_rtl (dump
, current_sched_info
->prev_head
);
22884 fprintf (dump
, "Done finish_sched\n");
22889 struct _rs6000_sched_context
22891 short cached_can_issue_more
;
22892 rtx last_scheduled_insn
;
22893 int load_store_pendulum
;
22896 typedef struct _rs6000_sched_context rs6000_sched_context_def
;
22897 typedef rs6000_sched_context_def
*rs6000_sched_context_t
;
22899 /* Allocate store for new scheduling context. */
22901 rs6000_alloc_sched_context (void)
22903 return xmalloc (sizeof (rs6000_sched_context_def
));
22906 /* If CLEAN_P is true then initializes _SC with clean data,
22907 and from the global context otherwise. */
22909 rs6000_init_sched_context (void *_sc
, bool clean_p
)
22911 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
22915 sc
->cached_can_issue_more
= 0;
22916 sc
->last_scheduled_insn
= NULL_RTX
;
22917 sc
->load_store_pendulum
= 0;
22921 sc
->cached_can_issue_more
= cached_can_issue_more
;
22922 sc
->last_scheduled_insn
= last_scheduled_insn
;
22923 sc
->load_store_pendulum
= load_store_pendulum
;
22927 /* Sets the global scheduling context to the one pointed to by _SC. */
22929 rs6000_set_sched_context (void *_sc
)
22931 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
22933 gcc_assert (sc
!= NULL
);
22935 cached_can_issue_more
= sc
->cached_can_issue_more
;
22936 last_scheduled_insn
= sc
->last_scheduled_insn
;
22937 load_store_pendulum
= sc
->load_store_pendulum
;
22942 rs6000_free_sched_context (void *_sc
)
22944 gcc_assert (_sc
!= NULL
);
22950 /* Length in units of the trampoline for entering a nested function. */
22953 rs6000_trampoline_size (void)
22957 switch (DEFAULT_ABI
)
22960 gcc_unreachable ();
22963 ret
= (TARGET_32BIT
) ? 12 : 24;
22968 ret
= (TARGET_32BIT
) ? 40 : 48;
22975 /* Emit RTL insns to initialize the variable parts of a trampoline.
22976 FNADDR is an RTX for the address of the function's pure code.
22977 CXT is an RTX for the static chain value for the function. */
22980 rs6000_trampoline_init (rtx m_tramp
, tree fndecl
, rtx cxt
)
22982 int regsize
= (TARGET_32BIT
) ? 4 : 8;
22983 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
22984 rtx ctx_reg
= force_reg (Pmode
, cxt
);
22985 rtx addr
= force_reg (Pmode
, XEXP (m_tramp
, 0));
22987 switch (DEFAULT_ABI
)
22990 gcc_unreachable ();
22992 /* Under AIX, just build the 3 word function descriptor */
22995 rtx fnmem
= gen_const_mem (Pmode
, force_reg (Pmode
, fnaddr
));
22996 rtx fn_reg
= gen_reg_rtx (Pmode
);
22997 rtx toc_reg
= gen_reg_rtx (Pmode
);
22999 /* Macro to shorten the code expansions below. */
23000 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23002 m_tramp
= replace_equiv_address (m_tramp
, addr
);
23004 emit_move_insn (fn_reg
, MEM_PLUS (fnmem
, 0));
23005 emit_move_insn (toc_reg
, MEM_PLUS (fnmem
, regsize
));
23006 emit_move_insn (MEM_PLUS (m_tramp
, 0), fn_reg
);
23007 emit_move_insn (MEM_PLUS (m_tramp
, regsize
), toc_reg
);
23008 emit_move_insn (MEM_PLUS (m_tramp
, 2*regsize
), ctx_reg
);
23014 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23017 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__trampoline_setup"),
23018 LCT_NORMAL
, VOIDmode
, 4,
23020 GEN_INT (rs6000_trampoline_size ()), SImode
,
23028 /* Handle the "altivec" attribute. The attribute may have
23029 arguments as follows:
23031 __attribute__((altivec(vector__)))
23032 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23033 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23035 and may appear more than once (e.g., 'vector bool char') in a
23036 given declaration. */
23039 rs6000_handle_altivec_attribute (tree
*node
,
23040 tree name ATTRIBUTE_UNUSED
,
23042 int flags ATTRIBUTE_UNUSED
,
23043 bool *no_add_attrs
)
23045 tree type
= *node
, result
= NULL_TREE
;
23046 enum machine_mode mode
;
23049 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
23050 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
23051 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
23054 while (POINTER_TYPE_P (type
)
23055 || TREE_CODE (type
) == FUNCTION_TYPE
23056 || TREE_CODE (type
) == METHOD_TYPE
23057 || TREE_CODE (type
) == ARRAY_TYPE
)
23058 type
= TREE_TYPE (type
);
23060 mode
= TYPE_MODE (type
);
23062 /* Check for invalid AltiVec type qualifiers. */
23063 if (type
== long_double_type_node
)
23064 error ("use of %<long double%> in AltiVec types is invalid");
23065 else if (type
== boolean_type_node
)
23066 error ("use of boolean types in AltiVec types is invalid");
23067 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
23068 error ("use of %<complex%> in AltiVec types is invalid");
23069 else if (DECIMAL_FLOAT_MODE_P (mode
))
23070 error ("use of decimal floating point types in AltiVec types is invalid");
23071 else if (!TARGET_VSX
)
23073 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
23076 error ("use of %<long%> in AltiVec types is invalid for "
23077 "64-bit code without -mvsx");
23078 else if (rs6000_warn_altivec_long
)
23079 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23082 else if (type
== long_long_unsigned_type_node
23083 || type
== long_long_integer_type_node
)
23084 error ("use of %<long long%> in AltiVec types is invalid without "
23086 else if (type
== double_type_node
)
23087 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23090 switch (altivec_type
)
23093 unsigned_p
= TYPE_UNSIGNED (type
);
23097 result
= (unsigned_p
? unsigned_V2DI_type_node
: V2DI_type_node
);
23100 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
23103 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
23106 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
23108 case SFmode
: result
= V4SF_type_node
; break;
23109 case DFmode
: result
= V2DF_type_node
; break;
23110 /* If the user says 'vector int bool', we may be handed the 'bool'
23111 attribute _before_ the 'vector' attribute, and so select the
23112 proper type in the 'b' case below. */
23113 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
23114 case V2DImode
: case V2DFmode
:
23122 case DImode
: case V2DImode
: result
= bool_V2DI_type_node
; break;
23123 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
23124 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
23125 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
23132 case V8HImode
: result
= pixel_V8HI_type_node
;
23138 /* Propagate qualifiers attached to the element type
23139 onto the vector type. */
23140 if (result
&& result
!= type
&& TYPE_QUALS (type
))
23141 result
= build_qualified_type (result
, TYPE_QUALS (type
));
23143 *no_add_attrs
= true; /* No need to hang on to the attribute. */
23146 *node
= lang_hooks
.types
.reconstruct_complex_type (*node
, result
);
23151 /* AltiVec defines four built-in scalar types that serve as vector
23152 elements; we must teach the compiler how to mangle them. */
23154 static const char *
23155 rs6000_mangle_type (const_tree type
)
23157 type
= TYPE_MAIN_VARIANT (type
);
23159 if (TREE_CODE (type
) != VOID_TYPE
&& TREE_CODE (type
) != BOOLEAN_TYPE
23160 && TREE_CODE (type
) != INTEGER_TYPE
&& TREE_CODE (type
) != REAL_TYPE
)
23163 if (type
== bool_char_type_node
) return "U6__boolc";
23164 if (type
== bool_short_type_node
) return "U6__bools";
23165 if (type
== pixel_type_node
) return "u7__pixel";
23166 if (type
== bool_int_type_node
) return "U6__booli";
23167 if (type
== bool_long_type_node
) return "U6__booll";
23169 /* Mangle IBM extended float long double as `g' (__float128) on
23170 powerpc*-linux where long-double-64 previously was the default. */
23171 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
23173 && TARGET_LONG_DOUBLE_128
23174 && !TARGET_IEEEQUAD
)
23177 /* For all other types, use normal C++ mangling. */
23181 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23182 struct attribute_spec.handler. */
23185 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
23186 tree args ATTRIBUTE_UNUSED
,
23187 int flags ATTRIBUTE_UNUSED
,
23188 bool *no_add_attrs
)
23190 if (TREE_CODE (*node
) != FUNCTION_TYPE
23191 && TREE_CODE (*node
) != FIELD_DECL
23192 && TREE_CODE (*node
) != TYPE_DECL
)
23194 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
23196 *no_add_attrs
= true;
23202 /* Set longcall attributes on all functions declared when
23203 rs6000_default_long_calls is true. */
23205 rs6000_set_default_type_attributes (tree type
)
23207 if (rs6000_default_long_calls
23208 && (TREE_CODE (type
) == FUNCTION_TYPE
23209 || TREE_CODE (type
) == METHOD_TYPE
))
23210 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
23212 TYPE_ATTRIBUTES (type
));
23215 darwin_set_default_type_attributes (type
);
23219 /* Return a reference suitable for calling a function with the
23220 longcall attribute. */
23223 rs6000_longcall_ref (rtx call_ref
)
23225 const char *call_name
;
23228 if (GET_CODE (call_ref
) != SYMBOL_REF
)
23231 /* System V adds '.' to the internal name, so skip them. */
23232 call_name
= XSTR (call_ref
, 0);
23233 if (*call_name
== '.')
23235 while (*call_name
== '.')
23238 node
= get_identifier (call_name
);
23239 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
23242 return force_reg (Pmode
, call_ref
);
23245 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23246 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23249 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23250 struct attribute_spec.handler. */
23252 rs6000_handle_struct_attribute (tree
*node
, tree name
,
23253 tree args ATTRIBUTE_UNUSED
,
23254 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
23257 if (DECL_P (*node
))
23259 if (TREE_CODE (*node
) == TYPE_DECL
)
23260 type
= &TREE_TYPE (*node
);
23265 if (!(type
&& (TREE_CODE (*type
) == RECORD_TYPE
23266 || TREE_CODE (*type
) == UNION_TYPE
)))
23268 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
23269 *no_add_attrs
= true;
23272 else if ((is_attribute_p ("ms_struct", name
)
23273 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type
)))
23274 || ((is_attribute_p ("gcc_struct", name
)
23275 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type
)))))
23277 warning (OPT_Wattributes
, "%qE incompatible attribute ignored",
23279 *no_add_attrs
= true;
23286 rs6000_ms_bitfield_layout_p (const_tree record_type
)
23288 return (TARGET_USE_MS_BITFIELD_LAYOUT
&&
23289 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type
)))
23290 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type
));
23293 #ifdef USING_ELFOS_H
23295 /* A get_unnamed_section callback, used for switching to toc_section. */
23298 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
23300 if (DEFAULT_ABI
== ABI_AIX
23301 && TARGET_MINIMAL_TOC
23302 && !TARGET_RELOCATABLE
)
23304 if (!toc_initialized
)
23306 toc_initialized
= 1;
23307 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
23308 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LCTOC", 0);
23309 fprintf (asm_out_file
, "\t.tc ");
23310 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1[TC],");
23311 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
23312 fprintf (asm_out_file
, "\n");
23314 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
23315 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
23316 fprintf (asm_out_file
, " = .+32768\n");
23319 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
23321 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_RELOCATABLE
)
23322 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
23325 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
23326 if (!toc_initialized
)
23328 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
23329 fprintf (asm_out_file
, " = .+32768\n");
23330 toc_initialized
= 1;
23335 /* Implement TARGET_ASM_INIT_SECTIONS. */
23338 rs6000_elf_asm_init_sections (void)
23341 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op
, NULL
);
23344 = get_unnamed_section (SECTION_WRITE
, output_section_asm_op
,
23345 SDATA2_SECTION_ASM_OP
);
23348 /* Implement TARGET_SELECT_RTX_SECTION. */
23351 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
23352 unsigned HOST_WIDE_INT align
)
23354 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
23355 return toc_section
;
23357 return default_elf_select_rtx_section (mode
, x
, align
);
23360 /* For a SYMBOL_REF, set generic flags and then perform some
23361 target-specific processing.
23363 When the AIX ABI is requested on a non-AIX system, replace the
23364 function name with the real name (with a leading .) rather than the
23365 function descriptor name. This saves a lot of overriding code to
23366 read the prefixes. */
23369 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
23371 default_encode_section_info (decl
, rtl
, first
);
23374 && TREE_CODE (decl
) == FUNCTION_DECL
23376 && DEFAULT_ABI
== ABI_AIX
)
23378 rtx sym_ref
= XEXP (rtl
, 0);
23379 size_t len
= strlen (XSTR (sym_ref
, 0));
23380 char *str
= XALLOCAVEC (char, len
+ 2);
23382 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
23383 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
23388 compare_section_name (const char *section
, const char *templ
)
23392 len
= strlen (templ
);
23393 return (strncmp (section
, templ
, len
) == 0
23394 && (section
[len
] == 0 || section
[len
] == '.'));
23398 rs6000_elf_in_small_data_p (const_tree decl
)
23400 if (rs6000_sdata
== SDATA_NONE
)
23403 /* We want to merge strings, so we never consider them small data. */
23404 if (TREE_CODE (decl
) == STRING_CST
)
23407 /* Functions are never in the small data area. */
23408 if (TREE_CODE (decl
) == FUNCTION_DECL
)
23411 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
23413 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
23414 if (compare_section_name (section
, ".sdata")
23415 || compare_section_name (section
, ".sdata2")
23416 || compare_section_name (section
, ".gnu.linkonce.s")
23417 || compare_section_name (section
, ".sbss")
23418 || compare_section_name (section
, ".sbss2")
23419 || compare_section_name (section
, ".gnu.linkonce.sb")
23420 || strcmp (section
, ".PPC.EMB.sdata0") == 0
23421 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
23426 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
23429 && (unsigned HOST_WIDE_INT
) size
<= g_switch_value
23430 /* If it's not public, and we're not going to reference it there,
23431 there's no need to put it in the small data section. */
23432 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
23439 #endif /* USING_ELFOS_H */
23441 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
23444 rs6000_use_blocks_for_constant_p (enum machine_mode mode
, const_rtx x
)
23446 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
);
23449 /* Return a REG that occurs in ADDR with coefficient 1.
23450 ADDR can be effectively incremented by incrementing REG.
23452 r0 is special and we must not select it as an address
23453 register by this routine since our caller will try to
23454 increment the returned register via an "la" instruction. */
23457 find_addr_reg (rtx addr
)
23459 while (GET_CODE (addr
) == PLUS
)
23461 if (GET_CODE (XEXP (addr
, 0)) == REG
23462 && REGNO (XEXP (addr
, 0)) != 0)
23463 addr
= XEXP (addr
, 0);
23464 else if (GET_CODE (XEXP (addr
, 1)) == REG
23465 && REGNO (XEXP (addr
, 1)) != 0)
23466 addr
= XEXP (addr
, 1);
23467 else if (CONSTANT_P (XEXP (addr
, 0)))
23468 addr
= XEXP (addr
, 1);
23469 else if (CONSTANT_P (XEXP (addr
, 1)))
23470 addr
= XEXP (addr
, 0);
23472 gcc_unreachable ();
23474 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
23479 rs6000_fatal_bad_address (rtx op
)
23481 fatal_insn ("bad address", op
);
23486 static tree branch_island_list
= 0;
23488 /* Remember to generate a branch island for far calls to the given
23492 add_compiler_branch_island (tree label_name
, tree function_name
,
23495 tree branch_island
= build_tree_list (function_name
, label_name
);
23496 TREE_TYPE (branch_island
) = build_int_cst (NULL_TREE
, line_number
);
23497 TREE_CHAIN (branch_island
) = branch_island_list
;
23498 branch_island_list
= branch_island
;
23501 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
23502 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
23503 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
23504 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
23506 /* Generate far-jump branch islands for everything on the
23507 branch_island_list. Invoked immediately after the last instruction
23508 of the epilogue has been emitted; the branch-islands must be
23509 appended to, and contiguous with, the function body. Mach-O stubs
23510 are generated in machopic_output_stub(). */
23513 macho_branch_islands (void)
23516 tree branch_island
;
23518 for (branch_island
= branch_island_list
;
23520 branch_island
= TREE_CHAIN (branch_island
))
23522 const char *label
=
23523 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island
));
23525 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island
));
23526 char name_buf
[512];
23527 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
23528 if (name
[0] == '*' || name
[0] == '&')
23529 strcpy (name_buf
, name
+1);
23533 strcpy (name_buf
+1, name
);
23535 strcpy (tmp_buf
, "\n");
23536 strcat (tmp_buf
, label
);
23537 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23538 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
23539 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
23540 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23543 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
23544 strcat (tmp_buf
, label
);
23545 strcat (tmp_buf
, "_pic\n");
23546 strcat (tmp_buf
, label
);
23547 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
23549 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
23550 strcat (tmp_buf
, name_buf
);
23551 strcat (tmp_buf
, " - ");
23552 strcat (tmp_buf
, label
);
23553 strcat (tmp_buf
, "_pic)\n");
23555 strcat (tmp_buf
, "\tmtlr r0\n");
23557 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
23558 strcat (tmp_buf
, name_buf
);
23559 strcat (tmp_buf
, " - ");
23560 strcat (tmp_buf
, label
);
23561 strcat (tmp_buf
, "_pic)\n");
23563 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
23567 strcat (tmp_buf
, ":\nlis r12,hi16(");
23568 strcat (tmp_buf
, name_buf
);
23569 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
23570 strcat (tmp_buf
, name_buf
);
23571 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
23573 output_asm_insn (tmp_buf
, 0);
23574 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
23575 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
23576 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
23577 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
23580 branch_island_list
= 0;
23583 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
23584 already there or not. */
23587 no_previous_def (tree function_name
)
23589 tree branch_island
;
23590 for (branch_island
= branch_island_list
;
23592 branch_island
= TREE_CHAIN (branch_island
))
23593 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
23598 /* GET_PREV_LABEL gets the label name from the previous definition of
23602 get_prev_label (tree function_name
)
23604 tree branch_island
;
23605 for (branch_island
= branch_island_list
;
23607 branch_island
= TREE_CHAIN (branch_island
))
23608 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
23609 return BRANCH_ISLAND_LABEL_NAME (branch_island
);
23613 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
23614 #define DARWIN_LINKER_GENERATES_ISLANDS 0
23617 /* KEXTs still need branch islands. */
23618 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
23619 || flag_mkernel || flag_apple_kext)
23621 /* INSN is either a function call or a millicode call. It may have an
23622 unconditional jump in its delay slot.
23624 CALL_DEST is the routine we are calling. */
23627 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
23628 int cookie_operand_number
)
23630 static char buf
[256];
23631 if (DARWIN_GENERATE_ISLANDS
23632 && GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
23633 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
23636 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
23638 if (no_previous_def (funname
))
23640 rtx label_rtx
= gen_label_rtx ();
23641 char *label_buf
, temp_buf
[256];
23642 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
23643 CODE_LABEL_NUMBER (label_rtx
));
23644 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
23645 labelname
= get_identifier (label_buf
);
23646 add_compiler_branch_island (labelname
, funname
, insn_line (insn
));
23649 labelname
= get_prev_label (funname
);
23651 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
23652 instruction will reach 'foo', otherwise link as 'bl L42'".
23653 "L42" should be a 'branch island', that will do a far jump to
23654 'foo'. Branch islands are generated in
23655 macho_branch_islands(). */
23656 sprintf (buf
, "jbsr %%z%d,%.246s",
23657 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
23660 sprintf (buf
, "bl %%z%d", dest_operand_number
);
23664 /* Generate PIC and indirect symbol stubs. */
23667 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
23669 unsigned int length
;
23670 char *symbol_name
, *lazy_ptr_name
;
23671 char *local_label_0
;
23672 static int label
= 0;
23674 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23675 symb
= (*targetm
.strip_name_encoding
) (symb
);
23678 length
= strlen (symb
);
23679 symbol_name
= XALLOCAVEC (char, length
+ 32);
23680 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
23682 lazy_ptr_name
= XALLOCAVEC (char, length
+ 32);
23683 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
23686 switch_to_section (darwin_sections
[machopic_picsymbol_stub1_section
]);
23688 switch_to_section (darwin_sections
[machopic_symbol_stub1_section
]);
23692 fprintf (file
, "\t.align 5\n");
23694 fprintf (file
, "%s:\n", stub
);
23695 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
23698 local_label_0
= XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
23699 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
23701 fprintf (file
, "\tmflr r0\n");
23702 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
23703 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
23704 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
23705 lazy_ptr_name
, local_label_0
);
23706 fprintf (file
, "\tmtlr r0\n");
23707 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
23708 (TARGET_64BIT
? "ldu" : "lwzu"),
23709 lazy_ptr_name
, local_label_0
);
23710 fprintf (file
, "\tmtctr r12\n");
23711 fprintf (file
, "\tbctr\n");
23715 fprintf (file
, "\t.align 4\n");
23717 fprintf (file
, "%s:\n", stub
);
23718 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
23720 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
23721 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
23722 (TARGET_64BIT
? "ldu" : "lwzu"),
23724 fprintf (file
, "\tmtctr r12\n");
23725 fprintf (file
, "\tbctr\n");
23728 switch_to_section (darwin_sections
[machopic_lazy_symbol_ptr_section
]);
23729 fprintf (file
, "%s:\n", lazy_ptr_name
);
23730 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
23731 fprintf (file
, "%sdyld_stub_binding_helper\n",
23732 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
23735 /* Legitimize PIC addresses. If the address is already
23736 position-independent, we return ORIG. Newly generated
23737 position-independent addresses go into a reg. This is REG if non
23738 zero, otherwise we allocate register(s) as necessary. */
23740 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
23743 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
23748 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
23749 reg
= gen_reg_rtx (Pmode
);
23751 if (GET_CODE (orig
) == CONST
)
23755 if (GET_CODE (XEXP (orig
, 0)) == PLUS
23756 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
23759 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
23761 /* Use a different reg for the intermediate value, as
23762 it will be marked UNCHANGING. */
23763 reg_temp
= !can_create_pseudo_p () ? reg
: gen_reg_rtx (Pmode
);
23764 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
23767 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
23770 if (GET_CODE (offset
) == CONST_INT
)
23772 if (SMALL_INT (offset
))
23773 return plus_constant (base
, INTVAL (offset
));
23774 else if (! reload_in_progress
&& ! reload_completed
)
23775 offset
= force_reg (Pmode
, offset
);
23778 rtx mem
= force_const_mem (Pmode
, orig
);
23779 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
23782 return gen_rtx_PLUS (Pmode
, base
, offset
);
23785 /* Fall back on generic machopic code. */
23786 return machopic_legitimize_pic_address (orig
, mode
, reg
);
23789 /* Output a .machine directive for the Darwin assembler, and call
23790 the generic start_file routine. */
23793 rs6000_darwin_file_start (void)
23795 static const struct
23801 { "ppc64", "ppc64", MASK_64BIT
},
23802 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
23803 { "power4", "ppc970", 0 },
23804 { "G5", "ppc970", 0 },
23805 { "7450", "ppc7450", 0 },
23806 { "7400", "ppc7400", MASK_ALTIVEC
},
23807 { "G4", "ppc7400", 0 },
23808 { "750", "ppc750", 0 },
23809 { "740", "ppc750", 0 },
23810 { "G3", "ppc750", 0 },
23811 { "604e", "ppc604e", 0 },
23812 { "604", "ppc604", 0 },
23813 { "603e", "ppc603", 0 },
23814 { "603", "ppc603", 0 },
23815 { "601", "ppc601", 0 },
23816 { NULL
, "ppc", 0 } };
23817 const char *cpu_id
= "";
23820 rs6000_file_start ();
23821 darwin_file_start ();
23823 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
23824 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
23825 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
23826 && rs6000_select
[i
].string
[0] != '\0')
23827 cpu_id
= rs6000_select
[i
].string
;
23829 /* Look through the mapping array. Pick the first name that either
23830 matches the argument, has a bit set in IF_SET that is also set
23831 in the target flags, or has a NULL name. */
23834 while (mapping
[i
].arg
!= NULL
23835 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
23836 && (mapping
[i
].if_set
& target_flags
) == 0)
23839 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
23842 #endif /* TARGET_MACHO */
23846 rs6000_elf_reloc_rw_mask (void)
23850 else if (DEFAULT_ABI
== ABI_AIX
)
23856 /* Record an element in the table of global constructors. SYMBOL is
23857 a SYMBOL_REF of the function to be called; PRIORITY is a number
23858 between 0 and MAX_INIT_PRIORITY.
23860 This differs from default_named_section_asm_out_constructor in
23861 that we have special handling for -mrelocatable. */
23864 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
23866 const char *section
= ".ctors";
23869 if (priority
!= DEFAULT_INIT_PRIORITY
)
23871 sprintf (buf
, ".ctors.%.5u",
23872 /* Invert the numbering so the linker puts us in the proper
23873 order; constructors are run from right to left, and the
23874 linker sorts in increasing order. */
23875 MAX_INIT_PRIORITY
- priority
);
23879 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
23880 assemble_align (POINTER_SIZE
);
23882 if (TARGET_RELOCATABLE
)
23884 fputs ("\t.long (", asm_out_file
);
23885 output_addr_const (asm_out_file
, symbol
);
23886 fputs (")@fixup\n", asm_out_file
);
23889 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
23893 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
23895 const char *section
= ".dtors";
23898 if (priority
!= DEFAULT_INIT_PRIORITY
)
23900 sprintf (buf
, ".dtors.%.5u",
23901 /* Invert the numbering so the linker puts us in the proper
23902 order; constructors are run from right to left, and the
23903 linker sorts in increasing order. */
23904 MAX_INIT_PRIORITY
- priority
);
23908 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
23909 assemble_align (POINTER_SIZE
);
23911 if (TARGET_RELOCATABLE
)
23913 fputs ("\t.long (", asm_out_file
);
23914 output_addr_const (asm_out_file
, symbol
);
23915 fputs (")@fixup\n", asm_out_file
);
23918 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
23922 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
23926 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
23927 ASM_OUTPUT_LABEL (file
, name
);
23928 fputs (DOUBLE_INT_ASM_OP
, file
);
23929 rs6000_output_function_entry (file
, name
);
23930 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
23933 fputs ("\t.size\t", file
);
23934 assemble_name (file
, name
);
23935 fputs (",24\n\t.type\t.", file
);
23936 assemble_name (file
, name
);
23937 fputs (",@function\n", file
);
23938 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
23940 fputs ("\t.globl\t.", file
);
23941 assemble_name (file
, name
);
23946 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
23947 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
23948 rs6000_output_function_entry (file
, name
);
23949 fputs (":\n", file
);
23953 if (TARGET_RELOCATABLE
23954 && !TARGET_SECURE_PLT
23955 && (get_pool_size () != 0 || crtl
->profile
)
23960 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
23962 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
23963 fprintf (file
, "\t.long ");
23964 assemble_name (file
, buf
);
23966 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
23967 assemble_name (file
, buf
);
23971 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
23972 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
23974 if (DEFAULT_ABI
== ABI_AIX
)
23976 const char *desc_name
, *orig_name
;
23978 orig_name
= (*targetm
.strip_name_encoding
) (name
);
23979 desc_name
= orig_name
;
23980 while (*desc_name
== '.')
23983 if (TREE_PUBLIC (decl
))
23984 fprintf (file
, "\t.globl %s\n", desc_name
);
23986 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
23987 fprintf (file
, "%s:\n", desc_name
);
23988 fprintf (file
, "\t.long %s\n", orig_name
);
23989 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
23990 if (DEFAULT_ABI
== ABI_AIX
)
23991 fputs ("\t.long 0\n", file
);
23992 fprintf (file
, "\t.previous\n");
23994 ASM_OUTPUT_LABEL (file
, name
);
23998 rs6000_elf_end_indicate_exec_stack (void)
24001 file_end_indicate_exec_stack ();
24007 rs6000_xcoff_asm_output_anchor (rtx symbol
)
24011 sprintf (buffer
, "$ + " HOST_WIDE_INT_PRINT_DEC
,
24012 SYMBOL_REF_BLOCK_OFFSET (symbol
));
24013 ASM_OUTPUT_DEF (asm_out_file
, XSTR (symbol
, 0), buffer
);
24017 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
24019 fputs (GLOBAL_ASM_OP
, stream
);
24020 RS6000_OUTPUT_BASENAME (stream
, name
);
24021 putc ('\n', stream
);
24024 /* A get_unnamed_decl callback, used for read-only sections. PTR
24025 points to the section string variable. */
24028 rs6000_xcoff_output_readonly_section_asm_op (const void *directive
)
24030 fprintf (asm_out_file
, "\t.csect %s[RO],%s\n",
24031 *(const char *const *) directive
,
24032 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
24035 /* Likewise for read-write sections. */
24038 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive
)
24040 fprintf (asm_out_file
, "\t.csect %s[RW],%s\n",
24041 *(const char *const *) directive
,
24042 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
24045 /* A get_unnamed_section callback, used for switching to toc_section. */
24048 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
24050 if (TARGET_MINIMAL_TOC
)
24052 /* toc_section is always selected at least once from
24053 rs6000_xcoff_file_start, so this is guaranteed to
24054 always be defined once and only once in each file. */
24055 if (!toc_initialized
)
24057 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file
);
24058 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file
);
24059 toc_initialized
= 1;
24061 fprintf (asm_out_file
, "\t.csect toc_table[RW]%s\n",
24062 (TARGET_32BIT
? "" : ",3"));
24065 fputs ("\t.toc\n", asm_out_file
);
24068 /* Implement TARGET_ASM_INIT_SECTIONS. */
24071 rs6000_xcoff_asm_init_sections (void)
24073 read_only_data_section
24074 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
24075 &xcoff_read_only_section_name
);
24077 private_data_section
24078 = get_unnamed_section (SECTION_WRITE
,
24079 rs6000_xcoff_output_readwrite_section_asm_op
,
24080 &xcoff_private_data_section_name
);
24082 read_only_private_data_section
24083 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
24084 &xcoff_private_data_section_name
);
24087 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op
, NULL
);
24089 readonly_data_section
= read_only_data_section
;
24090 exception_section
= data_section
;
24094 rs6000_xcoff_reloc_rw_mask (void)
24100 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
24101 tree decl ATTRIBUTE_UNUSED
)
24104 static const char * const suffix
[3] = { "PR", "RO", "RW" };
24106 if (flags
& SECTION_CODE
)
24108 else if (flags
& SECTION_WRITE
)
24113 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
24114 (flags
& SECTION_CODE
) ? "." : "",
24115 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
24119 rs6000_xcoff_select_section (tree decl
, int reloc
,
24120 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
24122 if (decl_readonly_section (decl
, reloc
))
24124 if (TREE_PUBLIC (decl
))
24125 return read_only_data_section
;
24127 return read_only_private_data_section
;
24131 if (TREE_PUBLIC (decl
))
24132 return data_section
;
24134 return private_data_section
;
24139 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
24143 /* Use select_section for private and uninitialized data. */
24144 if (!TREE_PUBLIC (decl
)
24145 || DECL_COMMON (decl
)
24146 || DECL_INITIAL (decl
) == NULL_TREE
24147 || DECL_INITIAL (decl
) == error_mark_node
24148 || (flag_zero_initialized_in_bss
24149 && initializer_zerop (DECL_INITIAL (decl
))))
24152 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
24153 name
= (*targetm
.strip_name_encoding
) (name
);
24154 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
24157 /* Select section for constant in constant pool.
24159 On RS/6000, all constants are in the private read-only data area.
24160 However, if this is being placed in the TOC it must be output as a
24164 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
24165 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
24167 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
24168 return toc_section
;
24170 return read_only_private_data_section
;
24173 /* Remove any trailing [DS] or the like from the symbol name. */
24175 static const char *
24176 rs6000_xcoff_strip_name_encoding (const char *name
)
24181 len
= strlen (name
);
24182 if (name
[len
- 1] == ']')
24183 return ggc_alloc_string (name
, len
- 4);
24188 /* Section attributes. AIX is always PIC. */
24190 static unsigned int
24191 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
24193 unsigned int align
;
24194 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
24196 /* Align to at least UNIT size. */
24197 if (flags
& SECTION_CODE
)
24198 align
= MIN_UNITS_PER_WORD
;
24200 /* Increase alignment of large objects if not already stricter. */
24201 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
24202 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
24203 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
24205 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
24208 /* Output at beginning of assembler file.
24210 Initialize the section names for the RS/6000 at this point.
24212 Specify filename, including full path, to assembler.
24214 We want to go into the TOC section so at least one .toc will be emitted.
24215 Also, in order to output proper .bs/.es pairs, we need at least one static
24216 [RW] section emitted.
24218 Finally, declare mcount when profiling to make the assembler happy. */
24221 rs6000_xcoff_file_start (void)
24223 rs6000_gen_section_name (&xcoff_bss_section_name
,
24224 main_input_filename
, ".bss_");
24225 rs6000_gen_section_name (&xcoff_private_data_section_name
,
24226 main_input_filename
, ".rw_");
24227 rs6000_gen_section_name (&xcoff_read_only_section_name
,
24228 main_input_filename
, ".ro_");
24230 fputs ("\t.file\t", asm_out_file
);
24231 output_quoted_string (asm_out_file
, main_input_filename
);
24232 fputc ('\n', asm_out_file
);
24233 if (write_symbols
!= NO_DEBUG
)
24234 switch_to_section (private_data_section
);
24235 switch_to_section (text_section
);
24237 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
24238 rs6000_file_start ();
24241 /* Output at end of assembler file.
24242 On the RS/6000, referencing data should automatically pull in text. */
24245 rs6000_xcoff_file_end (void)
24247 switch_to_section (text_section
);
24248 fputs ("_section_.text:\n", asm_out_file
);
24249 switch_to_section (data_section
);
24250 fputs (TARGET_32BIT
24251 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24254 #endif /* TARGET_XCOFF */
24256 /* Compute a (partial) cost for rtx X. Return true if the complete
24257 cost has been computed, and false if subexpressions should be
24258 scanned. In either case, *TOTAL contains the cost result. */
24261 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
24264 enum machine_mode mode
= GET_MODE (x
);
24268 /* On the RS/6000, if it is valid in the insn, it is free. */
24270 if (((outer_code
== SET
24271 || outer_code
== PLUS
24272 || outer_code
== MINUS
)
24273 && (satisfies_constraint_I (x
)
24274 || satisfies_constraint_L (x
)))
24275 || (outer_code
== AND
24276 && (satisfies_constraint_K (x
)
24278 ? satisfies_constraint_L (x
)
24279 : satisfies_constraint_J (x
))
24280 || mask_operand (x
, mode
)
24282 && mask64_operand (x
, DImode
))))
24283 || ((outer_code
== IOR
|| outer_code
== XOR
)
24284 && (satisfies_constraint_K (x
)
24286 ? satisfies_constraint_L (x
)
24287 : satisfies_constraint_J (x
))))
24288 || outer_code
== ASHIFT
24289 || outer_code
== ASHIFTRT
24290 || outer_code
== LSHIFTRT
24291 || outer_code
== ROTATE
24292 || outer_code
== ROTATERT
24293 || outer_code
== ZERO_EXTRACT
24294 || (outer_code
== MULT
24295 && satisfies_constraint_I (x
))
24296 || ((outer_code
== DIV
|| outer_code
== UDIV
24297 || outer_code
== MOD
|| outer_code
== UMOD
)
24298 && exact_log2 (INTVAL (x
)) >= 0)
24299 || (outer_code
== COMPARE
24300 && (satisfies_constraint_I (x
)
24301 || satisfies_constraint_K (x
)))
24302 || (outer_code
== EQ
24303 && (satisfies_constraint_I (x
)
24304 || satisfies_constraint_K (x
)
24306 ? satisfies_constraint_L (x
)
24307 : satisfies_constraint_J (x
))))
24308 || (outer_code
== GTU
24309 && satisfies_constraint_I (x
))
24310 || (outer_code
== LTU
24311 && satisfies_constraint_P (x
)))
24316 else if ((outer_code
== PLUS
24317 && reg_or_add_cint_operand (x
, VOIDmode
))
24318 || (outer_code
== MINUS
24319 && reg_or_sub_cint_operand (x
, VOIDmode
))
24320 || ((outer_code
== SET
24321 || outer_code
== IOR
24322 || outer_code
== XOR
)
24324 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
24326 *total
= COSTS_N_INSNS (1);
24332 if (mode
== DImode
&& code
== CONST_DOUBLE
)
24334 if ((outer_code
== IOR
|| outer_code
== XOR
)
24335 && CONST_DOUBLE_HIGH (x
) == 0
24336 && (CONST_DOUBLE_LOW (x
)
24337 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)
24342 else if ((outer_code
== AND
&& and64_2_operand (x
, DImode
))
24343 || ((outer_code
== SET
24344 || outer_code
== IOR
24345 || outer_code
== XOR
)
24346 && CONST_DOUBLE_HIGH (x
) == 0))
24348 *total
= COSTS_N_INSNS (1);
24358 /* When optimizing for size, MEM should be slightly more expensive
24359 than generating address, e.g., (plus (reg) (const)).
24360 L1 cache latency is about two instructions. */
24361 *total
= !speed
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
24369 if (mode
== DFmode
)
24371 if (GET_CODE (XEXP (x
, 0)) == MULT
)
24373 /* FNMA accounted in outer NEG. */
24374 if (outer_code
== NEG
)
24375 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
24377 *total
= rs6000_cost
->dmul
;
24380 *total
= rs6000_cost
->fp
;
24382 else if (mode
== SFmode
)
24384 /* FNMA accounted in outer NEG. */
24385 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
24388 *total
= rs6000_cost
->fp
;
24391 *total
= COSTS_N_INSNS (1);
24395 if (mode
== DFmode
)
24397 if (GET_CODE (XEXP (x
, 0)) == MULT
24398 || GET_CODE (XEXP (x
, 1)) == MULT
)
24400 /* FNMA accounted in outer NEG. */
24401 if (outer_code
== NEG
)
24402 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
24404 *total
= rs6000_cost
->dmul
;
24407 *total
= rs6000_cost
->fp
;
24409 else if (mode
== SFmode
)
24411 /* FNMA accounted in outer NEG. */
24412 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
24415 *total
= rs6000_cost
->fp
;
24418 *total
= COSTS_N_INSNS (1);
24422 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
24423 && satisfies_constraint_I (XEXP (x
, 1)))
24425 if (INTVAL (XEXP (x
, 1)) >= -256
24426 && INTVAL (XEXP (x
, 1)) <= 255)
24427 *total
= rs6000_cost
->mulsi_const9
;
24429 *total
= rs6000_cost
->mulsi_const
;
24431 /* FMA accounted in outer PLUS/MINUS. */
24432 else if ((mode
== DFmode
|| mode
== SFmode
)
24433 && (outer_code
== PLUS
|| outer_code
== MINUS
))
24435 else if (mode
== DFmode
)
24436 *total
= rs6000_cost
->dmul
;
24437 else if (mode
== SFmode
)
24438 *total
= rs6000_cost
->fp
;
24439 else if (mode
== DImode
)
24440 *total
= rs6000_cost
->muldi
;
24442 *total
= rs6000_cost
->mulsi
;
24447 if (FLOAT_MODE_P (mode
))
24449 *total
= mode
== DFmode
? rs6000_cost
->ddiv
24450 : rs6000_cost
->sdiv
;
24457 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
24458 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
24460 if (code
== DIV
|| code
== MOD
)
24462 *total
= COSTS_N_INSNS (2);
24465 *total
= COSTS_N_INSNS (1);
24469 if (GET_MODE (XEXP (x
, 1)) == DImode
)
24470 *total
= rs6000_cost
->divdi
;
24472 *total
= rs6000_cost
->divsi
;
24474 /* Add in shift and subtract for MOD. */
24475 if (code
== MOD
|| code
== UMOD
)
24476 *total
+= COSTS_N_INSNS (2);
24481 *total
= COSTS_N_INSNS (4);
24485 *total
= COSTS_N_INSNS (6);
24489 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
24501 *total
= COSTS_N_INSNS (1);
24509 /* Handle mul_highpart. */
24510 if (outer_code
== TRUNCATE
24511 && GET_CODE (XEXP (x
, 0)) == MULT
)
24513 if (mode
== DImode
)
24514 *total
= rs6000_cost
->muldi
;
24516 *total
= rs6000_cost
->mulsi
;
24519 else if (outer_code
== AND
)
24522 *total
= COSTS_N_INSNS (1);
24527 if (GET_CODE (XEXP (x
, 0)) == MEM
)
24530 *total
= COSTS_N_INSNS (1);
24536 if (!FLOAT_MODE_P (mode
))
24538 *total
= COSTS_N_INSNS (1);
24544 case UNSIGNED_FLOAT
:
24547 case FLOAT_TRUNCATE
:
24548 *total
= rs6000_cost
->fp
;
24552 if (mode
== DFmode
)
24555 *total
= rs6000_cost
->fp
;
24559 switch (XINT (x
, 1))
24562 *total
= rs6000_cost
->fp
;
24574 *total
= COSTS_N_INSNS (1);
24577 else if (FLOAT_MODE_P (mode
)
24578 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
24580 *total
= rs6000_cost
->fp
;
24588 /* Carry bit requires mode == Pmode.
24589 NEG or PLUS already counted so only add one. */
24591 && (outer_code
== NEG
|| outer_code
== PLUS
))
24593 *total
= COSTS_N_INSNS (1);
24596 if (outer_code
== SET
)
24598 if (XEXP (x
, 1) == const0_rtx
)
24600 *total
= COSTS_N_INSNS (2);
24603 else if (mode
== Pmode
)
24605 *total
= COSTS_N_INSNS (3);
24614 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
24616 *total
= COSTS_N_INSNS (2);
24620 if (outer_code
== COMPARE
)
24634 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
24637 rs6000_debug_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
24640 bool ret
= rs6000_rtx_costs (x
, code
, outer_code
, total
, speed
);
24643 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
24644 "total = %d, speed = %s, x:\n",
24645 ret
? "complete" : "scan inner",
24646 GET_RTX_NAME (code
),
24647 GET_RTX_NAME (outer_code
),
24649 speed
? "true" : "false");
24656 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
24659 rs6000_debug_address_cost (rtx x
, bool speed
)
24661 int ret
= TARGET_ADDRESS_COST (x
, speed
);
24663 fprintf (stderr
, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
24664 ret
, speed
? "true" : "false");
24671 /* A C expression returning the cost of moving data from a register of class
24672 CLASS1 to one of CLASS2. */
24675 rs6000_register_move_cost (enum machine_mode mode
,
24676 enum reg_class from
, enum reg_class to
)
24680 /* Moves from/to GENERAL_REGS. */
24681 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
24682 || reg_classes_intersect_p (from
, GENERAL_REGS
))
24684 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
24687 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
|| from
== VSX_REGS
)
24688 ret
= (rs6000_memory_move_cost (mode
, from
, 0)
24689 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, 0));
24691 /* It's more expensive to move CR_REGS than CR0_REGS because of the
24693 else if (from
== CR_REGS
)
24696 /* Power6 has slower LR/CTR moves so make them more expensive than
24697 memory in order to bias spills to memory .*/
24698 else if (rs6000_cpu
== PROCESSOR_POWER6
24699 && reg_classes_intersect_p (from
, LINK_OR_CTR_REGS
))
24700 ret
= 6 * hard_regno_nregs
[0][mode
];
24703 /* A move will cost one instruction per GPR moved. */
24704 ret
= 2 * hard_regno_nregs
[0][mode
];
24707 /* If we have VSX, we can easily move between FPR or Altivec registers. */
24708 else if (VECTOR_UNIT_VSX_P (mode
)
24709 && reg_classes_intersect_p (to
, VSX_REGS
)
24710 && reg_classes_intersect_p (from
, VSX_REGS
))
24711 ret
= 2 * hard_regno_nregs
[32][mode
];
24713 /* Moving between two similar registers is just one instruction. */
24714 else if (reg_classes_intersect_p (to
, from
))
24715 ret
= (mode
== TFmode
|| mode
== TDmode
) ? 4 : 2;
24717 /* Everything else has to go through GENERAL_REGS. */
24719 ret
= (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
24720 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
24722 if (TARGET_DEBUG_COST
)
24724 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
24725 ret
, GET_MODE_NAME (mode
), reg_class_names
[from
],
24726 reg_class_names
[to
]);
24731 /* A C expressions returning the cost of moving data of MODE from a register to
24735 rs6000_memory_move_cost (enum machine_mode mode
, enum reg_class rclass
,
24736 int in ATTRIBUTE_UNUSED
)
24740 if (reg_classes_intersect_p (rclass
, GENERAL_REGS
))
24741 ret
= 4 * hard_regno_nregs
[0][mode
];
24742 else if (reg_classes_intersect_p (rclass
, FLOAT_REGS
))
24743 ret
= 4 * hard_regno_nregs
[32][mode
];
24744 else if (reg_classes_intersect_p (rclass
, ALTIVEC_REGS
))
24745 ret
= 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
24747 ret
= 4 + rs6000_register_move_cost (mode
, rclass
, GENERAL_REGS
);
24749 if (TARGET_DEBUG_COST
)
24751 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
24752 ret
, GET_MODE_NAME (mode
), reg_class_names
[rclass
], in
);
24757 /* Returns a code for a target-specific builtin that implements
24758 reciprocal of the function, or NULL_TREE if not available. */
24761 rs6000_builtin_reciprocal (unsigned int fn
, bool md_fn
,
24762 bool sqrt ATTRIBUTE_UNUSED
)
24764 if (! (TARGET_RECIP
&& TARGET_PPC_GFXOPT
&& !optimize_size
24765 && flag_finite_math_only
&& !flag_trapping_math
24766 && flag_unsafe_math_optimizations
))
24774 case BUILT_IN_SQRTF
:
24775 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRTF
];
24782 /* Newton-Raphson approximation of single-precision floating point divide n/d.
24783 Assumes no trapping math and finite arguments. */
24786 rs6000_emit_swdivsf (rtx dst
, rtx n
, rtx d
)
24788 rtx x0
, e0
, e1
, y1
, u0
, v0
, one
;
24790 x0
= gen_reg_rtx (SFmode
);
24791 e0
= gen_reg_rtx (SFmode
);
24792 e1
= gen_reg_rtx (SFmode
);
24793 y1
= gen_reg_rtx (SFmode
);
24794 u0
= gen_reg_rtx (SFmode
);
24795 v0
= gen_reg_rtx (SFmode
);
24796 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
24798 /* x0 = 1./d estimate */
24799 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
24800 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, d
),
24802 /* e0 = 1. - d * x0 */
24803 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
24804 gen_rtx_MINUS (SFmode
, one
,
24805 gen_rtx_MULT (SFmode
, d
, x0
))));
24806 /* e1 = e0 + e0 * e0 */
24807 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
24808 gen_rtx_PLUS (SFmode
,
24809 gen_rtx_MULT (SFmode
, e0
, e0
), e0
)));
24810 /* y1 = x0 + e1 * x0 */
24811 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
24812 gen_rtx_PLUS (SFmode
,
24813 gen_rtx_MULT (SFmode
, e1
, x0
), x0
)));
24815 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
24816 gen_rtx_MULT (SFmode
, n
, y1
)));
24817 /* v0 = n - d * u0 */
24818 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
24819 gen_rtx_MINUS (SFmode
, n
,
24820 gen_rtx_MULT (SFmode
, d
, u0
))));
24821 /* dst = u0 + v0 * y1 */
24822 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
24823 gen_rtx_PLUS (SFmode
,
24824 gen_rtx_MULT (SFmode
, v0
, y1
), u0
)));
24827 /* Newton-Raphson approximation of double-precision floating point divide n/d.
24828 Assumes no trapping math and finite arguments. */
24831 rs6000_emit_swdivdf (rtx dst
, rtx n
, rtx d
)
24833 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
24835 x0
= gen_reg_rtx (DFmode
);
24836 e0
= gen_reg_rtx (DFmode
);
24837 e1
= gen_reg_rtx (DFmode
);
24838 e2
= gen_reg_rtx (DFmode
);
24839 y1
= gen_reg_rtx (DFmode
);
24840 y2
= gen_reg_rtx (DFmode
);
24841 y3
= gen_reg_rtx (DFmode
);
24842 u0
= gen_reg_rtx (DFmode
);
24843 v0
= gen_reg_rtx (DFmode
);
24844 one
= force_reg (DFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, DFmode
));
24846 /* x0 = 1./d estimate */
24847 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
24848 gen_rtx_UNSPEC (DFmode
, gen_rtvec (1, d
),
24850 /* e0 = 1. - d * x0 */
24851 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
24852 gen_rtx_MINUS (DFmode
, one
,
24853 gen_rtx_MULT (SFmode
, d
, x0
))));
24854 /* y1 = x0 + e0 * x0 */
24855 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
24856 gen_rtx_PLUS (DFmode
,
24857 gen_rtx_MULT (DFmode
, e0
, x0
), x0
)));
24859 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
24860 gen_rtx_MULT (DFmode
, e0
, e0
)));
24861 /* y2 = y1 + e1 * y1 */
24862 emit_insn (gen_rtx_SET (VOIDmode
, y2
,
24863 gen_rtx_PLUS (DFmode
,
24864 gen_rtx_MULT (DFmode
, e1
, y1
), y1
)));
24866 emit_insn (gen_rtx_SET (VOIDmode
, e2
,
24867 gen_rtx_MULT (DFmode
, e1
, e1
)));
24868 /* y3 = y2 + e2 * y2 */
24869 emit_insn (gen_rtx_SET (VOIDmode
, y3
,
24870 gen_rtx_PLUS (DFmode
,
24871 gen_rtx_MULT (DFmode
, e2
, y2
), y2
)));
24873 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
24874 gen_rtx_MULT (DFmode
, n
, y3
)));
24875 /* v0 = n - d * u0 */
24876 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
24877 gen_rtx_MINUS (DFmode
, n
,
24878 gen_rtx_MULT (DFmode
, d
, u0
))));
24879 /* dst = u0 + v0 * y3 */
24880 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
24881 gen_rtx_PLUS (DFmode
,
24882 gen_rtx_MULT (DFmode
, v0
, y3
), u0
)));
24886 /* Newton-Raphson approximation of single-precision floating point rsqrt.
24887 Assumes no trapping math and finite arguments. */
24890 rs6000_emit_swrsqrtsf (rtx dst
, rtx src
)
24892 rtx x0
, x1
, x2
, y1
, u0
, u1
, u2
, v0
, v1
, v2
, t0
,
24893 half
, one
, halfthree
, c1
, cond
, label
;
24895 x0
= gen_reg_rtx (SFmode
);
24896 x1
= gen_reg_rtx (SFmode
);
24897 x2
= gen_reg_rtx (SFmode
);
24898 y1
= gen_reg_rtx (SFmode
);
24899 u0
= gen_reg_rtx (SFmode
);
24900 u1
= gen_reg_rtx (SFmode
);
24901 u2
= gen_reg_rtx (SFmode
);
24902 v0
= gen_reg_rtx (SFmode
);
24903 v1
= gen_reg_rtx (SFmode
);
24904 v2
= gen_reg_rtx (SFmode
);
24905 t0
= gen_reg_rtx (SFmode
);
24906 halfthree
= gen_reg_rtx (SFmode
);
24907 cond
= gen_rtx_REG (CCFPmode
, CR1_REGNO
);
24908 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
24910 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
24911 emit_insn (gen_rtx_SET (VOIDmode
, t0
,
24912 gen_rtx_MULT (SFmode
, src
, src
)));
24914 emit_insn (gen_rtx_SET (VOIDmode
, cond
,
24915 gen_rtx_COMPARE (CCFPmode
, t0
, src
)));
24916 c1
= gen_rtx_EQ (VOIDmode
, cond
, const0_rtx
);
24917 emit_unlikely_jump (c1
, label
);
24919 half
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf
, SFmode
));
24920 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
24922 /* halfthree = 1.5 = 1.0 + 0.5 */
24923 emit_insn (gen_rtx_SET (VOIDmode
, halfthree
,
24924 gen_rtx_PLUS (SFmode
, one
, half
)));
24926 /* x0 = rsqrt estimate */
24927 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
24928 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, src
),
24931 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
24932 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
24933 gen_rtx_MINUS (SFmode
,
24934 gen_rtx_MULT (SFmode
, src
, halfthree
),
24937 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
24938 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
24939 gen_rtx_MULT (SFmode
, x0
, x0
)));
24940 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
24941 gen_rtx_MINUS (SFmode
,
24943 gen_rtx_MULT (SFmode
, y1
, u0
))));
24944 emit_insn (gen_rtx_SET (VOIDmode
, x1
,
24945 gen_rtx_MULT (SFmode
, x0
, v0
)));
24947 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
24948 emit_insn (gen_rtx_SET (VOIDmode
, u1
,
24949 gen_rtx_MULT (SFmode
, x1
, x1
)));
24950 emit_insn (gen_rtx_SET (VOIDmode
, v1
,
24951 gen_rtx_MINUS (SFmode
,
24953 gen_rtx_MULT (SFmode
, y1
, u1
))));
24954 emit_insn (gen_rtx_SET (VOIDmode
, x2
,
24955 gen_rtx_MULT (SFmode
, x1
, v1
)));
24957 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
24958 emit_insn (gen_rtx_SET (VOIDmode
, u2
,
24959 gen_rtx_MULT (SFmode
, x2
, x2
)));
24960 emit_insn (gen_rtx_SET (VOIDmode
, v2
,
24961 gen_rtx_MINUS (SFmode
,
24963 gen_rtx_MULT (SFmode
, y1
, u2
))));
24964 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
24965 gen_rtx_MULT (SFmode
, x2
, v2
)));
24967 emit_label (XEXP (label
, 0));
24970 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
24971 (Power7) targets. DST is the target, and SRC is the argument operand. */
24974 rs6000_emit_popcount (rtx dst
, rtx src
)
24976 enum machine_mode mode
= GET_MODE (dst
);
24979 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
24980 if (TARGET_POPCNTD
)
24982 if (mode
== SImode
)
24983 emit_insn (gen_popcntwsi2 (dst
, src
));
24985 emit_insn (gen_popcntddi2 (dst
, src
));
24989 tmp1
= gen_reg_rtx (mode
);
24991 if (mode
== SImode
)
24993 emit_insn (gen_popcntbsi2 (tmp1
, src
));
24994 tmp2
= expand_mult (SImode
, tmp1
, GEN_INT (0x01010101),
24996 tmp2
= force_reg (SImode
, tmp2
);
24997 emit_insn (gen_lshrsi3 (dst
, tmp2
, GEN_INT (24)));
25001 emit_insn (gen_popcntbdi2 (tmp1
, src
));
25002 tmp2
= expand_mult (DImode
, tmp1
,
25003 GEN_INT ((HOST_WIDE_INT
)
25004 0x01010101 << 32 | 0x01010101),
25006 tmp2
= force_reg (DImode
, tmp2
);
25007 emit_insn (gen_lshrdi3 (dst
, tmp2
, GEN_INT (56)));
25012 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25013 target, and SRC is the argument operand. */
25016 rs6000_emit_parity (rtx dst
, rtx src
)
25018 enum machine_mode mode
= GET_MODE (dst
);
25021 tmp
= gen_reg_rtx (mode
);
25022 if (mode
== SImode
)
25024 /* Is mult+shift >= shift+xor+shift+xor? */
25025 if (rs6000_cost
->mulsi_const
>= COSTS_N_INSNS (3))
25027 rtx tmp1
, tmp2
, tmp3
, tmp4
;
25029 tmp1
= gen_reg_rtx (SImode
);
25030 emit_insn (gen_popcntbsi2 (tmp1
, src
));
25032 tmp2
= gen_reg_rtx (SImode
);
25033 emit_insn (gen_lshrsi3 (tmp2
, tmp1
, GEN_INT (16)));
25034 tmp3
= gen_reg_rtx (SImode
);
25035 emit_insn (gen_xorsi3 (tmp3
, tmp1
, tmp2
));
25037 tmp4
= gen_reg_rtx (SImode
);
25038 emit_insn (gen_lshrsi3 (tmp4
, tmp3
, GEN_INT (8)));
25039 emit_insn (gen_xorsi3 (tmp
, tmp3
, tmp4
));
25042 rs6000_emit_popcount (tmp
, src
);
25043 emit_insn (gen_andsi3 (dst
, tmp
, const1_rtx
));
25047 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25048 if (rs6000_cost
->muldi
>= COSTS_N_INSNS (5))
25050 rtx tmp1
, tmp2
, tmp3
, tmp4
, tmp5
, tmp6
;
25052 tmp1
= gen_reg_rtx (DImode
);
25053 emit_insn (gen_popcntbdi2 (tmp1
, src
));
25055 tmp2
= gen_reg_rtx (DImode
);
25056 emit_insn (gen_lshrdi3 (tmp2
, tmp1
, GEN_INT (32)));
25057 tmp3
= gen_reg_rtx (DImode
);
25058 emit_insn (gen_xordi3 (tmp3
, tmp1
, tmp2
));
25060 tmp4
= gen_reg_rtx (DImode
);
25061 emit_insn (gen_lshrdi3 (tmp4
, tmp3
, GEN_INT (16)));
25062 tmp5
= gen_reg_rtx (DImode
);
25063 emit_insn (gen_xordi3 (tmp5
, tmp3
, tmp4
));
25065 tmp6
= gen_reg_rtx (DImode
);
25066 emit_insn (gen_lshrdi3 (tmp6
, tmp5
, GEN_INT (8)));
25067 emit_insn (gen_xordi3 (tmp
, tmp5
, tmp6
));
25070 rs6000_emit_popcount (tmp
, src
);
25071 emit_insn (gen_anddi3 (dst
, tmp
, const1_rtx
));
25075 /* Return an RTX representing where to find the function value of a
25076 function returning MODE. */
25078 rs6000_complex_function_value (enum machine_mode mode
)
25080 unsigned int regno
;
25082 enum machine_mode inner
= GET_MODE_INNER (mode
);
25083 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
25085 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
25086 regno
= FP_ARG_RETURN
;
25089 regno
= GP_ARG_RETURN
;
25091 /* 32-bit is OK since it'll go in r3/r4. */
25092 if (TARGET_32BIT
&& inner_bytes
>= 4)
25093 return gen_rtx_REG (mode
, regno
);
25096 if (inner_bytes
>= 8)
25097 return gen_rtx_REG (mode
, regno
);
25099 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
25101 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
25102 GEN_INT (inner_bytes
));
25103 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
25106 /* Target hook for TARGET_FUNCTION_VALUE.
25108 On the SPE, both FPs and vectors are returned in r3.
25110 On RS/6000 an integer value is in r3 and a floating-point value is in
25111 fp1, unless -msoft-float. */
25114 rs6000_function_value (const_tree valtype
,
25115 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
25116 bool outgoing ATTRIBUTE_UNUSED
)
25118 enum machine_mode mode
;
25119 unsigned int regno
;
25121 /* Special handling for structs in darwin64. */
25122 if (rs6000_darwin64_abi
25123 && TYPE_MODE (valtype
) == BLKmode
25124 && TREE_CODE (valtype
) == RECORD_TYPE
25125 && int_size_in_bytes (valtype
) > 0)
25127 CUMULATIVE_ARGS valcum
;
25131 valcum
.fregno
= FP_ARG_MIN_REG
;
25132 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
25133 /* Do a trial code generation as if this were going to be passed as
25134 an argument; if any part goes in memory, we return NULL. */
25135 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, 1, true);
25138 /* Otherwise fall through to standard ABI rules. */
25141 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
25143 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25144 return gen_rtx_PARALLEL (DImode
,
25146 gen_rtx_EXPR_LIST (VOIDmode
,
25147 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
25149 gen_rtx_EXPR_LIST (VOIDmode
,
25150 gen_rtx_REG (SImode
,
25151 GP_ARG_RETURN
+ 1),
25154 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
25156 return gen_rtx_PARALLEL (DCmode
,
25158 gen_rtx_EXPR_LIST (VOIDmode
,
25159 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
25161 gen_rtx_EXPR_LIST (VOIDmode
,
25162 gen_rtx_REG (SImode
,
25163 GP_ARG_RETURN
+ 1),
25165 gen_rtx_EXPR_LIST (VOIDmode
,
25166 gen_rtx_REG (SImode
,
25167 GP_ARG_RETURN
+ 2),
25169 gen_rtx_EXPR_LIST (VOIDmode
,
25170 gen_rtx_REG (SImode
,
25171 GP_ARG_RETURN
+ 3),
25175 mode
= TYPE_MODE (valtype
);
25176 if ((INTEGRAL_TYPE_P (valtype
) && GET_MODE_BITSIZE (mode
) < BITS_PER_WORD
)
25177 || POINTER_TYPE_P (valtype
))
25178 mode
= TARGET_32BIT
? SImode
: DImode
;
25180 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
25181 /* _Decimal128 must use an even/odd register pair. */
25182 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
25183 else if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
25184 && ((TARGET_SINGLE_FLOAT
&& (mode
== SFmode
)) || TARGET_DOUBLE_FLOAT
))
25185 regno
= FP_ARG_RETURN
;
25186 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
25187 && targetm
.calls
.split_complex_arg
)
25188 return rs6000_complex_function_value (mode
);
25189 else if (TREE_CODE (valtype
) == VECTOR_TYPE
25190 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
25191 && ALTIVEC_VECTOR_MODE (mode
))
25192 regno
= ALTIVEC_ARG_RETURN
;
25193 else if (TREE_CODE (valtype
) == VECTOR_TYPE
25194 && TARGET_VSX
&& TARGET_ALTIVEC_ABI
25195 && VSX_VECTOR_MODE (mode
))
25196 regno
= ALTIVEC_ARG_RETURN
;
25197 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
25198 && (mode
== DFmode
|| mode
== DCmode
25199 || mode
== TFmode
|| mode
== TCmode
))
25200 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
25202 regno
= GP_ARG_RETURN
;
25204 return gen_rtx_REG (mode
, regno
);
25207 /* Define how to find the value returned by a library function
25208 assuming the value has mode MODE. */
25210 rs6000_libcall_value (enum machine_mode mode
)
25212 unsigned int regno
;
25214 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
25216 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25217 return gen_rtx_PARALLEL (DImode
,
25219 gen_rtx_EXPR_LIST (VOIDmode
,
25220 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
25222 gen_rtx_EXPR_LIST (VOIDmode
,
25223 gen_rtx_REG (SImode
,
25224 GP_ARG_RETURN
+ 1),
25228 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
25229 /* _Decimal128 must use an even/odd register pair. */
25230 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
25231 else if (SCALAR_FLOAT_MODE_P (mode
)
25232 && TARGET_HARD_FLOAT
&& TARGET_FPRS
25233 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
) || TARGET_DOUBLE_FLOAT
))
25234 regno
= FP_ARG_RETURN
;
25235 else if (ALTIVEC_VECTOR_MODE (mode
)
25236 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
25237 regno
= ALTIVEC_ARG_RETURN
;
25238 else if (VSX_VECTOR_MODE (mode
)
25239 && TARGET_VSX
&& TARGET_ALTIVEC_ABI
)
25240 regno
= ALTIVEC_ARG_RETURN
;
25241 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
25242 return rs6000_complex_function_value (mode
);
25243 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
25244 && (mode
== DFmode
|| mode
== DCmode
25245 || mode
== TFmode
|| mode
== TCmode
))
25246 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
25248 regno
= GP_ARG_RETURN
;
25250 return gen_rtx_REG (mode
, regno
);
25254 /* Given FROM and TO register numbers, say whether this elimination is allowed.
25255 Frame pointer elimination is automatically handled.
25257 For the RS/6000, if frame pointer elimination is being done, we would like
25258 to convert ap into fp, not sp.
25260 We need r30 if -mminimal-toc was specified, and there are constant pool
25264 rs6000_can_eliminate (const int from
, const int to
)
25266 return (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
25267 ? ! frame_pointer_needed
25268 : from
== RS6000_PIC_OFFSET_TABLE_REGNUM
25269 ? ! TARGET_MINIMAL_TOC
|| TARGET_NO_TOC
|| get_pool_size () == 0
25273 /* Define the offset between two registers, FROM to be eliminated and its
25274 replacement TO, at the start of a routine. */
25276 rs6000_initial_elimination_offset (int from
, int to
)
25278 rs6000_stack_t
*info
= rs6000_stack_info ();
25279 HOST_WIDE_INT offset
;
25281 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
25282 offset
= info
->push_p
? 0 : -info
->total_size
;
25283 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
25285 offset
= info
->push_p
? 0 : -info
->total_size
;
25286 if (FRAME_GROWS_DOWNWARD
)
25287 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
25289 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
25290 offset
= FRAME_GROWS_DOWNWARD
25291 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
25293 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
25294 offset
= info
->total_size
;
25295 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
25296 offset
= info
->push_p
? info
->total_size
: 0;
25297 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
25300 gcc_unreachable ();
25306 rs6000_dwarf_register_span (rtx reg
)
25310 unsigned regno
= REGNO (reg
);
25311 enum machine_mode mode
= GET_MODE (reg
);
25315 && (SPE_VECTOR_MODE (GET_MODE (reg
))
25316 || (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
)
25317 && mode
!= SFmode
&& mode
!= SDmode
&& mode
!= SCmode
)))
25322 regno
= REGNO (reg
);
25324 /* The duality of the SPE register size wreaks all kinds of havoc.
25325 This is a way of distinguishing r0 in 32-bits from r0 in
25327 words
= (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
25328 gcc_assert (words
<= 4);
25329 for (i
= 0; i
< words
; i
++, regno
++)
25331 if (BYTES_BIG_ENDIAN
)
25333 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
+ 1200);
25334 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
);
25338 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
);
25339 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
+ 1200);
25343 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (words
* 2, parts
));
25346 /* Fill in sizes for SPE register high parts in table used by unwinder. */
25349 rs6000_init_dwarf_reg_sizes_extra (tree address
)
25354 enum machine_mode mode
= TYPE_MODE (char_type_node
);
25355 rtx addr
= expand_expr (address
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
25356 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
25357 rtx value
= gen_int_mode (4, mode
);
25359 for (i
= 1201; i
< 1232; i
++)
25361 int column
= DWARF_REG_TO_UNWIND_COLUMN (i
);
25362 HOST_WIDE_INT offset
25363 = DWARF_FRAME_REGNUM (column
) * GET_MODE_SIZE (mode
);
25365 emit_move_insn (adjust_address (mem
, mode
, offset
), value
);
25370 /* Map internal gcc register numbers to DWARF2 register numbers. */
25373 rs6000_dbx_register_number (unsigned int regno
)
25375 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
25377 if (regno
== MQ_REGNO
)
25379 if (regno
== LR_REGNO
)
25381 if (regno
== CTR_REGNO
)
25383 if (CR_REGNO_P (regno
))
25384 return regno
- CR0_REGNO
+ 86;
25385 if (regno
== XER_REGNO
)
25387 if (ALTIVEC_REGNO_P (regno
))
25388 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
25389 if (regno
== VRSAVE_REGNO
)
25391 if (regno
== VSCR_REGNO
)
25393 if (regno
== SPE_ACC_REGNO
)
25395 if (regno
== SPEFSCR_REGNO
)
25397 /* SPE high reg number. We get these values of regno from
25398 rs6000_dwarf_register_span. */
25399 gcc_assert (regno
>= 1200 && regno
< 1232);
25403 /* target hook eh_return_filter_mode */
25404 static enum machine_mode
25405 rs6000_eh_return_filter_mode (void)
25407 return TARGET_32BIT
? SImode
: word_mode
;
25410 /* Target hook for scalar_mode_supported_p. */
25412 rs6000_scalar_mode_supported_p (enum machine_mode mode
)
25414 if (DECIMAL_FLOAT_MODE_P (mode
))
25415 return default_decimal_float_supported_p ();
25417 return default_scalar_mode_supported_p (mode
);
25420 /* Target hook for vector_mode_supported_p. */
25422 rs6000_vector_mode_supported_p (enum machine_mode mode
)
25425 if (TARGET_PAIRED_FLOAT
&& PAIRED_VECTOR_MODE (mode
))
25428 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
25431 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode
))
25438 /* Target hook for invalid_arg_for_unprototyped_fn. */
25439 static const char *
25440 invalid_arg_for_unprototyped_fn (const_tree typelist
, const_tree funcdecl
, const_tree val
)
25442 return (!rs6000_darwin64_abi
25444 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
25445 && (funcdecl
== NULL_TREE
25446 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
25447 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
25448 ? N_("AltiVec argument passed to unprototyped function")
25452 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
25453 setup by using __stack_chk_fail_local hidden function instead of
25454 calling __stack_chk_fail directly. Otherwise it is better to call
25455 __stack_chk_fail directly. */
25458 rs6000_stack_protect_fail (void)
25460 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
25461 ? default_hidden_stack_protect_fail ()
25462 : default_external_stack_protect_fail ();
25466 rs6000_final_prescan_insn (rtx insn
, rtx
*operand ATTRIBUTE_UNUSED
,
25467 int num_operands ATTRIBUTE_UNUSED
)
25469 if (rs6000_warn_cell_microcode
)
25472 int insn_code_number
= recog_memoized (insn
);
25473 location_t location
= locator_location (INSN_LOCATOR (insn
));
25475 /* Punt on insns we cannot recognize. */
25476 if (insn_code_number
< 0)
25479 temp
= get_insn_template (insn_code_number
, insn
);
25481 if (get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
)
25482 warning_at (location
, OPT_mwarn_cell_microcode
,
25483 "emitting microcode insn %s\t[%s] #%d",
25484 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
25485 else if (get_attr_cell_micro (insn
) == CELL_MICRO_CONDITIONAL
)
25486 warning_at (location
, OPT_mwarn_cell_microcode
,
25487 "emitting conditional microcode insn %s\t[%s] #%d",
25488 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
25492 #include "gt-rs6000.h"