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 to use isel instructions. */
184 /* Nonzero if floating point operations are done in the GPRs. */
185 int rs6000_float_gprs
= 0;
187 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
188 int rs6000_darwin64_abi
;
190 /* Set to nonzero once AIX common-mode calls have been defined. */
191 static GTY(()) int common_mode_defined
;
193 /* Label number of label created for -mrelocatable, to call to so we can
194 get the address of the GOT section */
195 int rs6000_pic_labelno
;
198 /* Which abi to adhere to */
199 const char *rs6000_abi_name
;
201 /* Semantics of the small data area */
202 enum rs6000_sdata_type rs6000_sdata
= SDATA_DATA
;
204 /* Which small data model to use */
205 const char *rs6000_sdata_name
= (char *)0;
207 /* Counter for labels which are to be placed in .fixup. */
208 int fixuplabelno
= 0;
211 /* Bit size of immediate TLS offsets and string from which it is decoded. */
212 int rs6000_tls_size
= 32;
213 const char *rs6000_tls_size_string
;
215 /* ABI enumeration available for subtarget to use. */
216 enum rs6000_abi rs6000_current_abi
;
218 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
222 const char *rs6000_debug_name
;
223 int rs6000_debug_stack
; /* debug stack applications */
224 int rs6000_debug_arg
; /* debug argument handling */
226 /* Value is TRUE if register/mode pair is acceptable. */
227 bool rs6000_hard_regno_mode_ok_p
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
229 /* Built in types. */
231 tree rs6000_builtin_types
[RS6000_BTI_MAX
];
232 tree rs6000_builtin_decls
[RS6000_BUILTIN_COUNT
];
234 const char *rs6000_traceback_name
;
236 traceback_default
= 0,
242 /* Flag to say the TOC is initialized */
244 char toc_label_name
[10];
246 /* Cached value of rs6000_variable_issue. This is cached in
247 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
248 static short cached_can_issue_more
;
250 static GTY(()) section
*read_only_data_section
;
251 static GTY(()) section
*private_data_section
;
252 static GTY(()) section
*read_only_private_data_section
;
253 static GTY(()) section
*sdata2_section
;
254 static GTY(()) section
*toc_section
;
256 /* Control alignment for fields within structures. */
257 /* String from -malign-XXXXX. */
258 int rs6000_alignment_flags
;
260 /* True for any options that were explicitly set. */
262 bool aix_struct_ret
; /* True if -maix-struct-ret was used. */
263 bool alignment
; /* True if -malign- was used. */
264 bool spe_abi
; /* True if -mabi=spe/no-spe was used. */
265 bool altivec_abi
; /* True if -mabi=altivec/no-altivec used. */
266 bool spe
; /* True if -mspe= was used. */
267 bool float_gprs
; /* True if -mfloat-gprs= was used. */
268 bool isel
; /* True if -misel was used. */
269 bool long_double
; /* True if -mlong-double- was used. */
270 bool ieee
; /* True if -mabi=ieee/ibmlongdouble used. */
271 bool vrsave
; /* True if -mvrsave was used. */
272 } rs6000_explicit_options
;
274 struct builtin_description
276 /* mask is not const because we're going to alter it below. This
277 nonsense will go away when we rewrite the -march infrastructure
278 to give us more target flag bits. */
280 const enum insn_code icode
;
281 const char *const name
;
282 const enum rs6000_builtins code
;
285 /* Target cpu costs. */
287 struct processor_costs
{
288 const int mulsi
; /* cost of SImode multiplication. */
289 const int mulsi_const
; /* cost of SImode multiplication by constant. */
290 const int mulsi_const9
; /* cost of SImode mult by short constant. */
291 const int muldi
; /* cost of DImode multiplication. */
292 const int divsi
; /* cost of SImode division. */
293 const int divdi
; /* cost of DImode division. */
294 const int fp
; /* cost of simple SFmode and DFmode insns. */
295 const int dmul
; /* cost of DFmode multiplication (and fmadd). */
296 const int sdiv
; /* cost of SFmode division (fdivs). */
297 const int ddiv
; /* cost of DFmode division (fdiv). */
298 const int cache_line_size
; /* cache line size in bytes. */
299 const int l1_cache_size
; /* size of l1 cache, in kilobytes. */
300 const int l2_cache_size
; /* size of l2 cache, in kilobytes. */
301 const int simultaneous_prefetches
; /* number of parallel prefetch
305 const struct processor_costs
*rs6000_cost
;
307 /* Processor costs (relative to an add) */
309 /* Instruction size costs on 32bit processors. */
311 struct processor_costs size32_cost
= {
312 COSTS_N_INSNS (1), /* mulsi */
313 COSTS_N_INSNS (1), /* mulsi_const */
314 COSTS_N_INSNS (1), /* mulsi_const9 */
315 COSTS_N_INSNS (1), /* muldi */
316 COSTS_N_INSNS (1), /* divsi */
317 COSTS_N_INSNS (1), /* divdi */
318 COSTS_N_INSNS (1), /* fp */
319 COSTS_N_INSNS (1), /* dmul */
320 COSTS_N_INSNS (1), /* sdiv */
321 COSTS_N_INSNS (1), /* ddiv */
328 /* Instruction size costs on 64bit processors. */
330 struct processor_costs size64_cost
= {
331 COSTS_N_INSNS (1), /* mulsi */
332 COSTS_N_INSNS (1), /* mulsi_const */
333 COSTS_N_INSNS (1), /* mulsi_const9 */
334 COSTS_N_INSNS (1), /* muldi */
335 COSTS_N_INSNS (1), /* divsi */
336 COSTS_N_INSNS (1), /* divdi */
337 COSTS_N_INSNS (1), /* fp */
338 COSTS_N_INSNS (1), /* dmul */
339 COSTS_N_INSNS (1), /* sdiv */
340 COSTS_N_INSNS (1), /* ddiv */
347 /* Instruction costs on RIOS1 processors. */
349 struct processor_costs rios1_cost
= {
350 COSTS_N_INSNS (5), /* mulsi */
351 COSTS_N_INSNS (4), /* mulsi_const */
352 COSTS_N_INSNS (3), /* mulsi_const9 */
353 COSTS_N_INSNS (5), /* muldi */
354 COSTS_N_INSNS (19), /* divsi */
355 COSTS_N_INSNS (19), /* divdi */
356 COSTS_N_INSNS (2), /* fp */
357 COSTS_N_INSNS (2), /* dmul */
358 COSTS_N_INSNS (19), /* sdiv */
359 COSTS_N_INSNS (19), /* ddiv */
360 128, /* cache line size */
366 /* Instruction costs on RIOS2 processors. */
368 struct processor_costs rios2_cost
= {
369 COSTS_N_INSNS (2), /* mulsi */
370 COSTS_N_INSNS (2), /* mulsi_const */
371 COSTS_N_INSNS (2), /* mulsi_const9 */
372 COSTS_N_INSNS (2), /* muldi */
373 COSTS_N_INSNS (13), /* divsi */
374 COSTS_N_INSNS (13), /* divdi */
375 COSTS_N_INSNS (2), /* fp */
376 COSTS_N_INSNS (2), /* dmul */
377 COSTS_N_INSNS (17), /* sdiv */
378 COSTS_N_INSNS (17), /* ddiv */
379 256, /* cache line size */
385 /* Instruction costs on RS64A processors. */
387 struct processor_costs rs64a_cost
= {
388 COSTS_N_INSNS (20), /* mulsi */
389 COSTS_N_INSNS (12), /* mulsi_const */
390 COSTS_N_INSNS (8), /* mulsi_const9 */
391 COSTS_N_INSNS (34), /* muldi */
392 COSTS_N_INSNS (65), /* divsi */
393 COSTS_N_INSNS (67), /* divdi */
394 COSTS_N_INSNS (4), /* fp */
395 COSTS_N_INSNS (4), /* dmul */
396 COSTS_N_INSNS (31), /* sdiv */
397 COSTS_N_INSNS (31), /* ddiv */
398 128, /* cache line size */
404 /* Instruction costs on MPCCORE processors. */
406 struct processor_costs mpccore_cost
= {
407 COSTS_N_INSNS (2), /* mulsi */
408 COSTS_N_INSNS (2), /* mulsi_const */
409 COSTS_N_INSNS (2), /* mulsi_const9 */
410 COSTS_N_INSNS (2), /* muldi */
411 COSTS_N_INSNS (6), /* divsi */
412 COSTS_N_INSNS (6), /* divdi */
413 COSTS_N_INSNS (4), /* fp */
414 COSTS_N_INSNS (5), /* dmul */
415 COSTS_N_INSNS (10), /* sdiv */
416 COSTS_N_INSNS (17), /* ddiv */
417 32, /* cache line size */
423 /* Instruction costs on PPC403 processors. */
425 struct processor_costs ppc403_cost
= {
426 COSTS_N_INSNS (4), /* mulsi */
427 COSTS_N_INSNS (4), /* mulsi_const */
428 COSTS_N_INSNS (4), /* mulsi_const9 */
429 COSTS_N_INSNS (4), /* muldi */
430 COSTS_N_INSNS (33), /* divsi */
431 COSTS_N_INSNS (33), /* divdi */
432 COSTS_N_INSNS (11), /* fp */
433 COSTS_N_INSNS (11), /* dmul */
434 COSTS_N_INSNS (11), /* sdiv */
435 COSTS_N_INSNS (11), /* ddiv */
436 32, /* cache line size */
442 /* Instruction costs on PPC405 processors. */
444 struct processor_costs ppc405_cost
= {
445 COSTS_N_INSNS (5), /* mulsi */
446 COSTS_N_INSNS (4), /* mulsi_const */
447 COSTS_N_INSNS (3), /* mulsi_const9 */
448 COSTS_N_INSNS (5), /* muldi */
449 COSTS_N_INSNS (35), /* divsi */
450 COSTS_N_INSNS (35), /* divdi */
451 COSTS_N_INSNS (11), /* fp */
452 COSTS_N_INSNS (11), /* dmul */
453 COSTS_N_INSNS (11), /* sdiv */
454 COSTS_N_INSNS (11), /* ddiv */
455 32, /* cache line size */
461 /* Instruction costs on PPC440 processors. */
463 struct processor_costs ppc440_cost
= {
464 COSTS_N_INSNS (3), /* mulsi */
465 COSTS_N_INSNS (2), /* mulsi_const */
466 COSTS_N_INSNS (2), /* mulsi_const9 */
467 COSTS_N_INSNS (3), /* muldi */
468 COSTS_N_INSNS (34), /* divsi */
469 COSTS_N_INSNS (34), /* divdi */
470 COSTS_N_INSNS (5), /* fp */
471 COSTS_N_INSNS (5), /* dmul */
472 COSTS_N_INSNS (19), /* sdiv */
473 COSTS_N_INSNS (33), /* ddiv */
474 32, /* cache line size */
480 /* Instruction costs on PPC601 processors. */
482 struct processor_costs ppc601_cost
= {
483 COSTS_N_INSNS (5), /* mulsi */
484 COSTS_N_INSNS (5), /* mulsi_const */
485 COSTS_N_INSNS (5), /* mulsi_const9 */
486 COSTS_N_INSNS (5), /* muldi */
487 COSTS_N_INSNS (36), /* divsi */
488 COSTS_N_INSNS (36), /* divdi */
489 COSTS_N_INSNS (4), /* fp */
490 COSTS_N_INSNS (5), /* dmul */
491 COSTS_N_INSNS (17), /* sdiv */
492 COSTS_N_INSNS (31), /* ddiv */
493 32, /* cache line size */
499 /* Instruction costs on PPC603 processors. */
501 struct processor_costs ppc603_cost
= {
502 COSTS_N_INSNS (5), /* mulsi */
503 COSTS_N_INSNS (3), /* mulsi_const */
504 COSTS_N_INSNS (2), /* mulsi_const9 */
505 COSTS_N_INSNS (5), /* muldi */
506 COSTS_N_INSNS (37), /* divsi */
507 COSTS_N_INSNS (37), /* divdi */
508 COSTS_N_INSNS (3), /* fp */
509 COSTS_N_INSNS (4), /* dmul */
510 COSTS_N_INSNS (18), /* sdiv */
511 COSTS_N_INSNS (33), /* ddiv */
512 32, /* cache line size */
518 /* Instruction costs on PPC604 processors. */
520 struct processor_costs ppc604_cost
= {
521 COSTS_N_INSNS (4), /* mulsi */
522 COSTS_N_INSNS (4), /* mulsi_const */
523 COSTS_N_INSNS (4), /* mulsi_const9 */
524 COSTS_N_INSNS (4), /* muldi */
525 COSTS_N_INSNS (20), /* divsi */
526 COSTS_N_INSNS (20), /* divdi */
527 COSTS_N_INSNS (3), /* fp */
528 COSTS_N_INSNS (3), /* dmul */
529 COSTS_N_INSNS (18), /* sdiv */
530 COSTS_N_INSNS (32), /* ddiv */
531 32, /* cache line size */
537 /* Instruction costs on PPC604e processors. */
539 struct processor_costs ppc604e_cost
= {
540 COSTS_N_INSNS (2), /* mulsi */
541 COSTS_N_INSNS (2), /* mulsi_const */
542 COSTS_N_INSNS (2), /* mulsi_const9 */
543 COSTS_N_INSNS (2), /* muldi */
544 COSTS_N_INSNS (20), /* divsi */
545 COSTS_N_INSNS (20), /* divdi */
546 COSTS_N_INSNS (3), /* fp */
547 COSTS_N_INSNS (3), /* dmul */
548 COSTS_N_INSNS (18), /* sdiv */
549 COSTS_N_INSNS (32), /* ddiv */
550 32, /* cache line size */
556 /* Instruction costs on PPC620 processors. */
558 struct processor_costs ppc620_cost
= {
559 COSTS_N_INSNS (5), /* mulsi */
560 COSTS_N_INSNS (4), /* mulsi_const */
561 COSTS_N_INSNS (3), /* mulsi_const9 */
562 COSTS_N_INSNS (7), /* muldi */
563 COSTS_N_INSNS (21), /* divsi */
564 COSTS_N_INSNS (37), /* divdi */
565 COSTS_N_INSNS (3), /* fp */
566 COSTS_N_INSNS (3), /* dmul */
567 COSTS_N_INSNS (18), /* sdiv */
568 COSTS_N_INSNS (32), /* ddiv */
569 128, /* cache line size */
575 /* Instruction costs on PPC630 processors. */
577 struct processor_costs ppc630_cost
= {
578 COSTS_N_INSNS (5), /* mulsi */
579 COSTS_N_INSNS (4), /* mulsi_const */
580 COSTS_N_INSNS (3), /* mulsi_const9 */
581 COSTS_N_INSNS (7), /* muldi */
582 COSTS_N_INSNS (21), /* divsi */
583 COSTS_N_INSNS (37), /* divdi */
584 COSTS_N_INSNS (3), /* fp */
585 COSTS_N_INSNS (3), /* dmul */
586 COSTS_N_INSNS (17), /* sdiv */
587 COSTS_N_INSNS (21), /* ddiv */
588 128, /* cache line size */
594 /* Instruction costs on Cell processor. */
595 /* COSTS_N_INSNS (1) ~ one add. */
597 struct processor_costs ppccell_cost
= {
598 COSTS_N_INSNS (9/2)+2, /* mulsi */
599 COSTS_N_INSNS (6/2), /* mulsi_const */
600 COSTS_N_INSNS (6/2), /* mulsi_const9 */
601 COSTS_N_INSNS (15/2)+2, /* muldi */
602 COSTS_N_INSNS (38/2), /* divsi */
603 COSTS_N_INSNS (70/2), /* divdi */
604 COSTS_N_INSNS (10/2), /* fp */
605 COSTS_N_INSNS (10/2), /* dmul */
606 COSTS_N_INSNS (74/2), /* sdiv */
607 COSTS_N_INSNS (74/2), /* ddiv */
608 128, /* cache line size */
614 /* Instruction costs on PPC750 and PPC7400 processors. */
616 struct processor_costs ppc750_cost
= {
617 COSTS_N_INSNS (5), /* mulsi */
618 COSTS_N_INSNS (3), /* mulsi_const */
619 COSTS_N_INSNS (2), /* mulsi_const9 */
620 COSTS_N_INSNS (5), /* muldi */
621 COSTS_N_INSNS (17), /* divsi */
622 COSTS_N_INSNS (17), /* divdi */
623 COSTS_N_INSNS (3), /* fp */
624 COSTS_N_INSNS (3), /* dmul */
625 COSTS_N_INSNS (17), /* sdiv */
626 COSTS_N_INSNS (31), /* ddiv */
627 32, /* cache line size */
633 /* Instruction costs on PPC7450 processors. */
635 struct processor_costs ppc7450_cost
= {
636 COSTS_N_INSNS (4), /* mulsi */
637 COSTS_N_INSNS (3), /* mulsi_const */
638 COSTS_N_INSNS (3), /* mulsi_const9 */
639 COSTS_N_INSNS (4), /* muldi */
640 COSTS_N_INSNS (23), /* divsi */
641 COSTS_N_INSNS (23), /* divdi */
642 COSTS_N_INSNS (5), /* fp */
643 COSTS_N_INSNS (5), /* dmul */
644 COSTS_N_INSNS (21), /* sdiv */
645 COSTS_N_INSNS (35), /* ddiv */
646 32, /* cache line size */
652 /* Instruction costs on PPC8540 processors. */
654 struct processor_costs ppc8540_cost
= {
655 COSTS_N_INSNS (4), /* mulsi */
656 COSTS_N_INSNS (4), /* mulsi_const */
657 COSTS_N_INSNS (4), /* mulsi_const9 */
658 COSTS_N_INSNS (4), /* muldi */
659 COSTS_N_INSNS (19), /* divsi */
660 COSTS_N_INSNS (19), /* divdi */
661 COSTS_N_INSNS (4), /* fp */
662 COSTS_N_INSNS (4), /* dmul */
663 COSTS_N_INSNS (29), /* sdiv */
664 COSTS_N_INSNS (29), /* ddiv */
665 32, /* cache line size */
668 1, /* prefetch streams /*/
671 /* Instruction costs on E300C2 and E300C3 cores. */
673 struct processor_costs ppce300c2c3_cost
= {
674 COSTS_N_INSNS (4), /* mulsi */
675 COSTS_N_INSNS (4), /* mulsi_const */
676 COSTS_N_INSNS (4), /* mulsi_const9 */
677 COSTS_N_INSNS (4), /* muldi */
678 COSTS_N_INSNS (19), /* divsi */
679 COSTS_N_INSNS (19), /* divdi */
680 COSTS_N_INSNS (3), /* fp */
681 COSTS_N_INSNS (4), /* dmul */
682 COSTS_N_INSNS (18), /* sdiv */
683 COSTS_N_INSNS (33), /* ddiv */
687 1, /* prefetch streams /*/
690 /* Instruction costs on PPCE500MC processors. */
692 struct processor_costs ppce500mc_cost
= {
693 COSTS_N_INSNS (4), /* mulsi */
694 COSTS_N_INSNS (4), /* mulsi_const */
695 COSTS_N_INSNS (4), /* mulsi_const9 */
696 COSTS_N_INSNS (4), /* muldi */
697 COSTS_N_INSNS (14), /* divsi */
698 COSTS_N_INSNS (14), /* divdi */
699 COSTS_N_INSNS (8), /* fp */
700 COSTS_N_INSNS (10), /* dmul */
701 COSTS_N_INSNS (36), /* sdiv */
702 COSTS_N_INSNS (66), /* ddiv */
703 64, /* cache line size */
706 1, /* prefetch streams /*/
709 /* Instruction costs on POWER4 and POWER5 processors. */
711 struct processor_costs power4_cost
= {
712 COSTS_N_INSNS (3), /* mulsi */
713 COSTS_N_INSNS (2), /* mulsi_const */
714 COSTS_N_INSNS (2), /* mulsi_const9 */
715 COSTS_N_INSNS (4), /* muldi */
716 COSTS_N_INSNS (18), /* divsi */
717 COSTS_N_INSNS (34), /* divdi */
718 COSTS_N_INSNS (3), /* fp */
719 COSTS_N_INSNS (3), /* dmul */
720 COSTS_N_INSNS (17), /* sdiv */
721 COSTS_N_INSNS (17), /* ddiv */
722 128, /* cache line size */
725 8, /* prefetch streams /*/
728 /* Instruction costs on POWER6 processors. */
730 struct processor_costs power6_cost
= {
731 COSTS_N_INSNS (8), /* mulsi */
732 COSTS_N_INSNS (8), /* mulsi_const */
733 COSTS_N_INSNS (8), /* mulsi_const9 */
734 COSTS_N_INSNS (8), /* muldi */
735 COSTS_N_INSNS (22), /* divsi */
736 COSTS_N_INSNS (28), /* divdi */
737 COSTS_N_INSNS (3), /* fp */
738 COSTS_N_INSNS (3), /* dmul */
739 COSTS_N_INSNS (13), /* sdiv */
740 COSTS_N_INSNS (16), /* ddiv */
741 128, /* cache line size */
744 16, /* prefetch streams */
748 static bool rs6000_function_ok_for_sibcall (tree
, tree
);
749 static const char *rs6000_invalid_within_doloop (const_rtx
);
750 static bool rs6000_legitimate_address_p (enum machine_mode
, rtx
, bool);
751 static rtx
rs6000_generate_compare (rtx
, enum machine_mode
);
752 static void rs6000_emit_stack_tie (void);
753 static void rs6000_frame_related (rtx
, rtx
, HOST_WIDE_INT
, rtx
, rtx
);
754 static bool spe_func_has_64bit_regs_p (void);
755 static void emit_frame_save (rtx
, rtx
, enum machine_mode
, unsigned int,
757 static rtx
gen_frame_mem_offset (enum machine_mode
, rtx
, int);
758 static void rs6000_emit_allocate_stack (HOST_WIDE_INT
, int, int);
759 static unsigned rs6000_hash_constant (rtx
);
760 static unsigned toc_hash_function (const void *);
761 static int toc_hash_eq (const void *, const void *);
762 static bool constant_pool_expr_p (rtx
);
763 static bool legitimate_small_data_p (enum machine_mode
, rtx
);
764 static bool legitimate_lo_sum_address_p (enum machine_mode
, rtx
, int);
765 static struct machine_function
* rs6000_init_machine_status (void);
766 static bool rs6000_assemble_integer (rtx
, unsigned int, int);
767 static bool no_global_regs_above (int, bool);
768 #ifdef HAVE_GAS_HIDDEN
769 static void rs6000_assemble_visibility (tree
, int);
771 static int rs6000_ra_ever_killed (void);
772 static tree
rs6000_handle_longcall_attribute (tree
*, tree
, tree
, int, bool *);
773 static tree
rs6000_handle_altivec_attribute (tree
*, tree
, tree
, int, bool *);
774 static bool rs6000_ms_bitfield_layout_p (const_tree
);
775 static tree
rs6000_handle_struct_attribute (tree
*, tree
, tree
, int, bool *);
776 static void rs6000_eliminate_indexed_memrefs (rtx operands
[2]);
777 static const char *rs6000_mangle_type (const_tree
);
778 static void rs6000_set_default_type_attributes (tree
);
779 static rtx
rs6000_savres_routine_sym (rs6000_stack_t
*, bool, bool, bool);
780 static rtx
rs6000_emit_stack_reset (rs6000_stack_t
*, rtx
, rtx
, int, bool);
781 static rtx
rs6000_make_savres_rtx (rs6000_stack_t
*, rtx
, int,
782 enum machine_mode
, bool, bool, bool);
783 static bool rs6000_reg_live_or_pic_offset_p (int);
784 static int rs6000_savres_strategy (rs6000_stack_t
*, bool, int, int);
785 static void rs6000_restore_saved_cr (rtx
, int);
786 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT
);
787 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT
);
788 static void rs6000_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
790 static rtx
rs6000_emit_set_long_const (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
791 static bool rs6000_return_in_memory (const_tree
, const_tree
);
792 static void rs6000_file_start (void);
794 static int rs6000_elf_reloc_rw_mask (void);
795 static void rs6000_elf_asm_out_constructor (rtx
, int);
796 static void rs6000_elf_asm_out_destructor (rtx
, int);
797 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED
;
798 static void rs6000_elf_asm_init_sections (void);
799 static section
*rs6000_elf_select_rtx_section (enum machine_mode
, rtx
,
800 unsigned HOST_WIDE_INT
);
801 static void rs6000_elf_encode_section_info (tree
, rtx
, int)
804 static bool rs6000_use_blocks_for_constant_p (enum machine_mode
, const_rtx
);
805 static void rs6000_alloc_sdmode_stack_slot (void);
806 static void rs6000_instantiate_decls (void);
808 static void rs6000_xcoff_asm_output_anchor (rtx
);
809 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
810 static void rs6000_xcoff_asm_init_sections (void);
811 static int rs6000_xcoff_reloc_rw_mask (void);
812 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree
);
813 static section
*rs6000_xcoff_select_section (tree
, int,
814 unsigned HOST_WIDE_INT
);
815 static void rs6000_xcoff_unique_section (tree
, int);
816 static section
*rs6000_xcoff_select_rtx_section
817 (enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
);
818 static const char * rs6000_xcoff_strip_name_encoding (const char *);
819 static unsigned int rs6000_xcoff_section_type_flags (tree
, const char *, int);
820 static void rs6000_xcoff_file_start (void);
821 static void rs6000_xcoff_file_end (void);
823 static int rs6000_variable_issue (FILE *, int, rtx
, int);
824 static bool rs6000_rtx_costs (rtx
, int, int, int *, bool);
825 static int rs6000_adjust_cost (rtx
, rtx
, rtx
, int);
826 static void rs6000_sched_init (FILE *, int, int);
827 static bool is_microcoded_insn (rtx
);
828 static bool is_nonpipeline_insn (rtx
);
829 static bool is_cracked_insn (rtx
);
830 static bool is_branch_slot_insn (rtx
);
831 static bool is_load_insn (rtx
);
832 static rtx
get_store_dest (rtx pat
);
833 static bool is_store_insn (rtx
);
834 static bool set_to_load_agen (rtx
,rtx
);
835 static bool adjacent_mem_locations (rtx
,rtx
);
836 static int rs6000_adjust_priority (rtx
, int);
837 static int rs6000_issue_rate (void);
838 static bool rs6000_is_costly_dependence (dep_t
, int, int);
839 static rtx
get_next_active_insn (rtx
, rtx
);
840 static bool insn_terminates_group_p (rtx
, enum group_termination
);
841 static bool insn_must_be_first_in_group (rtx
);
842 static bool insn_must_be_last_in_group (rtx
);
843 static bool is_costly_group (rtx
*, rtx
);
844 static int force_new_group (int, FILE *, rtx
*, rtx
, bool *, int, int *);
845 static int redefine_groups (FILE *, int, rtx
, rtx
);
846 static int pad_groups (FILE *, int, rtx
, rtx
);
847 static void rs6000_sched_finish (FILE *, int);
848 static int rs6000_sched_reorder (FILE *, int, rtx
*, int *, int);
849 static int rs6000_sched_reorder2 (FILE *, int, rtx
*, int *, int);
850 static int rs6000_use_sched_lookahead (void);
851 static int rs6000_use_sched_lookahead_guard (rtx
);
852 static void * rs6000_alloc_sched_context (void);
853 static void rs6000_init_sched_context (void *, bool);
854 static void rs6000_set_sched_context (void *);
855 static void rs6000_free_sched_context (void *);
856 static tree
rs6000_builtin_reciprocal (unsigned int, bool, bool);
857 static tree
rs6000_builtin_mask_for_load (void);
858 static tree
rs6000_builtin_mul_widen_even (tree
);
859 static tree
rs6000_builtin_mul_widen_odd (tree
);
860 static tree
rs6000_builtin_conversion (unsigned int, tree
);
861 static tree
rs6000_builtin_vec_perm (tree
, tree
*);
863 static void def_builtin (int, const char *, tree
, int);
864 static bool rs6000_vector_alignment_reachable (const_tree
, bool);
865 static void rs6000_init_builtins (void);
866 static rtx
rs6000_expand_unop_builtin (enum insn_code
, tree
, rtx
);
867 static rtx
rs6000_expand_binop_builtin (enum insn_code
, tree
, rtx
);
868 static rtx
rs6000_expand_ternop_builtin (enum insn_code
, tree
, rtx
);
869 static rtx
rs6000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
870 static void altivec_init_builtins (void);
871 static void rs6000_common_init_builtins (void);
872 static void rs6000_init_libfuncs (void);
874 static void paired_init_builtins (void);
875 static rtx
paired_expand_builtin (tree
, rtx
, bool *);
876 static rtx
paired_expand_lv_builtin (enum insn_code
, tree
, rtx
);
877 static rtx
paired_expand_stv_builtin (enum insn_code
, tree
);
878 static rtx
paired_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
880 static void enable_mask_for_builtins (struct builtin_description
*, int,
881 enum rs6000_builtins
,
882 enum rs6000_builtins
);
883 static void spe_init_builtins (void);
884 static rtx
spe_expand_builtin (tree
, rtx
, bool *);
885 static rtx
spe_expand_stv_builtin (enum insn_code
, tree
);
886 static rtx
spe_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
887 static rtx
spe_expand_evsel_builtin (enum insn_code
, tree
, rtx
);
888 static int rs6000_emit_int_cmove (rtx
, rtx
, rtx
, rtx
);
889 static rs6000_stack_t
*rs6000_stack_info (void);
890 static void debug_stack_info (rs6000_stack_t
*);
892 static rtx
altivec_expand_builtin (tree
, rtx
, bool *);
893 static rtx
altivec_expand_ld_builtin (tree
, rtx
, bool *);
894 static rtx
altivec_expand_st_builtin (tree
, rtx
, bool *);
895 static rtx
altivec_expand_dst_builtin (tree
, rtx
, bool *);
896 static rtx
altivec_expand_abs_builtin (enum insn_code
, tree
, rtx
);
897 static rtx
altivec_expand_predicate_builtin (enum insn_code
,
898 const char *, tree
, rtx
);
899 static rtx
altivec_expand_stv_builtin (enum insn_code
, tree
);
900 static rtx
altivec_expand_vec_init_builtin (tree
, tree
, rtx
);
901 static rtx
altivec_expand_vec_set_builtin (tree
);
902 static rtx
altivec_expand_vec_ext_builtin (tree
, rtx
);
903 static int get_element_number (tree
, tree
);
904 static bool rs6000_handle_option (size_t, const char *, int);
905 static void rs6000_parse_tls_size_option (void);
906 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
907 static int first_altivec_reg_to_save (void);
908 static unsigned int compute_vrsave_mask (void);
909 static void compute_save_world_info (rs6000_stack_t
*info_ptr
);
910 static void is_altivec_return_reg (rtx
, void *);
911 static rtx
generate_set_vrsave (rtx
, rs6000_stack_t
*, int);
912 int easy_vector_constant (rtx
, enum machine_mode
);
913 static rtx
rs6000_dwarf_register_span (rtx
);
914 static void rs6000_init_dwarf_reg_sizes_extra (tree
);
915 static rtx
rs6000_legitimize_address (rtx
, rtx
, enum machine_mode
);
916 static rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
917 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
918 static rtx
rs6000_tls_get_addr (void);
919 static rtx
rs6000_got_sym (void);
920 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
921 static const char *rs6000_get_some_local_dynamic_name (void);
922 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
923 static rtx
rs6000_complex_function_value (enum machine_mode
);
924 static rtx
rs6000_spe_function_arg (CUMULATIVE_ARGS
*,
925 enum machine_mode
, tree
);
926 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
928 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
929 tree
, HOST_WIDE_INT
);
930 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
933 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
934 const_tree
, HOST_WIDE_INT
,
936 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, const_tree
, int, bool);
937 static rtx
rs6000_mixed_function_arg (enum machine_mode
, tree
, int);
938 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
939 static void setup_incoming_varargs (CUMULATIVE_ARGS
*,
940 enum machine_mode
, tree
,
942 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
944 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
946 static const char *invalid_arg_for_unprototyped_fn (const_tree
, const_tree
, const_tree
);
948 static void macho_branch_islands (void);
949 static int no_previous_def (tree function_name
);
950 static tree
get_prev_label (tree function_name
);
951 static void rs6000_darwin_file_start (void);
954 static tree
rs6000_build_builtin_va_list (void);
955 static void rs6000_va_start (tree
, rtx
);
956 static tree
rs6000_gimplify_va_arg (tree
, tree
, gimple_seq
*, gimple_seq
*);
957 static bool rs6000_must_pass_in_stack (enum machine_mode
, const_tree
);
958 static bool rs6000_scalar_mode_supported_p (enum machine_mode
);
959 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
960 static int get_vec_cmp_insn (enum rtx_code
, enum machine_mode
,
962 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
964 static int get_vsel_insn (enum machine_mode
);
965 static void rs6000_emit_vector_select (rtx
, rtx
, rtx
, rtx
);
966 static tree
rs6000_stack_protect_fail (void);
968 const int INSN_NOT_AVAILABLE
= -1;
969 static enum machine_mode
rs6000_eh_return_filter_mode (void);
971 /* Hash table stuff for keeping track of TOC entries. */
973 struct GTY(()) toc_hash_struct
975 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
976 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
978 enum machine_mode key_mode
;
982 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
984 /* Default register names. */
985 char rs6000_reg_names
[][8] =
987 "0", "1", "2", "3", "4", "5", "6", "7",
988 "8", "9", "10", "11", "12", "13", "14", "15",
989 "16", "17", "18", "19", "20", "21", "22", "23",
990 "24", "25", "26", "27", "28", "29", "30", "31",
991 "0", "1", "2", "3", "4", "5", "6", "7",
992 "8", "9", "10", "11", "12", "13", "14", "15",
993 "16", "17", "18", "19", "20", "21", "22", "23",
994 "24", "25", "26", "27", "28", "29", "30", "31",
995 "mq", "lr", "ctr","ap",
996 "0", "1", "2", "3", "4", "5", "6", "7",
998 /* AltiVec registers. */
999 "0", "1", "2", "3", "4", "5", "6", "7",
1000 "8", "9", "10", "11", "12", "13", "14", "15",
1001 "16", "17", "18", "19", "20", "21", "22", "23",
1002 "24", "25", "26", "27", "28", "29", "30", "31",
1004 /* SPE registers. */
1005 "spe_acc", "spefscr",
1006 /* Soft frame pointer. */
1010 #ifdef TARGET_REGNAMES
1011 static const char alt_reg_names
[][8] =
1013 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1014 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1015 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1016 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1017 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1018 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1019 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1020 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1021 "mq", "lr", "ctr", "ap",
1022 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1024 /* AltiVec registers. */
1025 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1026 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1027 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1028 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1030 /* SPE registers. */
1031 "spe_acc", "spefscr",
1032 /* Soft frame pointer. */
1037 /* Table of valid machine attributes. */
1039 static const struct attribute_spec rs6000_attribute_table
[] =
1041 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1042 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
},
1043 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
1044 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
1045 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
1046 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
1047 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1048 SUBTARGET_ATTRIBUTE_TABLE
,
1050 { NULL
, 0, 0, false, false, false, NULL
}
1053 #ifndef MASK_STRICT_ALIGN
1054 #define MASK_STRICT_ALIGN 0
1056 #ifndef TARGET_PROFILE_KERNEL
1057 #define TARGET_PROFILE_KERNEL 0
1060 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1061 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1063 /* Initialize the GCC target structure. */
1064 #undef TARGET_ATTRIBUTE_TABLE
1065 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1066 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1067 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1069 #undef TARGET_ASM_ALIGNED_DI_OP
1070 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1072 /* Default unaligned ops are only provided for ELF. Find the ops needed
1073 for non-ELF systems. */
1074 #ifndef OBJECT_FORMAT_ELF
1076 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1078 #undef TARGET_ASM_UNALIGNED_HI_OP
1079 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1080 #undef TARGET_ASM_UNALIGNED_SI_OP
1081 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1082 #undef TARGET_ASM_UNALIGNED_DI_OP
1083 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1086 #undef TARGET_ASM_UNALIGNED_HI_OP
1087 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1088 #undef TARGET_ASM_UNALIGNED_SI_OP
1089 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1090 #undef TARGET_ASM_UNALIGNED_DI_OP
1091 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1092 #undef TARGET_ASM_ALIGNED_DI_OP
1093 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1097 /* This hook deals with fixups for relocatable code and DI-mode objects
1099 #undef TARGET_ASM_INTEGER
1100 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1102 #ifdef HAVE_GAS_HIDDEN
1103 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1104 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1107 #undef TARGET_HAVE_TLS
1108 #define TARGET_HAVE_TLS HAVE_AS_TLS
1110 #undef TARGET_CANNOT_FORCE_CONST_MEM
1111 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1113 #undef TARGET_ASM_FUNCTION_PROLOGUE
1114 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1115 #undef TARGET_ASM_FUNCTION_EPILOGUE
1116 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1118 #undef TARGET_LEGITIMIZE_ADDRESS
1119 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1121 #undef TARGET_SCHED_VARIABLE_ISSUE
1122 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1124 #undef TARGET_SCHED_ISSUE_RATE
1125 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1126 #undef TARGET_SCHED_ADJUST_COST
1127 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1128 #undef TARGET_SCHED_ADJUST_PRIORITY
1129 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1130 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1131 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1132 #undef TARGET_SCHED_INIT
1133 #define TARGET_SCHED_INIT rs6000_sched_init
1134 #undef TARGET_SCHED_FINISH
1135 #define TARGET_SCHED_FINISH rs6000_sched_finish
1136 #undef TARGET_SCHED_REORDER
1137 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1138 #undef TARGET_SCHED_REORDER2
1139 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1141 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1142 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1144 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1145 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1147 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1148 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1149 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1150 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1151 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1152 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1153 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1154 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1156 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1157 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1158 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1159 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1160 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1161 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1162 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1163 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1164 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1165 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1167 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1168 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1170 #undef TARGET_INIT_BUILTINS
1171 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1173 #undef TARGET_EXPAND_BUILTIN
1174 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1176 #undef TARGET_MANGLE_TYPE
1177 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1179 #undef TARGET_INIT_LIBFUNCS
1180 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1183 #undef TARGET_BINDS_LOCAL_P
1184 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1187 #undef TARGET_MS_BITFIELD_LAYOUT_P
1188 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1190 #undef TARGET_ASM_OUTPUT_MI_THUNK
1191 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1193 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1194 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1196 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1197 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1199 #undef TARGET_INVALID_WITHIN_DOLOOP
1200 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1202 #undef TARGET_RTX_COSTS
1203 #define TARGET_RTX_COSTS rs6000_rtx_costs
1204 #undef TARGET_ADDRESS_COST
1205 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1207 #undef TARGET_DWARF_REGISTER_SPAN
1208 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1210 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1211 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1213 /* On rs6000, function arguments are promoted, as are function return
1215 #undef TARGET_PROMOTE_FUNCTION_ARGS
1216 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
1217 #undef TARGET_PROMOTE_FUNCTION_RETURN
1218 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
1220 #undef TARGET_RETURN_IN_MEMORY
1221 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1223 #undef TARGET_SETUP_INCOMING_VARARGS
1224 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1226 /* Always strict argument naming on rs6000. */
1227 #undef TARGET_STRICT_ARGUMENT_NAMING
1228 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1229 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1230 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1231 #undef TARGET_SPLIT_COMPLEX_ARG
1232 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1233 #undef TARGET_MUST_PASS_IN_STACK
1234 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1235 #undef TARGET_PASS_BY_REFERENCE
1236 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1237 #undef TARGET_ARG_PARTIAL_BYTES
1238 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1240 #undef TARGET_BUILD_BUILTIN_VA_LIST
1241 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1243 #undef TARGET_EXPAND_BUILTIN_VA_START
1244 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1246 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1247 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1249 #undef TARGET_EH_RETURN_FILTER_MODE
1250 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1252 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1253 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1255 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1256 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1258 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1259 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1261 #undef TARGET_HANDLE_OPTION
1262 #define TARGET_HANDLE_OPTION rs6000_handle_option
1264 #undef TARGET_DEFAULT_TARGET_FLAGS
1265 #define TARGET_DEFAULT_TARGET_FLAGS \
1268 #undef TARGET_STACK_PROTECT_FAIL
1269 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1271 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1272 The PowerPC architecture requires only weak consistency among
1273 processors--that is, memory accesses between processors need not be
1274 sequentially consistent and memory accesses among processors can occur
1275 in any order. The ability to order memory accesses weakly provides
1276 opportunities for more efficient use of the system bus. Unless a
1277 dependency exists, the 604e allows read operations to precede store
1279 #undef TARGET_RELAXED_ORDERING
1280 #define TARGET_RELAXED_ORDERING true
1283 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1284 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1287 /* Use a 32-bit anchor range. This leads to sequences like:
1289 addis tmp,anchor,high
1292 where tmp itself acts as an anchor, and can be shared between
1293 accesses to the same 64k page. */
1294 #undef TARGET_MIN_ANCHOR_OFFSET
1295 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1296 #undef TARGET_MAX_ANCHOR_OFFSET
1297 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1298 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1299 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1301 #undef TARGET_BUILTIN_RECIPROCAL
1302 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1304 #undef TARGET_EXPAND_TO_RTL_HOOK
1305 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1307 #undef TARGET_INSTANTIATE_DECLS
1308 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1310 #undef TARGET_LEGITIMATE_ADDRESS_P
1311 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1313 struct gcc_target targetm
= TARGET_INITIALIZER
;
1316 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1319 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
1321 /* The GPRs can hold any mode, but values bigger than one register
1322 cannot go past R31. */
1323 if (INT_REGNO_P (regno
))
1324 return INT_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1);
1326 /* The float registers can only hold floating modes and DImode.
1327 This excludes the 32-bit decimal float mode for now. */
1328 if (FP_REGNO_P (regno
))
1330 ((SCALAR_FLOAT_MODE_P (mode
)
1331 && (mode
!= TDmode
|| (regno
% 2) == 0)
1332 && FP_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1))
1333 || (GET_MODE_CLASS (mode
) == MODE_INT
1334 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
)
1335 || (PAIRED_SIMD_REGNO_P (regno
) && TARGET_PAIRED_FLOAT
1336 && PAIRED_VECTOR_MODE (mode
)));
1338 /* The CR register can only hold CC modes. */
1339 if (CR_REGNO_P (regno
))
1340 return GET_MODE_CLASS (mode
) == MODE_CC
;
1342 if (XER_REGNO_P (regno
))
1343 return mode
== PSImode
;
1345 /* AltiVec only in AldyVec registers. */
1346 if (ALTIVEC_REGNO_P (regno
))
1347 return ALTIVEC_VECTOR_MODE (mode
);
1349 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1350 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1353 /* We cannot put TImode anywhere except general register and it must be
1354 able to fit within the register set. */
1356 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1359 /* Initialize rs6000_hard_regno_mode_ok_p table. */
1361 rs6000_init_hard_regno_mode_ok (void)
1365 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
1366 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1367 if (rs6000_hard_regno_mode_ok (r
, (enum machine_mode
) m
))
1368 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
1372 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
1375 darwin_rs6000_override_options (void)
1377 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
1379 rs6000_altivec_abi
= 1;
1380 TARGET_ALTIVEC_VRSAVE
= 1;
1381 if (DEFAULT_ABI
== ABI_DARWIN
)
1383 if (MACHO_DYNAMIC_NO_PIC_P
)
1386 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
1389 else if (flag_pic
== 1)
1394 if (TARGET_64BIT
&& ! TARGET_POWERPC64
)
1396 target_flags
|= MASK_POWERPC64
;
1397 warning (0, "-m64 requires PowerPC64 architecture, enabling");
1401 rs6000_default_long_calls
= 1;
1402 target_flags
|= MASK_SOFT_FLOAT
;
1405 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
1407 if (!flag_mkernel
&& !flag_apple_kext
1409 && ! (target_flags_explicit
& MASK_ALTIVEC
))
1410 target_flags
|= MASK_ALTIVEC
;
1412 /* Unless the user (not the configurer) has explicitly overridden
1413 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
1414 G4 unless targetting the kernel. */
1417 && strverscmp (darwin_macosx_version_min
, "10.5") >= 0
1418 && ! (target_flags_explicit
& MASK_ALTIVEC
)
1419 && ! rs6000_select
[1].string
)
1421 target_flags
|= MASK_ALTIVEC
;
1426 /* If not otherwise specified by a target, make 'long double' equivalent to
1429 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1430 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1433 /* Override command line options. Mostly we process the processor
1434 type and sometimes adjust other TARGET_ options. */
1437 rs6000_override_options (const char *default_cpu
)
1440 struct rs6000_cpu_select
*ptr
;
1443 /* Simplifications for entries below. */
1446 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
1447 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
1450 /* This table occasionally claims that a processor does not support
1451 a particular feature even though it does, but the feature is slower
1452 than the alternative. Thus, it shouldn't be relied on as a
1453 complete description of the processor's support.
1455 Please keep this list in order, and don't forget to update the
1456 documentation in invoke.texi when adding a new processor or
1460 const char *const name
; /* Canonical processor name. */
1461 const enum processor_type processor
; /* Processor type enum value. */
1462 const int target_enable
; /* Target flags to enable. */
1463 } const processor_target_table
[]
1464 = {{"401", PROCESSOR_PPC403
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1465 {"403", PROCESSOR_PPC403
,
1466 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_STRICT_ALIGN
},
1467 {"405", PROCESSOR_PPC405
,
1468 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1469 {"405fp", PROCESSOR_PPC405
,
1470 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1471 {"440", PROCESSOR_PPC440
,
1472 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1473 {"440fp", PROCESSOR_PPC440
,
1474 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1475 {"464", PROCESSOR_PPC440
,
1476 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1477 {"464fp", PROCESSOR_PPC440
,
1478 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1479 {"505", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
},
1480 {"601", PROCESSOR_PPC601
,
1481 MASK_POWER
| POWERPC_BASE_MASK
| MASK_MULTIPLE
| MASK_STRING
},
1482 {"602", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1483 {"603", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1484 {"603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1485 {"604", PROCESSOR_PPC604
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1486 {"604e", PROCESSOR_PPC604e
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1487 {"620", PROCESSOR_PPC620
,
1488 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1489 {"630", PROCESSOR_PPC630
,
1490 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1491 {"740", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1492 {"7400", PROCESSOR_PPC7400
, POWERPC_7400_MASK
},
1493 {"7450", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1494 {"750", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1495 {"801", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1496 {"821", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1497 {"823", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1498 {"8540", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
},
1499 /* 8548 has a dummy entry for now. */
1500 {"8548", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
},
1501 {"e300c2", PROCESSOR_PPCE300C2
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1502 {"e300c3", PROCESSOR_PPCE300C3
, POWERPC_BASE_MASK
},
1503 {"e500mc", PROCESSOR_PPCE500MC
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1504 {"860", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1505 {"970", PROCESSOR_POWER4
,
1506 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1507 {"cell", PROCESSOR_CELL
,
1508 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1509 {"common", PROCESSOR_COMMON
, MASK_NEW_MNEMONICS
},
1510 {"ec603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1511 {"G3", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1512 {"G4", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1513 {"G5", PROCESSOR_POWER4
,
1514 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1515 {"power", PROCESSOR_POWER
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1516 {"power2", PROCESSOR_POWER
,
1517 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1518 {"power3", PROCESSOR_PPC630
,
1519 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1520 {"power4", PROCESSOR_POWER4
,
1521 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1523 {"power5", PROCESSOR_POWER5
,
1524 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1525 | MASK_MFCRF
| MASK_POPCNTB
},
1526 {"power5+", PROCESSOR_POWER5
,
1527 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1528 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
},
1529 {"power6", PROCESSOR_POWER6
,
1530 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1531 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
},
1532 {"power6x", PROCESSOR_POWER6
,
1533 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1534 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
1536 {"power7", PROCESSOR_POWER5
,
1537 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_MFCRF
1538 | MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
},
1539 {"powerpc", PROCESSOR_POWERPC
, POWERPC_BASE_MASK
},
1540 {"powerpc64", PROCESSOR_POWERPC64
,
1541 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1542 {"rios", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1543 {"rios1", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1544 {"rios2", PROCESSOR_RIOS2
,
1545 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1546 {"rsc", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1547 {"rsc1", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1548 {"rs64", PROCESSOR_RS64A
,
1549 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
}
1552 const size_t ptt_size
= ARRAY_SIZE (processor_target_table
);
1554 /* Some OSs don't support saving the high part of 64-bit registers on
1555 context switch. Other OSs don't support saving Altivec registers.
1556 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1557 settings; if the user wants either, the user must explicitly specify
1558 them and we won't interfere with the user's specification. */
1561 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
1562 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
| MASK_STRICT_ALIGN
1563 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
1564 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_MULHW
1565 | MASK_DLMZB
| MASK_CMPB
| MASK_MFPGPR
| MASK_DFP
)
1568 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
1569 #ifdef OS_MISSING_POWERPC64
1570 if (OS_MISSING_POWERPC64
)
1571 set_masks
&= ~MASK_POWERPC64
;
1573 #ifdef OS_MISSING_ALTIVEC
1574 if (OS_MISSING_ALTIVEC
)
1575 set_masks
&= ~MASK_ALTIVEC
;
1578 /* Don't override by the processor default if given explicitly. */
1579 set_masks
&= ~target_flags_explicit
;
1581 /* Identify the processor type. */
1582 rs6000_select
[0].string
= default_cpu
;
1583 rs6000_cpu
= TARGET_POWERPC64
? PROCESSOR_DEFAULT64
: PROCESSOR_DEFAULT
;
1585 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
1587 ptr
= &rs6000_select
[i
];
1588 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
1590 for (j
= 0; j
< ptt_size
; j
++)
1591 if (! strcmp (ptr
->string
, processor_target_table
[j
].name
))
1593 if (ptr
->set_tune_p
)
1594 rs6000_cpu
= processor_target_table
[j
].processor
;
1596 if (ptr
->set_arch_p
)
1598 target_flags
&= ~set_masks
;
1599 target_flags
|= (processor_target_table
[j
].target_enable
1606 error ("bad value (%s) for %s switch", ptr
->string
, ptr
->name
);
1610 if ((TARGET_E500
|| rs6000_cpu
== PROCESSOR_PPCE500MC
)
1611 && !rs6000_explicit_options
.isel
)
1614 if (rs6000_cpu
== PROCESSOR_PPCE300C2
|| rs6000_cpu
== PROCESSOR_PPCE300C3
1615 || rs6000_cpu
== PROCESSOR_PPCE500MC
)
1618 error ("AltiVec not supported in this target");
1620 error ("Spe not supported in this target");
1623 /* Disable Cell microcode if we are optimizing for the Cell
1624 and not optimizing for size. */
1625 if (rs6000_gen_cell_microcode
== -1)
1626 rs6000_gen_cell_microcode
= !(rs6000_cpu
== PROCESSOR_CELL
1629 /* If we are optimizing big endian systems for space, use the load/store
1630 multiple and string instructions unless we are not generating
1632 if (BYTES_BIG_ENDIAN
&& optimize_size
&& !rs6000_gen_cell_microcode
)
1633 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
1635 /* Don't allow -mmultiple or -mstring on little endian systems
1636 unless the cpu is a 750, because the hardware doesn't support the
1637 instructions used in little endian mode, and causes an alignment
1638 trap. The 750 does not cause an alignment trap (except when the
1639 target is unaligned). */
1641 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
1643 if (TARGET_MULTIPLE
)
1645 target_flags
&= ~MASK_MULTIPLE
;
1646 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
1647 warning (0, "-mmultiple is not supported on little endian systems");
1652 target_flags
&= ~MASK_STRING
;
1653 if ((target_flags_explicit
& MASK_STRING
) != 0)
1654 warning (0, "-mstring is not supported on little endian systems");
1658 /* Set debug flags */
1659 if (rs6000_debug_name
)
1661 if (! strcmp (rs6000_debug_name
, "all"))
1662 rs6000_debug_stack
= rs6000_debug_arg
= 1;
1663 else if (! strcmp (rs6000_debug_name
, "stack"))
1664 rs6000_debug_stack
= 1;
1665 else if (! strcmp (rs6000_debug_name
, "arg"))
1666 rs6000_debug_arg
= 1;
1668 error ("unknown -mdebug-%s switch", rs6000_debug_name
);
1671 if (rs6000_traceback_name
)
1673 if (! strncmp (rs6000_traceback_name
, "full", 4))
1674 rs6000_traceback
= traceback_full
;
1675 else if (! strncmp (rs6000_traceback_name
, "part", 4))
1676 rs6000_traceback
= traceback_part
;
1677 else if (! strncmp (rs6000_traceback_name
, "no", 2))
1678 rs6000_traceback
= traceback_none
;
1680 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
1681 rs6000_traceback_name
);
1684 if (!rs6000_explicit_options
.long_double
)
1685 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1687 #ifndef POWERPC_LINUX
1688 if (!rs6000_explicit_options
.ieee
)
1689 rs6000_ieeequad
= 1;
1692 /* Enable Altivec ABI for AIX -maltivec. */
1693 if (TARGET_XCOFF
&& TARGET_ALTIVEC
)
1694 rs6000_altivec_abi
= 1;
1696 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
1697 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
1698 be explicitly overridden in either case. */
1701 if (!rs6000_explicit_options
.altivec_abi
1702 && (TARGET_64BIT
|| TARGET_ALTIVEC
))
1703 rs6000_altivec_abi
= 1;
1705 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
1706 if (!rs6000_explicit_options
.vrsave
)
1707 TARGET_ALTIVEC_VRSAVE
= rs6000_altivec_abi
;
1710 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1711 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
1713 rs6000_darwin64_abi
= 1;
1715 darwin_one_byte_bool
= 1;
1717 /* Default to natural alignment, for better performance. */
1718 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
1721 /* Place FP constants in the constant pool instead of TOC
1722 if section anchors enabled. */
1723 if (flag_section_anchors
)
1724 TARGET_NO_FP_IN_TOC
= 1;
1726 /* Handle -mtls-size option. */
1727 rs6000_parse_tls_size_option ();
1729 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1730 SUBTARGET_OVERRIDE_OPTIONS
;
1732 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1733 SUBSUBTARGET_OVERRIDE_OPTIONS
;
1735 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
1736 SUB3TARGET_OVERRIDE_OPTIONS
;
1739 if (TARGET_E500
|| rs6000_cpu
== PROCESSOR_PPCE500MC
)
1741 /* The e500 and e500mc do not have string instructions, and we set
1742 MASK_STRING above when optimizing for size. */
1743 if ((target_flags
& MASK_STRING
) != 0)
1744 target_flags
= target_flags
& ~MASK_STRING
;
1746 else if (rs6000_select
[1].string
!= NULL
)
1748 /* For the powerpc-eabispe configuration, we set all these by
1749 default, so let's unset them if we manually set another
1750 CPU that is not the E500. */
1751 if (!rs6000_explicit_options
.spe_abi
)
1753 if (!rs6000_explicit_options
.spe
)
1755 if (!rs6000_explicit_options
.float_gprs
)
1756 rs6000_float_gprs
= 0;
1757 if (!rs6000_explicit_options
.isel
)
1761 /* Detect invalid option combinations with E500. */
1764 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
1765 && rs6000_cpu
!= PROCESSOR_POWER5
1766 && rs6000_cpu
!= PROCESSOR_POWER6
1767 && rs6000_cpu
!= PROCESSOR_CELL
);
1768 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
1769 || rs6000_cpu
== PROCESSOR_POWER5
);
1770 rs6000_align_branch_targets
= (rs6000_cpu
== PROCESSOR_POWER4
1771 || rs6000_cpu
== PROCESSOR_POWER5
1772 || rs6000_cpu
== PROCESSOR_POWER6
);
1774 rs6000_sched_restricted_insns_priority
1775 = (rs6000_sched_groups
? 1 : 0);
1777 /* Handle -msched-costly-dep option. */
1778 rs6000_sched_costly_dep
1779 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
1781 if (rs6000_sched_costly_dep_str
)
1783 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
1784 rs6000_sched_costly_dep
= no_dep_costly
;
1785 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
1786 rs6000_sched_costly_dep
= all_deps_costly
;
1787 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
1788 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
1789 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
1790 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
1792 rs6000_sched_costly_dep
= ((enum rs6000_dependence_cost
)
1793 atoi (rs6000_sched_costly_dep_str
));
1796 /* Handle -minsert-sched-nops option. */
1797 rs6000_sched_insert_nops
1798 = (rs6000_sched_groups
? sched_finish_regroup_exact
: sched_finish_none
);
1800 if (rs6000_sched_insert_nops_str
)
1802 if (! strcmp (rs6000_sched_insert_nops_str
, "no"))
1803 rs6000_sched_insert_nops
= sched_finish_none
;
1804 else if (! strcmp (rs6000_sched_insert_nops_str
, "pad"))
1805 rs6000_sched_insert_nops
= sched_finish_pad_groups
;
1806 else if (! strcmp (rs6000_sched_insert_nops_str
, "regroup_exact"))
1807 rs6000_sched_insert_nops
= sched_finish_regroup_exact
;
1809 rs6000_sched_insert_nops
= ((enum rs6000_nop_insertion
)
1810 atoi (rs6000_sched_insert_nops_str
));
1813 #ifdef TARGET_REGNAMES
1814 /* If the user desires alternate register names, copy in the
1815 alternate names now. */
1816 if (TARGET_REGNAMES
)
1817 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
1820 /* Set aix_struct_return last, after the ABI is determined.
1821 If -maix-struct-return or -msvr4-struct-return was explicitly
1822 used, don't override with the ABI default. */
1823 if (!rs6000_explicit_options
.aix_struct_ret
)
1824 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
1826 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
1827 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
1830 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
1832 /* We can only guarantee the availability of DI pseudo-ops when
1833 assembling for 64-bit targets. */
1836 targetm
.asm_out
.aligned_op
.di
= NULL
;
1837 targetm
.asm_out
.unaligned_op
.di
= NULL
;
1840 /* Set branch target alignment, if not optimizing for size. */
1843 /* Cell wants to be aligned 8byte for dual issue. */
1844 if (rs6000_cpu
== PROCESSOR_CELL
)
1846 if (align_functions
<= 0)
1847 align_functions
= 8;
1848 if (align_jumps
<= 0)
1850 if (align_loops
<= 0)
1853 if (rs6000_align_branch_targets
)
1855 if (align_functions
<= 0)
1856 align_functions
= 16;
1857 if (align_jumps
<= 0)
1859 if (align_loops
<= 0)
1862 if (align_jumps_max_skip
<= 0)
1863 align_jumps_max_skip
= 15;
1864 if (align_loops_max_skip
<= 0)
1865 align_loops_max_skip
= 15;
1868 /* Arrange to save and restore machine status around nested functions. */
1869 init_machine_status
= rs6000_init_machine_status
;
1871 /* We should always be splitting complex arguments, but we can't break
1872 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1873 if (DEFAULT_ABI
!= ABI_AIX
)
1874 targetm
.calls
.split_complex_arg
= NULL
;
1876 /* Initialize rs6000_cost with the appropriate target costs. */
1878 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
1882 case PROCESSOR_RIOS1
:
1883 rs6000_cost
= &rios1_cost
;
1886 case PROCESSOR_RIOS2
:
1887 rs6000_cost
= &rios2_cost
;
1890 case PROCESSOR_RS64A
:
1891 rs6000_cost
= &rs64a_cost
;
1894 case PROCESSOR_MPCCORE
:
1895 rs6000_cost
= &mpccore_cost
;
1898 case PROCESSOR_PPC403
:
1899 rs6000_cost
= &ppc403_cost
;
1902 case PROCESSOR_PPC405
:
1903 rs6000_cost
= &ppc405_cost
;
1906 case PROCESSOR_PPC440
:
1907 rs6000_cost
= &ppc440_cost
;
1910 case PROCESSOR_PPC601
:
1911 rs6000_cost
= &ppc601_cost
;
1914 case PROCESSOR_PPC603
:
1915 rs6000_cost
= &ppc603_cost
;
1918 case PROCESSOR_PPC604
:
1919 rs6000_cost
= &ppc604_cost
;
1922 case PROCESSOR_PPC604e
:
1923 rs6000_cost
= &ppc604e_cost
;
1926 case PROCESSOR_PPC620
:
1927 rs6000_cost
= &ppc620_cost
;
1930 case PROCESSOR_PPC630
:
1931 rs6000_cost
= &ppc630_cost
;
1934 case PROCESSOR_CELL
:
1935 rs6000_cost
= &ppccell_cost
;
1938 case PROCESSOR_PPC750
:
1939 case PROCESSOR_PPC7400
:
1940 rs6000_cost
= &ppc750_cost
;
1943 case PROCESSOR_PPC7450
:
1944 rs6000_cost
= &ppc7450_cost
;
1947 case PROCESSOR_PPC8540
:
1948 rs6000_cost
= &ppc8540_cost
;
1951 case PROCESSOR_PPCE300C2
:
1952 case PROCESSOR_PPCE300C3
:
1953 rs6000_cost
= &ppce300c2c3_cost
;
1956 case PROCESSOR_PPCE500MC
:
1957 rs6000_cost
= &ppce500mc_cost
;
1960 case PROCESSOR_POWER4
:
1961 case PROCESSOR_POWER5
:
1962 rs6000_cost
= &power4_cost
;
1965 case PROCESSOR_POWER6
:
1966 rs6000_cost
= &power6_cost
;
1973 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES
))
1974 set_param_value ("simultaneous-prefetches",
1975 rs6000_cost
->simultaneous_prefetches
);
1976 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE
))
1977 set_param_value ("l1-cache-size", rs6000_cost
->l1_cache_size
);
1978 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE
))
1979 set_param_value ("l1-cache-line-size", rs6000_cost
->cache_line_size
);
1980 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE
))
1981 set_param_value ("l2-cache-size", rs6000_cost
->l2_cache_size
);
1983 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
1984 can be optimized to ap = __builtin_next_arg (0). */
1985 if (DEFAULT_ABI
!= ABI_V4
)
1986 targetm
.expand_builtin_va_start
= NULL
;
1988 /* Set up single/double float flags.
1989 If TARGET_HARD_FLOAT is set, but neither single or double is set,
1990 then set both flags. */
1991 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
1992 && rs6000_single_float
== 0 && rs6000_double_float
== 0)
1993 rs6000_single_float
= rs6000_double_float
= 1;
1995 /* Reset single and double FP flags if target is E500. */
1998 rs6000_single_float
= rs6000_double_float
= 0;
1999 if (TARGET_E500_SINGLE
)
2000 rs6000_single_float
= 1;
2001 if (TARGET_E500_DOUBLE
)
2002 rs6000_single_float
= rs6000_double_float
= 1;
2005 /* If not explicitly specified via option, decide whether to generate indexed
2006 load/store instructions. */
2007 if (TARGET_AVOID_XFORM
== -1)
2008 /* Avoid indexed addressing when targeting Power6 in order to avoid
2009 the DERAT mispredict penalty. */
2010 TARGET_AVOID_XFORM
= (rs6000_cpu
== PROCESSOR_POWER6
&& TARGET_CMPB
);
2012 rs6000_init_hard_regno_mode_ok ();
2015 /* Implement targetm.vectorize.builtin_mask_for_load. */
2017 rs6000_builtin_mask_for_load (void)
2020 return altivec_builtin_mask_for_load
;
2025 /* Implement targetm.vectorize.builtin_conversion.
2026 Returns a decl of a function that implements conversion of an integer vector
2027 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2028 side of the conversion.
2029 Return NULL_TREE if it is not available. */
2031 rs6000_builtin_conversion (unsigned int tcode
, tree type
)
2033 enum tree_code code
= (enum tree_code
) tcode
;
2035 if (!TARGET_ALTIVEC
)
2040 case FIX_TRUNC_EXPR
:
2041 switch (TYPE_MODE (type
))
2044 return TYPE_UNSIGNED (type
)
2045 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCTUXS
]
2046 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCTSXS
];
2052 switch (TYPE_MODE (type
))
2055 return TYPE_UNSIGNED (type
)
2056 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCFUX
]
2057 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCFSX
];
2067 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2069 rs6000_builtin_mul_widen_even (tree type
)
2071 if (!TARGET_ALTIVEC
)
2074 switch (TYPE_MODE (type
))
2077 return TYPE_UNSIGNED (type
)
2078 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUH
]
2079 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESH
];
2082 return TYPE_UNSIGNED (type
)
2083 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUB
]
2084 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESB
];
2090 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2092 rs6000_builtin_mul_widen_odd (tree type
)
2094 if (!TARGET_ALTIVEC
)
2097 switch (TYPE_MODE (type
))
2100 return TYPE_UNSIGNED (type
)
2101 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUH
]
2102 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSH
];
2105 return TYPE_UNSIGNED (type
)
2106 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUB
]
2107 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSB
];
2114 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2115 after applying N number of iterations. This routine does not determine
2116 how may iterations are required to reach desired alignment. */
2119 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED
, bool is_packed
)
2126 if (rs6000_alignment_flags
== MASK_ALIGN_NATURAL
)
2129 if (rs6000_alignment_flags
== MASK_ALIGN_POWER
)
2139 /* Assuming that all other types are naturally aligned. CHECKME! */
2144 /* Implement targetm.vectorize.builtin_vec_perm. */
2146 rs6000_builtin_vec_perm (tree type
, tree
*mask_element_type
)
2150 *mask_element_type
= unsigned_char_type_node
;
2152 switch (TYPE_MODE (type
))
2155 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_16QI
];
2159 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_8HI
];
2163 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SI
];
2167 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SF
];
2178 /* Handle generic options of the form -mfoo=yes/no.
2179 NAME is the option name.
2180 VALUE is the option value.
2181 FLAG is the pointer to the flag where to store a 1 or 0, depending on
2182 whether the option value is 'yes' or 'no' respectively. */
2184 rs6000_parse_yes_no_option (const char *name
, const char *value
, int *flag
)
2188 else if (!strcmp (value
, "yes"))
2190 else if (!strcmp (value
, "no"))
2193 error ("unknown -m%s= option specified: '%s'", name
, value
);
2196 /* Validate and record the size specified with the -mtls-size option. */
2199 rs6000_parse_tls_size_option (void)
2201 if (rs6000_tls_size_string
== 0)
2203 else if (strcmp (rs6000_tls_size_string
, "16") == 0)
2204 rs6000_tls_size
= 16;
2205 else if (strcmp (rs6000_tls_size_string
, "32") == 0)
2206 rs6000_tls_size
= 32;
2207 else if (strcmp (rs6000_tls_size_string
, "64") == 0)
2208 rs6000_tls_size
= 64;
2210 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string
);
2214 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
2216 if (DEFAULT_ABI
== ABI_DARWIN
)
2217 /* The Darwin libraries never set errno, so we might as well
2218 avoid calling them when that's the only reason we would. */
2219 flag_errno_math
= 0;
2221 /* Double growth factor to counter reduced min jump length. */
2222 set_param_value ("max-grow-copy-bb-insns", 16);
2224 /* Enable section anchors by default.
2225 Skip section anchors for Objective C and Objective C++
2226 until front-ends fixed. */
2227 if (!TARGET_MACHO
&& lang_hooks
.name
[4] != 'O')
2228 flag_section_anchors
= 2;
2231 static enum fpu_type_t
2232 rs6000_parse_fpu_option (const char *option
)
2234 if (!strcmp("none", option
)) return FPU_NONE
;
2235 if (!strcmp("sp_lite", option
)) return FPU_SF_LITE
;
2236 if (!strcmp("dp_lite", option
)) return FPU_DF_LITE
;
2237 if (!strcmp("sp_full", option
)) return FPU_SF_FULL
;
2238 if (!strcmp("dp_full", option
)) return FPU_DF_FULL
;
2239 error("unknown value %s for -mfpu", option
);
2243 /* Implement TARGET_HANDLE_OPTION. */
2246 rs6000_handle_option (size_t code
, const char *arg
, int value
)
2248 enum fpu_type_t fpu_type
= FPU_NONE
;
2253 target_flags
&= ~(MASK_POWER
| MASK_POWER2
2254 | MASK_MULTIPLE
| MASK_STRING
);
2255 target_flags_explicit
|= (MASK_POWER
| MASK_POWER2
2256 | MASK_MULTIPLE
| MASK_STRING
);
2258 case OPT_mno_powerpc
:
2259 target_flags
&= ~(MASK_POWERPC
| MASK_PPC_GPOPT
2260 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
2261 target_flags_explicit
|= (MASK_POWERPC
| MASK_PPC_GPOPT
2262 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
2265 target_flags
&= ~MASK_MINIMAL_TOC
;
2266 TARGET_NO_FP_IN_TOC
= 0;
2267 TARGET_NO_SUM_IN_TOC
= 0;
2268 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2269 #ifdef TARGET_USES_SYSV4_OPT
2270 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
2271 just the same as -mminimal-toc. */
2272 target_flags
|= MASK_MINIMAL_TOC
;
2273 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2277 #ifdef TARGET_USES_SYSV4_OPT
2279 /* Make -mtoc behave like -mminimal-toc. */
2280 target_flags
|= MASK_MINIMAL_TOC
;
2281 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2285 #ifdef TARGET_USES_AIX64_OPT
2290 target_flags
|= MASK_POWERPC64
| MASK_POWERPC
;
2291 target_flags
|= ~target_flags_explicit
& MASK_PPC_GFXOPT
;
2292 target_flags_explicit
|= MASK_POWERPC64
| MASK_POWERPC
;
2295 #ifdef TARGET_USES_AIX64_OPT
2300 target_flags
&= ~MASK_POWERPC64
;
2301 target_flags_explicit
|= MASK_POWERPC64
;
2304 case OPT_minsert_sched_nops_
:
2305 rs6000_sched_insert_nops_str
= arg
;
2308 case OPT_mminimal_toc
:
2311 TARGET_NO_FP_IN_TOC
= 0;
2312 TARGET_NO_SUM_IN_TOC
= 0;
2319 target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
2320 target_flags_explicit
|= (MASK_MULTIPLE
| MASK_STRING
);
2327 target_flags
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
2328 target_flags_explicit
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
2332 case OPT_mpowerpc_gpopt
:
2333 case OPT_mpowerpc_gfxopt
:
2336 target_flags
|= MASK_POWERPC
;
2337 target_flags_explicit
|= MASK_POWERPC
;
2341 case OPT_maix_struct_return
:
2342 case OPT_msvr4_struct_return
:
2343 rs6000_explicit_options
.aix_struct_ret
= true;
2347 rs6000_explicit_options
.vrsave
= true;
2348 TARGET_ALTIVEC_VRSAVE
= value
;
2352 rs6000_explicit_options
.vrsave
= true;
2353 rs6000_parse_yes_no_option ("vrsave", arg
, &(TARGET_ALTIVEC_VRSAVE
));
2357 rs6000_explicit_options
.isel
= true;
2358 rs6000_isel
= value
;
2362 rs6000_explicit_options
.isel
= true;
2363 rs6000_parse_yes_no_option ("isel", arg
, &(rs6000_isel
));
2367 rs6000_explicit_options
.spe
= true;
2372 rs6000_explicit_options
.spe
= true;
2373 rs6000_parse_yes_no_option ("spe", arg
, &(rs6000_spe
));
2377 rs6000_debug_name
= arg
;
2380 #ifdef TARGET_USES_SYSV4_OPT
2382 rs6000_abi_name
= arg
;
2386 rs6000_sdata_name
= arg
;
2389 case OPT_mtls_size_
:
2390 rs6000_tls_size_string
= arg
;
2393 case OPT_mrelocatable
:
2396 target_flags
|= MASK_MINIMAL_TOC
;
2397 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2398 TARGET_NO_FP_IN_TOC
= 1;
2402 case OPT_mrelocatable_lib
:
2405 target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
2406 target_flags_explicit
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
2407 TARGET_NO_FP_IN_TOC
= 1;
2411 target_flags
&= ~MASK_RELOCATABLE
;
2412 target_flags_explicit
|= MASK_RELOCATABLE
;
2418 if (!strcmp (arg
, "altivec"))
2420 rs6000_explicit_options
.altivec_abi
= true;
2421 rs6000_altivec_abi
= 1;
2423 /* Enabling the AltiVec ABI turns off the SPE ABI. */
2426 else if (! strcmp (arg
, "no-altivec"))
2428 rs6000_explicit_options
.altivec_abi
= true;
2429 rs6000_altivec_abi
= 0;
2431 else if (! strcmp (arg
, "spe"))
2433 rs6000_explicit_options
.spe_abi
= true;
2435 rs6000_altivec_abi
= 0;
2436 if (!TARGET_SPE_ABI
)
2437 error ("not configured for ABI: '%s'", arg
);
2439 else if (! strcmp (arg
, "no-spe"))
2441 rs6000_explicit_options
.spe_abi
= true;
2445 /* These are here for testing during development only, do not
2446 document in the manual please. */
2447 else if (! strcmp (arg
, "d64"))
2449 rs6000_darwin64_abi
= 1;
2450 warning (0, "Using darwin64 ABI");
2452 else if (! strcmp (arg
, "d32"))
2454 rs6000_darwin64_abi
= 0;
2455 warning (0, "Using old darwin ABI");
2458 else if (! strcmp (arg
, "ibmlongdouble"))
2460 rs6000_explicit_options
.ieee
= true;
2461 rs6000_ieeequad
= 0;
2462 warning (0, "Using IBM extended precision long double");
2464 else if (! strcmp (arg
, "ieeelongdouble"))
2466 rs6000_explicit_options
.ieee
= true;
2467 rs6000_ieeequad
= 1;
2468 warning (0, "Using IEEE extended precision long double");
2473 error ("unknown ABI specified: '%s'", arg
);
2479 rs6000_select
[1].string
= arg
;
2483 rs6000_select
[2].string
= arg
;
2486 case OPT_mtraceback_
:
2487 rs6000_traceback_name
= arg
;
2490 case OPT_mfloat_gprs_
:
2491 rs6000_explicit_options
.float_gprs
= true;
2492 if (! strcmp (arg
, "yes") || ! strcmp (arg
, "single"))
2493 rs6000_float_gprs
= 1;
2494 else if (! strcmp (arg
, "double"))
2495 rs6000_float_gprs
= 2;
2496 else if (! strcmp (arg
, "no"))
2497 rs6000_float_gprs
= 0;
2500 error ("invalid option for -mfloat-gprs: '%s'", arg
);
2505 case OPT_mlong_double_
:
2506 rs6000_explicit_options
.long_double
= true;
2507 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2508 if (value
!= 64 && value
!= 128)
2510 error ("Unknown switch -mlong-double-%s", arg
);
2511 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2515 rs6000_long_double_type_size
= value
;
2518 case OPT_msched_costly_dep_
:
2519 rs6000_sched_costly_dep_str
= arg
;
2523 rs6000_explicit_options
.alignment
= true;
2524 if (! strcmp (arg
, "power"))
2526 /* On 64-bit Darwin, power alignment is ABI-incompatible with
2527 some C library functions, so warn about it. The flag may be
2528 useful for performance studies from time to time though, so
2529 don't disable it entirely. */
2530 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
2531 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2532 " it is incompatible with the installed C and C++ libraries");
2533 rs6000_alignment_flags
= MASK_ALIGN_POWER
;
2535 else if (! strcmp (arg
, "natural"))
2536 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
2539 error ("unknown -malign-XXXXX option specified: '%s'", arg
);
2544 case OPT_msingle_float
:
2545 if (!TARGET_SINGLE_FPU
)
2546 warning (0, "-msingle-float option equivalent to -mhard-float");
2547 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
2548 rs6000_double_float
= 0;
2549 target_flags
&= ~MASK_SOFT_FLOAT
;
2550 target_flags_explicit
|= MASK_SOFT_FLOAT
;
2553 case OPT_mdouble_float
:
2554 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
2555 rs6000_single_float
= 1;
2556 target_flags
&= ~MASK_SOFT_FLOAT
;
2557 target_flags_explicit
|= MASK_SOFT_FLOAT
;
2560 case OPT_msimple_fpu
:
2561 if (!TARGET_SINGLE_FPU
)
2562 warning (0, "-msimple-fpu option ignored");
2565 case OPT_mhard_float
:
2566 /* -mhard_float implies -msingle-float and -mdouble-float. */
2567 rs6000_single_float
= rs6000_double_float
= 1;
2570 case OPT_msoft_float
:
2571 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
2572 rs6000_single_float
= rs6000_double_float
= 0;
2576 fpu_type
= rs6000_parse_fpu_option(arg
);
2577 if (fpu_type
!= FPU_NONE
)
2578 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
2580 target_flags
&= ~MASK_SOFT_FLOAT
;
2581 target_flags_explicit
|= MASK_SOFT_FLOAT
;
2582 rs6000_xilinx_fpu
= 1;
2583 if (fpu_type
== FPU_SF_LITE
|| fpu_type
== FPU_SF_FULL
)
2584 rs6000_single_float
= 1;
2585 if (fpu_type
== FPU_DF_LITE
|| fpu_type
== FPU_DF_FULL
)
2586 rs6000_single_float
= rs6000_double_float
= 1;
2587 if (fpu_type
== FPU_SF_LITE
|| fpu_type
== FPU_DF_LITE
)
2588 rs6000_simple_fpu
= 1;
2592 /* -mfpu=none is equivalent to -msoft-float */
2593 target_flags
|= MASK_SOFT_FLOAT
;
2594 target_flags_explicit
|= MASK_SOFT_FLOAT
;
2595 rs6000_single_float
= rs6000_double_float
= 0;
2602 /* Do anything needed at the start of the asm file. */
2605 rs6000_file_start (void)
2609 const char *start
= buffer
;
2610 struct rs6000_cpu_select
*ptr
;
2611 const char *default_cpu
= TARGET_CPU_DEFAULT
;
2612 FILE *file
= asm_out_file
;
2614 default_file_start ();
2616 #ifdef TARGET_BI_ARCH
2617 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
2621 if (flag_verbose_asm
)
2623 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
2624 rs6000_select
[0].string
= default_cpu
;
2626 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
2628 ptr
= &rs6000_select
[i
];
2629 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
2631 fprintf (file
, "%s %s%s", start
, ptr
->name
, ptr
->string
);
2636 if (PPC405_ERRATUM77
)
2638 fprintf (file
, "%s PPC405CR_ERRATUM77", start
);
2642 #ifdef USING_ELFOS_H
2643 switch (rs6000_sdata
)
2645 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
2646 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
2647 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
2648 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
2651 if (rs6000_sdata
&& g_switch_value
)
2653 fprintf (file
, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED
, start
,
2663 #ifdef HAVE_AS_GNU_ATTRIBUTE
2664 if (TARGET_32BIT
&& DEFAULT_ABI
== ABI_V4
)
2666 fprintf (file
, "\t.gnu_attribute 4, %d\n",
2667 ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
) ? 1
2668 : (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_SINGLE_FLOAT
) ? 3
2670 fprintf (file
, "\t.gnu_attribute 8, %d\n",
2671 (TARGET_ALTIVEC_ABI
? 2
2672 : TARGET_SPE_ABI
? 3
2674 fprintf (file
, "\t.gnu_attribute 12, %d\n",
2675 aix_struct_return
? 2 : 1);
2680 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
2682 switch_to_section (toc_section
);
2683 switch_to_section (text_section
);
2688 /* Return nonzero if this function is known to have a null epilogue. */
2691 direct_return (void)
2693 if (reload_completed
)
2695 rs6000_stack_t
*info
= rs6000_stack_info ();
2697 if (info
->first_gp_reg_save
== 32
2698 && info
->first_fp_reg_save
== 64
2699 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
2700 && ! info
->lr_save_p
2701 && ! info
->cr_save_p
2702 && info
->vrsave_mask
== 0
2710 /* Return the number of instructions it takes to form a constant in an
2711 integer register. */
2714 num_insns_constant_wide (HOST_WIDE_INT value
)
2716 /* signed constant loadable with {cal|addi} */
2717 if ((unsigned HOST_WIDE_INT
) (value
+ 0x8000) < 0x10000)
2720 /* constant loadable with {cau|addis} */
2721 else if ((value
& 0xffff) == 0
2722 && (value
>> 31 == -1 || value
>> 31 == 0))
2725 #if HOST_BITS_PER_WIDE_INT == 64
2726 else if (TARGET_POWERPC64
)
2728 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
2729 HOST_WIDE_INT high
= value
>> 31;
2731 if (high
== 0 || high
== -1)
2737 return num_insns_constant_wide (high
) + 1;
2739 return (num_insns_constant_wide (high
)
2740 + num_insns_constant_wide (low
) + 1);
2749 num_insns_constant (rtx op
, enum machine_mode mode
)
2751 HOST_WIDE_INT low
, high
;
2753 switch (GET_CODE (op
))
2756 #if HOST_BITS_PER_WIDE_INT == 64
2757 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
2758 && mask64_operand (op
, mode
))
2762 return num_insns_constant_wide (INTVAL (op
));
2765 if (mode
== SFmode
|| mode
== SDmode
)
2770 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2771 if (DECIMAL_FLOAT_MODE_P (mode
))
2772 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
2774 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
2775 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
2778 if (mode
== VOIDmode
|| mode
== DImode
)
2780 high
= CONST_DOUBLE_HIGH (op
);
2781 low
= CONST_DOUBLE_LOW (op
);
2788 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2789 if (DECIMAL_FLOAT_MODE_P (mode
))
2790 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, l
);
2792 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
2793 high
= l
[WORDS_BIG_ENDIAN
== 0];
2794 low
= l
[WORDS_BIG_ENDIAN
!= 0];
2798 return (num_insns_constant_wide (low
)
2799 + num_insns_constant_wide (high
));
2802 if ((high
== 0 && low
>= 0)
2803 || (high
== -1 && low
< 0))
2804 return num_insns_constant_wide (low
);
2806 else if (mask64_operand (op
, mode
))
2810 return num_insns_constant_wide (high
) + 1;
2813 return (num_insns_constant_wide (high
)
2814 + num_insns_constant_wide (low
) + 1);
2822 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
2823 If the mode of OP is MODE_VECTOR_INT, this simply returns the
2824 corresponding element of the vector, but for V4SFmode and V2SFmode,
2825 the corresponding "float" is interpreted as an SImode integer. */
2828 const_vector_elt_as_int (rtx op
, unsigned int elt
)
2830 rtx tmp
= CONST_VECTOR_ELT (op
, elt
);
2831 if (GET_MODE (op
) == V4SFmode
2832 || GET_MODE (op
) == V2SFmode
)
2833 tmp
= gen_lowpart (SImode
, tmp
);
2834 return INTVAL (tmp
);
2837 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
2838 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2839 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2840 all items are set to the same value and contain COPIES replicas of the
2841 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2842 operand and the others are set to the value of the operand's msb. */
2845 vspltis_constant (rtx op
, unsigned step
, unsigned copies
)
2847 enum machine_mode mode
= GET_MODE (op
);
2848 enum machine_mode inner
= GET_MODE_INNER (mode
);
2851 unsigned nunits
= GET_MODE_NUNITS (mode
);
2852 unsigned bitsize
= GET_MODE_BITSIZE (inner
);
2853 unsigned mask
= GET_MODE_MASK (inner
);
2855 HOST_WIDE_INT val
= const_vector_elt_as_int (op
, nunits
- 1);
2856 HOST_WIDE_INT splat_val
= val
;
2857 HOST_WIDE_INT msb_val
= val
> 0 ? 0 : -1;
2859 /* Construct the value to be splatted, if possible. If not, return 0. */
2860 for (i
= 2; i
<= copies
; i
*= 2)
2862 HOST_WIDE_INT small_val
;
2864 small_val
= splat_val
>> bitsize
;
2866 if (splat_val
!= ((small_val
<< bitsize
) | (small_val
& mask
)))
2868 splat_val
= small_val
;
2871 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2872 if (EASY_VECTOR_15 (splat_val
))
2875 /* Also check if we can splat, and then add the result to itself. Do so if
2876 the value is positive, of if the splat instruction is using OP's mode;
2877 for splat_val < 0, the splat and the add should use the same mode. */
2878 else if (EASY_VECTOR_15_ADD_SELF (splat_val
)
2879 && (splat_val
>= 0 || (step
== 1 && copies
== 1)))
2885 /* Check if VAL is present in every STEP-th element, and the
2886 other elements are filled with its most significant bit. */
2887 for (i
= 0; i
< nunits
- 1; ++i
)
2889 HOST_WIDE_INT desired_val
;
2890 if (((i
+ 1) & (step
- 1)) == 0)
2893 desired_val
= msb_val
;
2895 if (desired_val
!= const_vector_elt_as_int (op
, i
))
2903 /* Return true if OP is of the given MODE and can be synthesized
2904 with a vspltisb, vspltish or vspltisw. */
2907 easy_altivec_constant (rtx op
, enum machine_mode mode
)
2909 unsigned step
, copies
;
2911 if (mode
== VOIDmode
)
2912 mode
= GET_MODE (op
);
2913 else if (mode
!= GET_MODE (op
))
2916 /* Start with a vspltisw. */
2917 step
= GET_MODE_NUNITS (mode
) / 4;
2920 if (vspltis_constant (op
, step
, copies
))
2923 /* Then try with a vspltish. */
2929 if (vspltis_constant (op
, step
, copies
))
2932 /* And finally a vspltisb. */
2938 if (vspltis_constant (op
, step
, copies
))
2944 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2945 result is OP. Abort if it is not possible. */
2948 gen_easy_altivec_constant (rtx op
)
2950 enum machine_mode mode
= GET_MODE (op
);
2951 int nunits
= GET_MODE_NUNITS (mode
);
2952 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
2953 unsigned step
= nunits
/ 4;
2954 unsigned copies
= 1;
2956 /* Start with a vspltisw. */
2957 if (vspltis_constant (op
, step
, copies
))
2958 return gen_rtx_VEC_DUPLICATE (V4SImode
, gen_lowpart (SImode
, last
));
2960 /* Then try with a vspltish. */
2966 if (vspltis_constant (op
, step
, copies
))
2967 return gen_rtx_VEC_DUPLICATE (V8HImode
, gen_lowpart (HImode
, last
));
2969 /* And finally a vspltisb. */
2975 if (vspltis_constant (op
, step
, copies
))
2976 return gen_rtx_VEC_DUPLICATE (V16QImode
, gen_lowpart (QImode
, last
));
2982 output_vec_const_move (rtx
*operands
)
2985 enum machine_mode mode
;
2990 mode
= GET_MODE (dest
);
2995 if (zero_constant (vec
, mode
))
2996 return "vxor %0,%0,%0";
2998 splat_vec
= gen_easy_altivec_constant (vec
);
2999 gcc_assert (GET_CODE (splat_vec
) == VEC_DUPLICATE
);
3000 operands
[1] = XEXP (splat_vec
, 0);
3001 if (!EASY_VECTOR_15 (INTVAL (operands
[1])))
3004 switch (GET_MODE (splat_vec
))
3007 return "vspltisw %0,%1";
3010 return "vspltish %0,%1";
3013 return "vspltisb %0,%1";
3020 gcc_assert (TARGET_SPE
);
3022 /* Vector constant 0 is handled as a splitter of V2SI, and in the
3023 pattern of V1DI, V4HI, and V2SF.
3025 FIXME: We should probably return # and add post reload
3026 splitters for these, but this way is so easy ;-). */
3027 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
3028 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
3029 operands
[1] = CONST_VECTOR_ELT (vec
, 0);
3030 operands
[2] = CONST_VECTOR_ELT (vec
, 1);
3032 return "li %0,%1\n\tevmergelo %0,%0,%0";
3034 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
3037 /* Initialize TARGET of vector PAIRED to VALS. */
3040 paired_expand_vector_init (rtx target
, rtx vals
)
3042 enum machine_mode mode
= GET_MODE (target
);
3043 int n_elts
= GET_MODE_NUNITS (mode
);
3045 rtx x
, new_rtx
, tmp
, constant_op
, op1
, op2
;
3048 for (i
= 0; i
< n_elts
; ++i
)
3050 x
= XVECEXP (vals
, 0, i
);
3051 if (!CONSTANT_P (x
))
3056 /* Load from constant pool. */
3057 emit_move_insn (target
, gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0)));
3063 /* The vector is initialized only with non-constants. */
3064 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, XVECEXP (vals
, 0, 0),
3065 XVECEXP (vals
, 0, 1));
3067 emit_move_insn (target
, new_rtx
);
3071 /* One field is non-constant and the other one is a constant. Load the
3072 constant from the constant pool and use ps_merge instruction to
3073 construct the whole vector. */
3074 op1
= XVECEXP (vals
, 0, 0);
3075 op2
= XVECEXP (vals
, 0, 1);
3077 constant_op
= (CONSTANT_P (op1
)) ? op1
: op2
;
3079 tmp
= gen_reg_rtx (GET_MODE (constant_op
));
3080 emit_move_insn (tmp
, constant_op
);
3082 if (CONSTANT_P (op1
))
3083 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, tmp
, op2
);
3085 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, op1
, tmp
);
3087 emit_move_insn (target
, new_rtx
);
3091 paired_expand_vector_move (rtx operands
[])
3093 rtx op0
= operands
[0], op1
= operands
[1];
3095 emit_move_insn (op0
, op1
);
3098 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
3099 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
3100 operands for the relation operation COND. This is a recursive
3104 paired_emit_vector_compare (enum rtx_code rcode
,
3105 rtx dest
, rtx op0
, rtx op1
,
3106 rtx cc_op0
, rtx cc_op1
)
3108 rtx tmp
= gen_reg_rtx (V2SFmode
);
3109 rtx tmp1
, max
, min
, equal_zero
;
3111 gcc_assert (TARGET_PAIRED_FLOAT
);
3112 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
3118 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3122 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
3123 emit_insn (gen_selv2sf4 (dest
, tmp
, op0
, op1
, CONST0_RTX (SFmode
)));
3127 paired_emit_vector_compare (GE
, dest
, op0
, op1
, cc_op1
, cc_op0
);
3130 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3133 tmp1
= gen_reg_rtx (V2SFmode
);
3134 max
= gen_reg_rtx (V2SFmode
);
3135 min
= gen_reg_rtx (V2SFmode
);
3136 equal_zero
= gen_reg_rtx (V2SFmode
);
3138 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
3139 emit_insn (gen_selv2sf4
3140 (max
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
3141 emit_insn (gen_subv2sf3 (tmp
, cc_op1
, cc_op0
));
3142 emit_insn (gen_selv2sf4
3143 (min
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
3144 emit_insn (gen_subv2sf3 (tmp1
, min
, max
));
3145 emit_insn (gen_selv2sf4 (dest
, tmp1
, op0
, op1
, CONST0_RTX (SFmode
)));
3148 paired_emit_vector_compare (EQ
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3151 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3154 paired_emit_vector_compare (LT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3157 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3160 paired_emit_vector_compare (GT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3169 /* Emit vector conditional expression.
3170 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
3171 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
3174 paired_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
3175 rtx cond
, rtx cc_op0
, rtx cc_op1
)
3177 enum rtx_code rcode
= GET_CODE (cond
);
3179 if (!TARGET_PAIRED_FLOAT
)
3182 paired_emit_vector_compare (rcode
, dest
, op1
, op2
, cc_op0
, cc_op1
);
3187 /* Initialize vector TARGET to VALS. */
3190 rs6000_expand_vector_init (rtx target
, rtx vals
)
3192 enum machine_mode mode
= GET_MODE (target
);
3193 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
3194 int n_elts
= GET_MODE_NUNITS (mode
);
3195 int n_var
= 0, one_var
= -1;
3196 bool all_same
= true, all_const_zero
= true;
3200 for (i
= 0; i
< n_elts
; ++i
)
3202 x
= XVECEXP (vals
, 0, i
);
3203 if (!CONSTANT_P (x
))
3204 ++n_var
, one_var
= i
;
3205 else if (x
!= CONST0_RTX (inner_mode
))
3206 all_const_zero
= false;
3208 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
3214 rtx const_vec
= gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0));
3215 if (mode
!= V4SFmode
&& all_const_zero
)
3217 /* Zero register. */
3218 emit_insn (gen_rtx_SET (VOIDmode
, target
,
3219 gen_rtx_XOR (mode
, target
, target
)));
3222 else if (mode
!= V4SFmode
&& easy_vector_constant (const_vec
, mode
))
3224 /* Splat immediate. */
3225 emit_insn (gen_rtx_SET (VOIDmode
, target
, const_vec
));
3229 ; /* Splat vector element. */
3232 /* Load from constant pool. */
3233 emit_move_insn (target
, const_vec
);
3238 /* Store value to stack temp. Load vector element. Splat. */
3241 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
3242 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0),
3243 XVECEXP (vals
, 0, 0));
3244 x
= gen_rtx_UNSPEC (VOIDmode
,
3245 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
3246 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3248 gen_rtx_SET (VOIDmode
,
3251 x
= gen_rtx_VEC_SELECT (inner_mode
, target
,
3252 gen_rtx_PARALLEL (VOIDmode
,
3253 gen_rtvec (1, const0_rtx
)));
3254 emit_insn (gen_rtx_SET (VOIDmode
, target
,
3255 gen_rtx_VEC_DUPLICATE (mode
, x
)));
3259 /* One field is non-constant. Load constant then overwrite
3263 rtx copy
= copy_rtx (vals
);
3265 /* Load constant part of vector, substitute neighboring value for
3267 XVECEXP (copy
, 0, one_var
) = XVECEXP (vals
, 0, (one_var
+ 1) % n_elts
);
3268 rs6000_expand_vector_init (target
, copy
);
3270 /* Insert variable. */
3271 rs6000_expand_vector_set (target
, XVECEXP (vals
, 0, one_var
), one_var
);
3275 /* Construct the vector in memory one field at a time
3276 and load the whole vector. */
3277 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
3278 for (i
= 0; i
< n_elts
; i
++)
3279 emit_move_insn (adjust_address_nv (mem
, inner_mode
,
3280 i
* GET_MODE_SIZE (inner_mode
)),
3281 XVECEXP (vals
, 0, i
));
3282 emit_move_insn (target
, mem
);
3285 /* Set field ELT of TARGET to VAL. */
3288 rs6000_expand_vector_set (rtx target
, rtx val
, int elt
)
3290 enum machine_mode mode
= GET_MODE (target
);
3291 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
3292 rtx reg
= gen_reg_rtx (mode
);
3294 int width
= GET_MODE_SIZE (inner_mode
);
3297 /* Load single variable value. */
3298 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
3299 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0), val
);
3300 x
= gen_rtx_UNSPEC (VOIDmode
,
3301 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
3302 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3304 gen_rtx_SET (VOIDmode
,
3308 /* Linear sequence. */
3309 mask
= gen_rtx_PARALLEL (V16QImode
, rtvec_alloc (16));
3310 for (i
= 0; i
< 16; ++i
)
3311 XVECEXP (mask
, 0, i
) = GEN_INT (i
);
3313 /* Set permute mask to insert element into target. */
3314 for (i
= 0; i
< width
; ++i
)
3315 XVECEXP (mask
, 0, elt
*width
+ i
)
3316 = GEN_INT (i
+ 0x10);
3317 x
= gen_rtx_CONST_VECTOR (V16QImode
, XVEC (mask
, 0));
3318 x
= gen_rtx_UNSPEC (mode
,
3319 gen_rtvec (3, target
, reg
,
3320 force_reg (V16QImode
, x
)),
3322 emit_insn (gen_rtx_SET (VOIDmode
, target
, x
));
3325 /* Extract field ELT from VEC into TARGET. */
3328 rs6000_expand_vector_extract (rtx target
, rtx vec
, int elt
)
3330 enum machine_mode mode
= GET_MODE (vec
);
3331 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
3334 /* Allocate mode-sized buffer. */
3335 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
3337 /* Add offset to field within buffer matching vector element. */
3338 mem
= adjust_address_nv (mem
, mode
, elt
* GET_MODE_SIZE (inner_mode
));
3340 /* Store single field into mode-sized buffer. */
3341 x
= gen_rtx_UNSPEC (VOIDmode
,
3342 gen_rtvec (1, const0_rtx
), UNSPEC_STVE
);
3343 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3345 gen_rtx_SET (VOIDmode
,
3348 emit_move_insn (target
, adjust_address_nv (mem
, inner_mode
, 0));
3351 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
3352 implement ANDing by the mask IN. */
3354 build_mask64_2_operands (rtx in
, rtx
*out
)
3356 #if HOST_BITS_PER_WIDE_INT >= 64
3357 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
3360 gcc_assert (GET_CODE (in
) == CONST_INT
);
3365 /* Assume c initially something like 0x00fff000000fffff. The idea
3366 is to rotate the word so that the middle ^^^^^^ group of zeros
3367 is at the MS end and can be cleared with an rldicl mask. We then
3368 rotate back and clear off the MS ^^ group of zeros with a
3370 c
= ~c
; /* c == 0xff000ffffff00000 */
3371 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
3372 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
3373 c
= ~c
; /* c == 0x00fff000000fffff */
3374 c
&= -lsb
; /* c == 0x00fff00000000000 */
3375 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
3376 c
= ~c
; /* c == 0xff000fffffffffff */
3377 c
&= -lsb
; /* c == 0xff00000000000000 */
3379 while ((lsb
>>= 1) != 0)
3380 shift
++; /* shift == 44 on exit from loop */
3381 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
3382 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
3383 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
3387 /* Assume c initially something like 0xff000f0000000000. The idea
3388 is to rotate the word so that the ^^^ middle group of zeros
3389 is at the LS end and can be cleared with an rldicr mask. We then
3390 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
3392 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
3393 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
3394 c
= ~c
; /* c == 0x00fff0ffffffffff */
3395 c
&= -lsb
; /* c == 0x00fff00000000000 */
3396 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
3397 c
= ~c
; /* c == 0xff000fffffffffff */
3398 c
&= -lsb
; /* c == 0xff00000000000000 */
3400 while ((lsb
>>= 1) != 0)
3401 shift
++; /* shift == 44 on exit from loop */
3402 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
3403 m1
>>= shift
; /* m1 == 0x0000000000000fff */
3404 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
3407 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
3408 masks will be all 1's. We are guaranteed more than one transition. */
3409 out
[0] = GEN_INT (64 - shift
);
3410 out
[1] = GEN_INT (m1
);
3411 out
[2] = GEN_INT (shift
);
3412 out
[3] = GEN_INT (m2
);
3420 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
3423 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
3425 if (TARGET_E500_DOUBLE
)
3427 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
3428 subreg:TI and reg:TF. Decimal float modes are like integer
3429 modes (only low part of each register used) for this
3431 if (GET_CODE (op
) == SUBREG
3432 && (mode
== SImode
|| mode
== DImode
|| mode
== TImode
3433 || mode
== DDmode
|| mode
== TDmode
)
3434 && REG_P (SUBREG_REG (op
))
3435 && (GET_MODE (SUBREG_REG (op
)) == DFmode
3436 || GET_MODE (SUBREG_REG (op
)) == TFmode
))
3439 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
3441 if (GET_CODE (op
) == SUBREG
3442 && (mode
== DFmode
|| mode
== TFmode
)
3443 && REG_P (SUBREG_REG (op
))
3444 && (GET_MODE (SUBREG_REG (op
)) == DImode
3445 || GET_MODE (SUBREG_REG (op
)) == TImode
3446 || GET_MODE (SUBREG_REG (op
)) == DDmode
3447 || GET_MODE (SUBREG_REG (op
)) == TDmode
))
3452 && GET_CODE (op
) == SUBREG
3454 && REG_P (SUBREG_REG (op
))
3455 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op
))))
3461 /* AIX increases natural record alignment to doubleword if the first
3462 field is an FP double while the FP fields remain word aligned. */
3465 rs6000_special_round_type_align (tree type
, unsigned int computed
,
3466 unsigned int specified
)
3468 unsigned int align
= MAX (computed
, specified
);
3469 tree field
= TYPE_FIELDS (type
);
3471 /* Skip all non field decls */
3472 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
3473 field
= TREE_CHAIN (field
);
3475 if (field
!= NULL
&& field
!= type
)
3477 type
= TREE_TYPE (field
);
3478 while (TREE_CODE (type
) == ARRAY_TYPE
)
3479 type
= TREE_TYPE (type
);
3481 if (type
!= error_mark_node
&& TYPE_MODE (type
) == DFmode
)
3482 align
= MAX (align
, 64);
3488 /* Darwin increases record alignment to the natural alignment of
3492 darwin_rs6000_special_round_type_align (tree type
, unsigned int computed
,
3493 unsigned int specified
)
3495 unsigned int align
= MAX (computed
, specified
);
3497 if (TYPE_PACKED (type
))
3500 /* Find the first field, looking down into aggregates. */
3502 tree field
= TYPE_FIELDS (type
);
3503 /* Skip all non field decls */
3504 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
3505 field
= TREE_CHAIN (field
);
3508 type
= TREE_TYPE (field
);
3509 while (TREE_CODE (type
) == ARRAY_TYPE
)
3510 type
= TREE_TYPE (type
);
3511 } while (AGGREGATE_TYPE_P (type
));
3513 if (! AGGREGATE_TYPE_P (type
) && type
!= error_mark_node
)
3514 align
= MAX (align
, TYPE_ALIGN (type
));
3519 /* Return 1 for an operand in small memory on V.4/eabi. */
3522 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
3523 enum machine_mode mode ATTRIBUTE_UNUSED
)
3528 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
3531 if (DEFAULT_ABI
!= ABI_V4
)
3534 /* Vector and float memory instructions have a limited offset on the
3535 SPE, so using a vector or float variable directly as an operand is
3538 && (SPE_VECTOR_MODE (mode
) || FLOAT_MODE_P (mode
)))
3541 if (GET_CODE (op
) == SYMBOL_REF
)
3544 else if (GET_CODE (op
) != CONST
3545 || GET_CODE (XEXP (op
, 0)) != PLUS
3546 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
3547 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
3552 rtx sum
= XEXP (op
, 0);
3553 HOST_WIDE_INT summand
;
3555 /* We have to be careful here, because it is the referenced address
3556 that must be 32k from _SDA_BASE_, not just the symbol. */
3557 summand
= INTVAL (XEXP (sum
, 1));
3558 if (summand
< 0 || (unsigned HOST_WIDE_INT
) summand
> g_switch_value
)
3561 sym_ref
= XEXP (sum
, 0);
3564 return SYMBOL_REF_SMALL_P (sym_ref
);
3570 /* Return true if either operand is a general purpose register. */
3573 gpr_or_gpr_p (rtx op0
, rtx op1
)
3575 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
3576 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
3580 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
3583 constant_pool_expr_p (rtx op
)
3587 split_const (op
, &base
, &offset
);
3588 return (GET_CODE (base
) == SYMBOL_REF
3589 && CONSTANT_POOL_ADDRESS_P (base
)
3590 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base
), Pmode
));
3594 toc_relative_expr_p (rtx op
)
3598 if (GET_CODE (op
) != CONST
)
3601 split_const (op
, &base
, &offset
);
3602 return (GET_CODE (base
) == UNSPEC
3603 && XINT (base
, 1) == UNSPEC_TOCREL
);
3607 legitimate_constant_pool_address_p (rtx x
)
3610 && GET_CODE (x
) == PLUS
3611 && GET_CODE (XEXP (x
, 0)) == REG
3612 && (TARGET_MINIMAL_TOC
|| REGNO (XEXP (x
, 0)) == TOC_REGISTER
)
3613 && toc_relative_expr_p (XEXP (x
, 1)));
3617 legitimate_small_data_p (enum machine_mode mode
, rtx x
)
3619 return (DEFAULT_ABI
== ABI_V4
3620 && !flag_pic
&& !TARGET_TOC
3621 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
3622 && small_data_operand (x
, mode
));
3625 /* SPE offset addressing is limited to 5-bits worth of double words. */
3626 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
3629 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
3631 unsigned HOST_WIDE_INT offset
, extra
;
3633 if (GET_CODE (x
) != PLUS
)
3635 if (GET_CODE (XEXP (x
, 0)) != REG
)
3637 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
3639 if (legitimate_constant_pool_address_p (x
))
3641 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
3644 offset
= INTVAL (XEXP (x
, 1));
3652 /* AltiVec vector modes. Only reg+reg addressing is valid and
3653 constant offset zero should not occur due to canonicalization. */
3660 /* Paired vector modes. Only reg+reg addressing is valid and
3661 constant offset zero should not occur due to canonicalization. */
3662 if (TARGET_PAIRED_FLOAT
)
3664 /* SPE vector modes. */
3665 return SPE_CONST_OFFSET_OK (offset
);
3668 if (TARGET_E500_DOUBLE
)
3669 return SPE_CONST_OFFSET_OK (offset
);
3673 /* On e500v2, we may have:
3675 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
3677 Which gets addressed with evldd instructions. */
3678 if (TARGET_E500_DOUBLE
)
3679 return SPE_CONST_OFFSET_OK (offset
);
3681 if (mode
== DFmode
|| mode
== DDmode
|| !TARGET_POWERPC64
)
3683 else if (offset
& 3)
3688 if (TARGET_E500_DOUBLE
)
3689 return (SPE_CONST_OFFSET_OK (offset
)
3690 && SPE_CONST_OFFSET_OK (offset
+ 8));
3694 if (mode
== TFmode
|| mode
== TDmode
|| !TARGET_POWERPC64
)
3696 else if (offset
& 3)
3707 return (offset
< 0x10000) && (offset
+ extra
< 0x10000);
3711 legitimate_indexed_address_p (rtx x
, int strict
)
3715 if (GET_CODE (x
) != PLUS
)
3721 /* Recognize the rtl generated by reload which we know will later be
3722 replaced with proper base and index regs. */
3724 && reload_in_progress
3725 && (REG_P (op0
) || GET_CODE (op0
) == PLUS
)
3729 return (REG_P (op0
) && REG_P (op1
)
3730 && ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
3731 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
3732 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
3733 && INT_REG_OK_FOR_INDEX_P (op0
, strict
))));
3737 avoiding_indexed_address_p (enum machine_mode mode
)
3739 /* Avoid indexed addressing for modes that have non-indexed
3740 load/store instruction forms. */
3741 return TARGET_AVOID_XFORM
&& !ALTIVEC_VECTOR_MODE (mode
);
3745 legitimate_indirect_address_p (rtx x
, int strict
)
3747 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
3751 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
3753 if (!TARGET_MACHO
|| !flag_pic
3754 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
3758 if (GET_CODE (x
) != LO_SUM
)
3760 if (GET_CODE (XEXP (x
, 0)) != REG
)
3762 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
3766 return CONSTANT_P (x
);
3770 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
3772 if (GET_CODE (x
) != LO_SUM
)
3774 if (GET_CODE (XEXP (x
, 0)) != REG
)
3776 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
3778 /* Restrict addressing for DI because of our SUBREG hackery. */
3779 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3780 || mode
== DDmode
|| mode
== TDmode
3785 if (TARGET_ELF
|| TARGET_MACHO
)
3787 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
3791 if (GET_MODE_NUNITS (mode
) != 1)
3793 if (GET_MODE_BITSIZE (mode
) > 64
3794 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
3795 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
3796 && (mode
== DFmode
|| mode
== DDmode
))))
3799 return CONSTANT_P (x
);
3806 /* Try machine-dependent ways of modifying an illegitimate address
3807 to be legitimate. If we find one, return the new, valid address.
3808 This is used from only one place: `memory_address' in explow.c.
3810 OLDX is the address as it was before break_out_memory_refs was
3811 called. In some cases it is useful to look at this to decide what
3814 It is always safe for this function to do nothing. It exists to
3815 recognize opportunities to optimize the output.
3817 On RS/6000, first check for the sum of a register with a constant
3818 integer that is out of range. If so, generate code to add the
3819 constant with the low-order 16 bits masked to the register and force
3820 this result into another register (this can be done with `cau').
3821 Then generate an address of REG+(CONST&0xffff), allowing for the
3822 possibility of bit 16 being a one.
3824 Then check for the sum of a register and something not constant, try to
3825 load the other things into a register and return the sum. */
3828 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3829 enum machine_mode mode
)
3831 if (GET_CODE (x
) == SYMBOL_REF
)
3833 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
3835 return rs6000_legitimize_tls_address (x
, model
);
3838 if (GET_CODE (x
) == PLUS
3839 && GET_CODE (XEXP (x
, 0)) == REG
3840 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3841 && (unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000) >= 0x10000
3842 && !((TARGET_POWERPC64
3843 && (mode
== DImode
|| mode
== TImode
)
3844 && (INTVAL (XEXP (x
, 1)) & 3) != 0)
3845 || SPE_VECTOR_MODE (mode
)
3846 || ALTIVEC_VECTOR_MODE (mode
)
3847 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3848 || mode
== DImode
|| mode
== DDmode
3849 || mode
== TDmode
))))
3851 HOST_WIDE_INT high_int
, low_int
;
3853 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
3854 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
3855 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
3856 GEN_INT (high_int
)), 0);
3857 return gen_rtx_PLUS (Pmode
, sum
, GEN_INT (low_int
));
3859 else if (GET_CODE (x
) == PLUS
3860 && GET_CODE (XEXP (x
, 0)) == REG
3861 && GET_CODE (XEXP (x
, 1)) != CONST_INT
3862 && GET_MODE_NUNITS (mode
) == 1
3863 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
3865 || ((mode
!= DImode
&& mode
!= DFmode
&& mode
!= DDmode
)
3866 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
)))
3867 && (TARGET_POWERPC64
|| mode
!= DImode
)
3868 && !avoiding_indexed_address_p (mode
)
3873 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
3874 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
3876 else if (ALTIVEC_VECTOR_MODE (mode
))
3880 /* Make sure both operands are registers. */
3881 if (GET_CODE (x
) == PLUS
)
3882 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, XEXP (x
, 0)),
3883 force_reg (Pmode
, XEXP (x
, 1)));
3885 reg
= force_reg (Pmode
, x
);
3888 else if (SPE_VECTOR_MODE (mode
)
3889 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3890 || mode
== DDmode
|| mode
== TDmode
3891 || mode
== DImode
)))
3895 /* We accept [reg + reg] and [reg + OFFSET]. */
3897 if (GET_CODE (x
) == PLUS
)
3899 rtx op1
= XEXP (x
, 0);
3900 rtx op2
= XEXP (x
, 1);
3903 op1
= force_reg (Pmode
, op1
);
3905 if (GET_CODE (op2
) != REG
3906 && (GET_CODE (op2
) != CONST_INT
3907 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))
3908 || (GET_MODE_SIZE (mode
) > 8
3909 && !SPE_CONST_OFFSET_OK (INTVAL (op2
) + 8))))
3910 op2
= force_reg (Pmode
, op2
);
3912 /* We can't always do [reg + reg] for these, because [reg +
3913 reg + offset] is not a legitimate addressing mode. */
3914 y
= gen_rtx_PLUS (Pmode
, op1
, op2
);
3916 if ((GET_MODE_SIZE (mode
) > 8 || mode
== DDmode
) && REG_P (op2
))
3917 return force_reg (Pmode
, y
);
3922 return force_reg (Pmode
, x
);
3928 && GET_CODE (x
) != CONST_INT
3929 && GET_CODE (x
) != CONST_DOUBLE
3931 && GET_MODE_NUNITS (mode
) == 1
3932 && (GET_MODE_BITSIZE (mode
) <= 32
3933 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
3934 && (mode
== DFmode
|| mode
== DDmode
))))
3936 rtx reg
= gen_reg_rtx (Pmode
);
3937 emit_insn (gen_elf_high (reg
, x
));
3938 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
3940 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
3943 && ! MACHO_DYNAMIC_NO_PIC_P
3945 && GET_CODE (x
) != CONST_INT
3946 && GET_CODE (x
) != CONST_DOUBLE
3948 && GET_MODE_NUNITS (mode
) == 1
3949 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
3950 || (mode
!= DFmode
&& mode
!= DDmode
))
3954 rtx reg
= gen_reg_rtx (Pmode
);
3955 emit_insn (gen_macho_high (reg
, x
));
3956 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
3959 && GET_CODE (x
) == SYMBOL_REF
3960 && constant_pool_expr_p (x
)
3961 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
3963 return create_TOC_reference (x
);
3969 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
3970 We need to emit DTP-relative relocations. */
3973 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
3978 fputs ("\t.long\t", file
);
3981 fputs (DOUBLE_INT_ASM_OP
, file
);
3986 output_addr_const (file
, x
);
3987 fputs ("@dtprel+0x8000", file
);
3990 /* Construct the SYMBOL_REF for the tls_get_addr function. */
3992 static GTY(()) rtx rs6000_tls_symbol
;
3994 rs6000_tls_get_addr (void)
3996 if (!rs6000_tls_symbol
)
3997 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
3999 return rs6000_tls_symbol
;
4002 /* Construct the SYMBOL_REF for TLS GOT references. */
4004 static GTY(()) rtx rs6000_got_symbol
;
4006 rs6000_got_sym (void)
4008 if (!rs6000_got_symbol
)
4010 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
4011 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
4012 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
4015 return rs6000_got_symbol
;
4018 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
4019 this (thread-local) address. */
4022 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
4026 dest
= gen_reg_rtx (Pmode
);
4027 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
4033 tlsreg
= gen_rtx_REG (Pmode
, 13);
4034 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
4038 tlsreg
= gen_rtx_REG (Pmode
, 2);
4039 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
4043 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
4047 tmp
= gen_reg_rtx (Pmode
);
4050 tlsreg
= gen_rtx_REG (Pmode
, 13);
4051 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
4055 tlsreg
= gen_rtx_REG (Pmode
, 2);
4056 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
4060 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
4062 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
4067 rtx r3
, got
, tga
, tmp1
, tmp2
, eqv
;
4069 /* We currently use relocations like @got@tlsgd for tls, which
4070 means the linker will handle allocation of tls entries, placing
4071 them in the .got section. So use a pointer to the .got section,
4072 not one to secondary TOC sections used by 64-bit -mminimal-toc,
4073 or to secondary GOT sections used by 32-bit -fPIC. */
4075 got
= gen_rtx_REG (Pmode
, 2);
4079 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
4082 rtx gsym
= rs6000_got_sym ();
4083 got
= gen_reg_rtx (Pmode
);
4085 rs6000_emit_move (got
, gsym
, Pmode
);
4091 tmp1
= gen_reg_rtx (Pmode
);
4092 tmp2
= gen_reg_rtx (Pmode
);
4093 tmp3
= gen_reg_rtx (Pmode
);
4094 mem
= gen_const_mem (Pmode
, tmp1
);
4096 first
= emit_insn (gen_load_toc_v4_PIC_1b (gsym
));
4097 emit_move_insn (tmp1
,
4098 gen_rtx_REG (Pmode
, LR_REGNO
));
4099 emit_move_insn (tmp2
, mem
);
4100 emit_insn (gen_addsi3 (tmp3
, tmp1
, tmp2
));
4101 last
= emit_move_insn (got
, tmp3
);
4102 set_unique_reg_note (last
, REG_EQUAL
, gsym
);
4107 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
4109 r3
= gen_rtx_REG (Pmode
, 3);
4110 tga
= rs6000_tls_get_addr ();
4112 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
4113 insn
= gen_tls_gd_aix64 (r3
, got
, addr
, tga
, const0_rtx
);
4114 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
4115 insn
= gen_tls_gd_aix32 (r3
, got
, addr
, tga
, const0_rtx
);
4116 else if (DEFAULT_ABI
== ABI_V4
)
4117 insn
= gen_tls_gd_sysvsi (r3
, got
, addr
, tga
, const0_rtx
);
4122 insn
= emit_call_insn (insn
);
4123 RTL_CONST_CALL_P (insn
) = 1;
4124 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
4125 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
4126 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
4127 insn
= get_insns ();
4129 emit_libcall_block (insn
, dest
, r3
, addr
);
4131 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
4133 r3
= gen_rtx_REG (Pmode
, 3);
4134 tga
= rs6000_tls_get_addr ();
4136 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
4137 insn
= gen_tls_ld_aix64 (r3
, got
, tga
, const0_rtx
);
4138 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
4139 insn
= gen_tls_ld_aix32 (r3
, got
, tga
, const0_rtx
);
4140 else if (DEFAULT_ABI
== ABI_V4
)
4141 insn
= gen_tls_ld_sysvsi (r3
, got
, tga
, const0_rtx
);
4146 insn
= emit_call_insn (insn
);
4147 RTL_CONST_CALL_P (insn
) = 1;
4148 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
4149 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
4150 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
4151 insn
= get_insns ();
4153 tmp1
= gen_reg_rtx (Pmode
);
4154 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
),
4156 emit_libcall_block (insn
, tmp1
, r3
, eqv
);
4157 if (rs6000_tls_size
== 16)
4160 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
4162 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
4164 else if (rs6000_tls_size
== 32)
4166 tmp2
= gen_reg_rtx (Pmode
);
4168 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
4170 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
4173 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
4175 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
4179 tmp2
= gen_reg_rtx (Pmode
);
4181 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
4183 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
4185 insn
= gen_rtx_SET (Pmode
, dest
,
4186 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
4192 /* IE, or 64-bit offset LE. */
4193 tmp2
= gen_reg_rtx (Pmode
);
4195 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
4197 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
4200 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
4202 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
4210 /* Return 1 if X contains a thread-local symbol. */
4213 rs6000_tls_referenced_p (rtx x
)
4215 if (! TARGET_HAVE_TLS
)
4218 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
4221 /* Return 1 if *X is a thread-local symbol. This is the same as
4222 rs6000_tls_symbol_ref except for the type of the unused argument. */
4225 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
4227 return RS6000_SYMBOL_REF_TLS_P (*x
);
4230 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
4231 replace the input X, or the original X if no replacement is called for.
4232 The output parameter *WIN is 1 if the calling macro should goto WIN,
4235 For RS/6000, we wish to handle large displacements off a base
4236 register by splitting the addend across an addiu/addis and the mem insn.
4237 This cuts number of extra insns needed from 3 to 1.
4239 On Darwin, we use this to generate code for floating point constants.
4240 A movsf_low is generated so we wind up with 2 instructions rather than 3.
4241 The Darwin code is inside #if TARGET_MACHO because only then are the
4242 machopic_* functions defined. */
4244 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
4245 int opnum
, int type
,
4246 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
4248 /* We must recognize output that we have already generated ourselves. */
4249 if (GET_CODE (x
) == PLUS
4250 && GET_CODE (XEXP (x
, 0)) == PLUS
4251 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
4252 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
4253 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
4255 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4256 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
4257 opnum
, (enum reload_type
)type
);
4263 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
4264 && GET_CODE (x
) == LO_SUM
4265 && GET_CODE (XEXP (x
, 0)) == PLUS
4266 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
4267 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
4268 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
4269 && machopic_operand_p (XEXP (x
, 1)))
4271 /* Result of previous invocation of this function on Darwin
4272 floating point constant. */
4273 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4274 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
4275 opnum
, (enum reload_type
)type
);
4281 /* Force ld/std non-word aligned offset into base register by wrapping
4283 if (GET_CODE (x
) == PLUS
4284 && GET_CODE (XEXP (x
, 0)) == REG
4285 && REGNO (XEXP (x
, 0)) < 32
4286 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 1)
4287 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4288 && (INTVAL (XEXP (x
, 1)) & 3) != 0
4289 && !ALTIVEC_VECTOR_MODE (mode
)
4290 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
4291 && TARGET_POWERPC64
)
4293 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
4294 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4295 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
4296 opnum
, (enum reload_type
) type
);
4301 if (GET_CODE (x
) == PLUS
4302 && GET_CODE (XEXP (x
, 0)) == REG
4303 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
4304 && INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 1)
4305 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4306 && !SPE_VECTOR_MODE (mode
)
4307 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
4308 || mode
== DDmode
|| mode
== TDmode
4310 && !ALTIVEC_VECTOR_MODE (mode
))
4312 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
4313 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
4315 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
4317 /* Check for 32-bit overflow. */
4318 if (high
+ low
!= val
)
4324 /* Reload the high part into a base reg; leave the low part
4325 in the mem directly. */
4327 x
= gen_rtx_PLUS (GET_MODE (x
),
4328 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
4332 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4333 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
4334 opnum
, (enum reload_type
)type
);
4339 if (GET_CODE (x
) == SYMBOL_REF
4340 && !ALTIVEC_VECTOR_MODE (mode
)
4341 && !SPE_VECTOR_MODE (mode
)
4343 && DEFAULT_ABI
== ABI_DARWIN
4344 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
4346 && DEFAULT_ABI
== ABI_V4
4349 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
4350 The same goes for DImode without 64-bit gprs and DFmode and DDmode
4354 && (mode
!= DImode
|| TARGET_POWERPC64
)
4355 && ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_POWERPC64
4356 || (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)))
4361 rtx offset
= machopic_gen_offset (x
);
4362 x
= gen_rtx_LO_SUM (GET_MODE (x
),
4363 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
4364 gen_rtx_HIGH (Pmode
, offset
)), offset
);
4368 x
= gen_rtx_LO_SUM (GET_MODE (x
),
4369 gen_rtx_HIGH (Pmode
, x
), x
);
4371 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4372 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
4373 opnum
, (enum reload_type
)type
);
4378 /* Reload an offset address wrapped by an AND that represents the
4379 masking of the lower bits. Strip the outer AND and let reload
4380 convert the offset address into an indirect address. */
4382 && ALTIVEC_VECTOR_MODE (mode
)
4383 && GET_CODE (x
) == AND
4384 && GET_CODE (XEXP (x
, 0)) == PLUS
4385 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
4386 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
4387 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4388 && INTVAL (XEXP (x
, 1)) == -16)
4396 && GET_CODE (x
) == SYMBOL_REF
4397 && constant_pool_expr_p (x
)
4398 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
4400 x
= create_TOC_reference (x
);
4408 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
4409 that is a valid memory address for an instruction.
4410 The MODE argument is the machine mode for the MEM expression
4411 that wants to use this address.
4413 On the RS/6000, there are four valid address: a SYMBOL_REF that
4414 refers to a constant pool entry of an address (or the sum of it
4415 plus a constant), a short (16-bit signed) constant plus a register,
4416 the sum of two registers, or a register indirect, possibly with an
4417 auto-increment. For DFmode, DDmode and DImode with a constant plus
4418 register, we must ensure that both words are addressable or PowerPC64
4419 with offset word aligned.
4421 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
4422 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
4423 because adjacent memory cells are accessed by adding word-sized offsets
4424 during assembly output. */
4426 rs6000_legitimate_address_p (enum machine_mode mode
, rtx x
, bool reg_ok_strict
)
4428 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
4430 && ALTIVEC_VECTOR_MODE (mode
)
4431 && GET_CODE (x
) == AND
4432 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4433 && INTVAL (XEXP (x
, 1)) == -16)
4436 if (RS6000_SYMBOL_REF_TLS_P (x
))
4438 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
4440 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
4441 && !ALTIVEC_VECTOR_MODE (mode
)
4442 && !SPE_VECTOR_MODE (mode
)
4445 /* Restrict addressing for DI because of our SUBREG hackery. */
4446 && !(TARGET_E500_DOUBLE
4447 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
4449 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
4451 if (legitimate_small_data_p (mode
, x
))
4453 if (legitimate_constant_pool_address_p (x
))
4455 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
4457 && GET_CODE (x
) == PLUS
4458 && GET_CODE (XEXP (x
, 0)) == REG
4459 && (XEXP (x
, 0) == virtual_stack_vars_rtx
4460 || XEXP (x
, 0) == arg_pointer_rtx
)
4461 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
4463 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
4468 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
4470 || (mode
!= DFmode
&& mode
!= DDmode
)
4471 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
))
4472 && (TARGET_POWERPC64
|| mode
!= DImode
)
4473 && !avoiding_indexed_address_p (mode
)
4474 && legitimate_indexed_address_p (x
, reg_ok_strict
))
4476 if (GET_CODE (x
) == PRE_MODIFY
4480 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
4482 || ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_E500_DOUBLE
))
4483 && (TARGET_POWERPC64
|| mode
!= DImode
)
4484 && !ALTIVEC_VECTOR_MODE (mode
)
4485 && !SPE_VECTOR_MODE (mode
)
4486 /* Restrict addressing for DI because of our SUBREG hackery. */
4487 && !(TARGET_E500_DOUBLE
4488 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
4490 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
)
4491 && (rs6000_legitimate_offset_address_p (mode
, XEXP (x
, 1), reg_ok_strict
)
4492 || (!avoiding_indexed_address_p (mode
)
4493 && legitimate_indexed_address_p (XEXP (x
, 1), reg_ok_strict
)))
4494 && rtx_equal_p (XEXP (XEXP (x
, 1), 0), XEXP (x
, 0)))
4496 if (legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
4501 /* Go to LABEL if ADDR (a legitimate address expression)
4502 has an effect that depends on the machine mode it is used for.
4504 On the RS/6000 this is true of all integral offsets (since AltiVec
4505 modes don't allow them) or is a pre-increment or decrement.
4507 ??? Except that due to conceptual problems in offsettable_address_p
4508 we can't really report the problems of integral offsets. So leave
4509 this assuming that the adjustable offset must be valid for the
4510 sub-words of a TFmode operand, which is what we had before. */
4513 rs6000_mode_dependent_address (rtx addr
)
4515 switch (GET_CODE (addr
))
4518 if (GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
4520 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
4521 return val
+ 12 + 0x8000 >= 0x10000;
4528 /* Auto-increment cases are now treated generically in recog.c. */
4530 return TARGET_UPDATE
;
4539 /* Implement FIND_BASE_TERM. */
4542 rs6000_find_base_term (rtx op
)
4546 split_const (op
, &base
, &offset
);
4547 if (GET_CODE (base
) == UNSPEC
)
4548 switch (XINT (base
, 1))
4551 case UNSPEC_MACHOPIC_OFFSET
:
4552 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
4553 for aliasing purposes. */
4554 return XVECEXP (base
, 0, 0);
4560 /* More elaborate version of recog's offsettable_memref_p predicate
4561 that works around the ??? note of rs6000_mode_dependent_address.
4562 In particular it accepts
4564 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
4566 in 32-bit mode, that the recog predicate rejects. */
4569 rs6000_offsettable_memref_p (rtx op
)
4574 /* First mimic offsettable_memref_p. */
4575 if (offsettable_address_p (1, GET_MODE (op
), XEXP (op
, 0)))
4578 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
4579 the latter predicate knows nothing about the mode of the memory
4580 reference and, therefore, assumes that it is the largest supported
4581 mode (TFmode). As a consequence, legitimate offsettable memory
4582 references are rejected. rs6000_legitimate_offset_address_p contains
4583 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
4584 return rs6000_legitimate_offset_address_p (GET_MODE (op
), XEXP (op
, 0), 1);
4587 /* Return number of consecutive hard regs needed starting at reg REGNO
4588 to hold something of mode MODE.
4589 This is ordinarily the length in words of a value of mode MODE
4590 but can be less for certain modes in special long registers.
4592 For the SPE, GPRs are 64 bits but only 32 bits are visible in
4593 scalar instructions. The upper 32 bits are only available to the
4596 POWER and PowerPC GPRs hold 32 bits worth;
4597 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
4600 rs6000_hard_regno_nregs (int regno
, enum machine_mode mode
)
4602 if (FP_REGNO_P (regno
))
4603 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
4605 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
4606 return (GET_MODE_SIZE (mode
) + UNITS_PER_SPE_WORD
- 1) / UNITS_PER_SPE_WORD
;
4608 if (ALTIVEC_REGNO_P (regno
))
4610 (GET_MODE_SIZE (mode
) + UNITS_PER_ALTIVEC_WORD
- 1) / UNITS_PER_ALTIVEC_WORD
;
4612 /* The value returned for SCmode in the E500 double case is 2 for
4613 ABI compatibility; storing an SCmode value in a single register
4614 would require function_arg and rs6000_spe_function_arg to handle
4615 SCmode so as to pass the value correctly in a pair of
4617 if (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
) && mode
!= SCmode
4618 && !DECIMAL_FLOAT_MODE_P (mode
))
4619 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
4621 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
4624 /* Change register usage conditional on target flags. */
4626 rs6000_conditional_register_usage (void)
4630 /* Set MQ register fixed (already call_used) if not POWER
4631 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
4636 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
4638 fixed_regs
[13] = call_used_regs
[13]
4639 = call_really_used_regs
[13] = 1;
4641 /* Conditionally disable FPRs. */
4642 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
4643 for (i
= 32; i
< 64; i
++)
4644 fixed_regs
[i
] = call_used_regs
[i
]
4645 = call_really_used_regs
[i
] = 1;
4647 /* The TOC register is not killed across calls in a way that is
4648 visible to the compiler. */
4649 if (DEFAULT_ABI
== ABI_AIX
)
4650 call_really_used_regs
[2] = 0;
4652 if (DEFAULT_ABI
== ABI_V4
4653 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
4655 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4657 if (DEFAULT_ABI
== ABI_V4
4658 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
4660 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4661 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4662 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4664 if (DEFAULT_ABI
== ABI_DARWIN
4665 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
4666 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4667 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4668 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4670 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
4671 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4672 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4676 global_regs
[SPEFSCR_REGNO
] = 1;
4677 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
4678 registers in prologues and epilogues. We no longer use r14
4679 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
4680 pool for link-compatibility with older versions of GCC. Once
4681 "old" code has died out, we can return r14 to the allocation
4684 = call_used_regs
[14]
4685 = call_really_used_regs
[14] = 1;
4688 if (!TARGET_ALTIVEC
)
4690 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
4691 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4692 call_really_used_regs
[VRSAVE_REGNO
] = 1;
4696 global_regs
[VSCR_REGNO
] = 1;
4698 if (TARGET_ALTIVEC_ABI
)
4700 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
4701 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4703 /* AIX reserves VR20:31 in non-extended ABI mode. */
4705 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
< FIRST_ALTIVEC_REGNO
+ 32; ++i
)
4706 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4710 /* Try to output insns to set TARGET equal to the constant C if it can
4711 be done in less than N insns. Do all computations in MODE.
4712 Returns the place where the output has been placed if it can be
4713 done and the insns have been emitted. If it would take more than N
4714 insns, zero is returned and no insns and emitted. */
4717 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
4718 rtx source
, int n ATTRIBUTE_UNUSED
)
4720 rtx result
, insn
, set
;
4721 HOST_WIDE_INT c0
, c1
;
4728 dest
= gen_reg_rtx (mode
);
4729 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
4733 result
= !can_create_pseudo_p () ? dest
: gen_reg_rtx (SImode
);
4735 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (result
),
4736 GEN_INT (INTVAL (source
)
4737 & (~ (HOST_WIDE_INT
) 0xffff))));
4738 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
4739 gen_rtx_IOR (SImode
, copy_rtx (result
),
4740 GEN_INT (INTVAL (source
) & 0xffff))));
4745 switch (GET_CODE (source
))
4748 c0
= INTVAL (source
);
4753 #if HOST_BITS_PER_WIDE_INT >= 64
4754 c0
= CONST_DOUBLE_LOW (source
);
4757 c0
= CONST_DOUBLE_LOW (source
);
4758 c1
= CONST_DOUBLE_HIGH (source
);
4766 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
4773 insn
= get_last_insn ();
4774 set
= single_set (insn
);
4775 if (! CONSTANT_P (SET_SRC (set
)))
4776 set_unique_reg_note (insn
, REG_EQUAL
, source
);
4781 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
4782 fall back to a straight forward decomposition. We do this to avoid
4783 exponential run times encountered when looking for longer sequences
4784 with rs6000_emit_set_const. */
4786 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
4788 if (!TARGET_POWERPC64
)
4790 rtx operand1
, operand2
;
4792 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
4794 operand2
= operand_subword_force (copy_rtx (dest
), WORDS_BIG_ENDIAN
!= 0,
4796 emit_move_insn (operand1
, GEN_INT (c1
));
4797 emit_move_insn (operand2
, GEN_INT (c2
));
4801 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
4804 ud2
= (c1
& 0xffff0000) >> 16;
4805 #if HOST_BITS_PER_WIDE_INT >= 64
4809 ud4
= (c2
& 0xffff0000) >> 16;
4811 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
4812 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
4815 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
4817 emit_move_insn (dest
, GEN_INT (ud1
));
4820 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
4821 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
4824 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
4827 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
4829 emit_move_insn (copy_rtx (dest
),
4830 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4833 else if ((ud4
== 0xffff && (ud3
& 0x8000))
4834 || (ud4
== 0 && ! (ud3
& 0x8000)))
4837 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
4840 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
4843 emit_move_insn (copy_rtx (dest
),
4844 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4846 emit_move_insn (copy_rtx (dest
),
4847 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
4850 emit_move_insn (copy_rtx (dest
),
4851 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4857 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
4860 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
4863 emit_move_insn (copy_rtx (dest
),
4864 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4867 emit_move_insn (copy_rtx (dest
),
4868 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
4871 emit_move_insn (copy_rtx (dest
),
4872 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4873 GEN_INT (ud2
<< 16)));
4875 emit_move_insn (copy_rtx (dest
),
4876 gen_rtx_IOR (DImode
, copy_rtx (dest
), GEN_INT (ud1
)));
4882 /* Helper for the following. Get rid of [r+r] memory refs
4883 in cases where it won't work (TImode, TFmode, TDmode). */
4886 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
4888 if (GET_CODE (operands
[0]) == MEM
4889 && GET_CODE (XEXP (operands
[0], 0)) != REG
4890 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0))
4891 && ! reload_in_progress
)
4893 = replace_equiv_address (operands
[0],
4894 copy_addr_to_reg (XEXP (operands
[0], 0)));
4896 if (GET_CODE (operands
[1]) == MEM
4897 && GET_CODE (XEXP (operands
[1], 0)) != REG
4898 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0))
4899 && ! reload_in_progress
)
4901 = replace_equiv_address (operands
[1],
4902 copy_addr_to_reg (XEXP (operands
[1], 0)));
4905 /* Emit a move from SOURCE to DEST in mode MODE. */
4907 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
4911 operands
[1] = source
;
4913 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
4914 if (GET_CODE (operands
[1]) == CONST_DOUBLE
4915 && ! FLOAT_MODE_P (mode
)
4916 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
4918 /* FIXME. This should never happen. */
4919 /* Since it seems that it does, do the safe thing and convert
4921 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
4923 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
4924 || FLOAT_MODE_P (mode
)
4925 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
4926 || CONST_DOUBLE_LOW (operands
[1]) < 0)
4927 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
4928 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
4930 /* Check if GCC is setting up a block move that will end up using FP
4931 registers as temporaries. We must make sure this is acceptable. */
4932 if (GET_CODE (operands
[0]) == MEM
4933 && GET_CODE (operands
[1]) == MEM
4935 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
4936 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
4937 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
4938 ? 32 : MEM_ALIGN (operands
[0])))
4939 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
4941 : MEM_ALIGN (operands
[1]))))
4942 && ! MEM_VOLATILE_P (operands
[0])
4943 && ! MEM_VOLATILE_P (operands
[1]))
4945 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
4946 adjust_address (operands
[1], SImode
, 0));
4947 emit_move_insn (adjust_address (copy_rtx (operands
[0]), SImode
, 4),
4948 adjust_address (copy_rtx (operands
[1]), SImode
, 4));
4952 if (can_create_pseudo_p () && GET_CODE (operands
[0]) == MEM
4953 && !gpc_reg_operand (operands
[1], mode
))
4954 operands
[1] = force_reg (mode
, operands
[1]);
4956 if (mode
== SFmode
&& ! TARGET_POWERPC
4957 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
4958 && GET_CODE (operands
[0]) == MEM
)
4962 if (reload_in_progress
|| reload_completed
)
4963 regnum
= true_regnum (operands
[1]);
4964 else if (GET_CODE (operands
[1]) == REG
)
4965 regnum
= REGNO (operands
[1]);
4969 /* If operands[1] is a register, on POWER it may have
4970 double-precision data in it, so truncate it to single
4972 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
4975 newreg
= (!can_create_pseudo_p () ? copy_rtx (operands
[1])
4976 : gen_reg_rtx (mode
));
4977 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
4978 operands
[1] = newreg
;
4982 /* Recognize the case where operand[1] is a reference to thread-local
4983 data and load its address to a register. */
4984 if (rs6000_tls_referenced_p (operands
[1]))
4986 enum tls_model model
;
4987 rtx tmp
= operands
[1];
4990 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
4992 addend
= XEXP (XEXP (tmp
, 0), 1);
4993 tmp
= XEXP (XEXP (tmp
, 0), 0);
4996 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
4997 model
= SYMBOL_REF_TLS_MODEL (tmp
);
4998 gcc_assert (model
!= 0);
5000 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
5003 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
5004 tmp
= force_operand (tmp
, operands
[0]);
5009 /* Handle the case where reload calls us with an invalid address. */
5010 if (reload_in_progress
&& mode
== Pmode
5011 && (! general_operand (operands
[1], mode
)
5012 || ! nonimmediate_operand (operands
[0], mode
)))
5015 /* 128-bit constant floating-point values on Darwin should really be
5016 loaded as two parts. */
5017 if (!TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
5018 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
5020 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
5021 know how to get a DFmode SUBREG of a TFmode. */
5022 enum machine_mode imode
= (TARGET_E500_DOUBLE
? DFmode
: DImode
);
5023 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
, 0),
5024 simplify_gen_subreg (imode
, operands
[1], mode
, 0),
5026 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
,
5027 GET_MODE_SIZE (imode
)),
5028 simplify_gen_subreg (imode
, operands
[1], mode
,
5029 GET_MODE_SIZE (imode
)),
5034 if (reload_in_progress
&& cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
5035 cfun
->machine
->sdmode_stack_slot
=
5036 eliminate_regs (cfun
->machine
->sdmode_stack_slot
, VOIDmode
, NULL_RTX
);
5038 if (reload_in_progress
5040 && MEM_P (operands
[0])
5041 && rtx_equal_p (operands
[0], cfun
->machine
->sdmode_stack_slot
)
5042 && REG_P (operands
[1]))
5044 if (FP_REGNO_P (REGNO (operands
[1])))
5046 rtx mem
= adjust_address_nv (operands
[0], DDmode
, 0);
5047 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
5048 emit_insn (gen_movsd_store (mem
, operands
[1]));
5050 else if (INT_REGNO_P (REGNO (operands
[1])))
5052 rtx mem
= adjust_address_nv (operands
[0], mode
, 4);
5053 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
5054 emit_insn (gen_movsd_hardfloat (mem
, operands
[1]));
5060 if (reload_in_progress
5062 && REG_P (operands
[0])
5063 && MEM_P (operands
[1])
5064 && rtx_equal_p (operands
[1], cfun
->machine
->sdmode_stack_slot
))
5066 if (FP_REGNO_P (REGNO (operands
[0])))
5068 rtx mem
= adjust_address_nv (operands
[1], DDmode
, 0);
5069 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
5070 emit_insn (gen_movsd_load (operands
[0], mem
));
5072 else if (INT_REGNO_P (REGNO (operands
[0])))
5074 rtx mem
= adjust_address_nv (operands
[1], mode
, 4);
5075 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
5076 emit_insn (gen_movsd_hardfloat (operands
[0], mem
));
5083 /* FIXME: In the long term, this switch statement should go away
5084 and be replaced by a sequence of tests based on things like
5090 if (CONSTANT_P (operands
[1])
5091 && GET_CODE (operands
[1]) != CONST_INT
)
5092 operands
[1] = force_const_mem (mode
, operands
[1]);
5097 rs6000_eliminate_indexed_memrefs (operands
);
5104 if (CONSTANT_P (operands
[1])
5105 && ! easy_fp_constant (operands
[1], mode
))
5106 operands
[1] = force_const_mem (mode
, operands
[1]);
5117 if (CONSTANT_P (operands
[1])
5118 && !easy_vector_constant (operands
[1], mode
))
5119 operands
[1] = force_const_mem (mode
, operands
[1]);
5124 /* Use default pattern for address of ELF small data */
5127 && DEFAULT_ABI
== ABI_V4
5128 && (GET_CODE (operands
[1]) == SYMBOL_REF
5129 || GET_CODE (operands
[1]) == CONST
)
5130 && small_data_operand (operands
[1], mode
))
5132 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
5136 if (DEFAULT_ABI
== ABI_V4
5137 && mode
== Pmode
&& mode
== SImode
5138 && flag_pic
== 1 && got_operand (operands
[1], mode
))
5140 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
5144 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
5148 && CONSTANT_P (operands
[1])
5149 && GET_CODE (operands
[1]) != HIGH
5150 && GET_CODE (operands
[1]) != CONST_INT
)
5152 rtx target
= (!can_create_pseudo_p ()
5154 : gen_reg_rtx (mode
));
5156 /* If this is a function address on -mcall-aixdesc,
5157 convert it to the address of the descriptor. */
5158 if (DEFAULT_ABI
== ABI_AIX
5159 && GET_CODE (operands
[1]) == SYMBOL_REF
5160 && XSTR (operands
[1], 0)[0] == '.')
5162 const char *name
= XSTR (operands
[1], 0);
5164 while (*name
== '.')
5166 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
5167 CONSTANT_POOL_ADDRESS_P (new_ref
)
5168 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
5169 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
5170 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
5171 SYMBOL_REF_DATA (new_ref
) = SYMBOL_REF_DATA (operands
[1]);
5172 operands
[1] = new_ref
;
5175 if (DEFAULT_ABI
== ABI_DARWIN
)
5178 if (MACHO_DYNAMIC_NO_PIC_P
)
5180 /* Take care of any required data indirection. */
5181 operands
[1] = rs6000_machopic_legitimize_pic_address (
5182 operands
[1], mode
, operands
[0]);
5183 if (operands
[0] != operands
[1])
5184 emit_insn (gen_rtx_SET (VOIDmode
,
5185 operands
[0], operands
[1]));
5189 emit_insn (gen_macho_high (target
, operands
[1]));
5190 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
5194 emit_insn (gen_elf_high (target
, operands
[1]));
5195 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
5199 /* If this is a SYMBOL_REF that refers to a constant pool entry,
5200 and we have put it in the TOC, we just need to make a TOC-relative
5203 && GET_CODE (operands
[1]) == SYMBOL_REF
5204 && constant_pool_expr_p (operands
[1])
5205 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
5206 get_pool_mode (operands
[1])))
5208 operands
[1] = create_TOC_reference (operands
[1]);
5210 else if (mode
== Pmode
5211 && CONSTANT_P (operands
[1])
5212 && ((GET_CODE (operands
[1]) != CONST_INT
5213 && ! easy_fp_constant (operands
[1], mode
))
5214 || (GET_CODE (operands
[1]) == CONST_INT
5215 && num_insns_constant (operands
[1], mode
) > 2)
5216 || (GET_CODE (operands
[0]) == REG
5217 && FP_REGNO_P (REGNO (operands
[0]))))
5218 && GET_CODE (operands
[1]) != HIGH
5219 && ! legitimate_constant_pool_address_p (operands
[1])
5220 && ! toc_relative_expr_p (operands
[1]))
5224 /* Darwin uses a special PIC legitimizer. */
5225 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
5228 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
5230 if (operands
[0] != operands
[1])
5231 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
5236 /* If we are to limit the number of things we put in the TOC and
5237 this is a symbol plus a constant we can add in one insn,
5238 just put the symbol in the TOC and add the constant. Don't do
5239 this if reload is in progress. */
5240 if (GET_CODE (operands
[1]) == CONST
5241 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
5242 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
5243 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
5244 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
5245 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
5246 && ! side_effects_p (operands
[0]))
5249 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
5250 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
5252 sym
= force_reg (mode
, sym
);
5254 emit_insn (gen_addsi3 (operands
[0], sym
, other
));
5256 emit_insn (gen_adddi3 (operands
[0], sym
, other
));
5260 operands
[1] = force_const_mem (mode
, operands
[1]);
5263 && GET_CODE (XEXP (operands
[1], 0)) == SYMBOL_REF
5264 && constant_pool_expr_p (XEXP (operands
[1], 0))
5265 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
5266 get_pool_constant (XEXP (operands
[1], 0)),
5267 get_pool_mode (XEXP (operands
[1], 0))))
5270 = gen_const_mem (mode
,
5271 create_TOC_reference (XEXP (operands
[1], 0)));
5272 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
5278 rs6000_eliminate_indexed_memrefs (operands
);
5282 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
5284 gen_rtx_SET (VOIDmode
,
5285 operands
[0], operands
[1]),
5286 gen_rtx_CLOBBER (VOIDmode
,
5287 gen_rtx_SCRATCH (SImode
)))));
5296 /* Above, we may have called force_const_mem which may have returned
5297 an invalid address. If we can, fix this up; otherwise, reload will
5298 have to deal with it. */
5299 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
5300 operands
[1] = validize_mem (operands
[1]);
5303 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
5306 /* Nonzero if we can use a floating-point register to pass this arg. */
5307 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
5308 (SCALAR_FLOAT_MODE_P (MODE) \
5309 && (CUM)->fregno <= FP_ARG_MAX_REG \
5310 && TARGET_HARD_FLOAT && TARGET_FPRS)
5312 /* Nonzero if we can use an AltiVec register to pass this arg. */
5313 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
5314 (ALTIVEC_VECTOR_MODE (MODE) \
5315 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
5316 && TARGET_ALTIVEC_ABI \
5319 /* Return a nonzero value to say to return the function value in
5320 memory, just as large structures are always returned. TYPE will be
5321 the data type of the value, and FNTYPE will be the type of the
5322 function doing the returning, or @code{NULL} for libcalls.
5324 The AIX ABI for the RS/6000 specifies that all structures are
5325 returned in memory. The Darwin ABI does the same. The SVR4 ABI
5326 specifies that structures <= 8 bytes are returned in r3/r4, but a
5327 draft put them in memory, and GCC used to implement the draft
5328 instead of the final standard. Therefore, aix_struct_return
5329 controls this instead of DEFAULT_ABI; V.4 targets needing backward
5330 compatibility can change DRAFT_V4_STRUCT_RET to override the
5331 default, and -m switches get the final word. See
5332 rs6000_override_options for more details.
5334 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
5335 long double support is enabled. These values are returned in memory.
5337 int_size_in_bytes returns -1 for variable size objects, which go in
5338 memory always. The cast to unsigned makes -1 > 8. */
5341 rs6000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
5343 /* In the darwin64 abi, try to use registers for larger structs
5345 if (rs6000_darwin64_abi
5346 && TREE_CODE (type
) == RECORD_TYPE
5347 && int_size_in_bytes (type
) > 0)
5349 CUMULATIVE_ARGS valcum
;
5353 valcum
.fregno
= FP_ARG_MIN_REG
;
5354 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
5355 /* Do a trial code generation as if this were going to be passed
5356 as an argument; if any part goes in memory, we return NULL. */
5357 valret
= rs6000_darwin64_record_arg (&valcum
, type
, 1, true);
5360 /* Otherwise fall through to more conventional ABI rules. */
5363 if (AGGREGATE_TYPE_P (type
)
5364 && (aix_struct_return
5365 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
5368 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5369 modes only exist for GCC vector types if -maltivec. */
5370 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
5371 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
5374 /* Return synthetic vectors in memory. */
5375 if (TREE_CODE (type
) == VECTOR_TYPE
5376 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
5378 static bool warned_for_return_big_vectors
= false;
5379 if (!warned_for_return_big_vectors
)
5381 warning (0, "GCC vector returned by reference: "
5382 "non-standard ABI extension with no compatibility guarantee");
5383 warned_for_return_big_vectors
= true;
5388 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& TYPE_MODE (type
) == TFmode
)
5394 /* Initialize a variable CUM of type CUMULATIVE_ARGS
5395 for a call to a function whose data type is FNTYPE.
5396 For a library call, FNTYPE is 0.
5398 For incoming args we set the number of arguments in the prototype large
5399 so we never return a PARALLEL. */
5402 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
5403 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
5404 int libcall
, int n_named_args
)
5406 static CUMULATIVE_ARGS zero_cumulative
;
5408 *cum
= zero_cumulative
;
5410 cum
->fregno
= FP_ARG_MIN_REG
;
5411 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
5412 cum
->prototype
= (fntype
&& TYPE_ARG_TYPES (fntype
));
5413 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
5414 ? CALL_LIBCALL
: CALL_NORMAL
);
5415 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
5416 cum
->stdarg
= fntype
5417 && (TYPE_ARG_TYPES (fntype
) != 0
5418 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
5419 != void_type_node
));
5421 cum
->nargs_prototype
= 0;
5422 if (incoming
|| cum
->prototype
)
5423 cum
->nargs_prototype
= n_named_args
;
5425 /* Check for a longcall attribute. */
5426 if ((!fntype
&& rs6000_default_long_calls
)
5428 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
5429 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
5430 cum
->call_cookie
|= CALL_LONG
;
5432 if (TARGET_DEBUG_ARG
)
5434 fprintf (stderr
, "\ninit_cumulative_args:");
5437 tree ret_type
= TREE_TYPE (fntype
);
5438 fprintf (stderr
, " ret code = %s,",
5439 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
5442 if (cum
->call_cookie
& CALL_LONG
)
5443 fprintf (stderr
, " longcall,");
5445 fprintf (stderr
, " proto = %d, nargs = %d\n",
5446 cum
->prototype
, cum
->nargs_prototype
);
5451 && TARGET_ALTIVEC_ABI
5452 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
5454 error ("cannot return value in vector register because"
5455 " altivec instructions are disabled, use -maltivec"
5460 /* Return true if TYPE must be passed on the stack and not in registers. */
5463 rs6000_must_pass_in_stack (enum machine_mode mode
, const_tree type
)
5465 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
5466 return must_pass_in_stack_var_size (mode
, type
);
5468 return must_pass_in_stack_var_size_or_pad (mode
, type
);
5471 /* If defined, a C expression which determines whether, and in which
5472 direction, to pad out an argument with extra space. The value
5473 should be of type `enum direction': either `upward' to pad above
5474 the argument, `downward' to pad below, or `none' to inhibit
5477 For the AIX ABI structs are always stored left shifted in their
5481 function_arg_padding (enum machine_mode mode
, const_tree type
)
5483 #ifndef AGGREGATE_PADDING_FIXED
5484 #define AGGREGATE_PADDING_FIXED 0
5486 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
5487 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
5490 if (!AGGREGATE_PADDING_FIXED
)
5492 /* GCC used to pass structures of the same size as integer types as
5493 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
5494 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
5495 passed padded downward, except that -mstrict-align further
5496 muddied the water in that multi-component structures of 2 and 4
5497 bytes in size were passed padded upward.
5499 The following arranges for best compatibility with previous
5500 versions of gcc, but removes the -mstrict-align dependency. */
5501 if (BYTES_BIG_ENDIAN
)
5503 HOST_WIDE_INT size
= 0;
5505 if (mode
== BLKmode
)
5507 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
5508 size
= int_size_in_bytes (type
);
5511 size
= GET_MODE_SIZE (mode
);
5513 if (size
== 1 || size
== 2 || size
== 4)
5519 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
5521 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
5525 /* Fall back to the default. */
5526 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
5529 /* If defined, a C expression that gives the alignment boundary, in bits,
5530 of an argument with the specified mode and type. If it is not defined,
5531 PARM_BOUNDARY is used for all arguments.
5533 V.4 wants long longs and doubles to be double word aligned. Just
5534 testing the mode size is a boneheaded way to do this as it means
5535 that other types such as complex int are also double word aligned.
5536 However, we're stuck with this because changing the ABI might break
5537 existing library interfaces.
5539 Doubleword align SPE vectors.
5540 Quadword align Altivec vectors.
5541 Quadword align large synthetic vector types. */
5544 function_arg_boundary (enum machine_mode mode
, tree type
)
5546 if (DEFAULT_ABI
== ABI_V4
5547 && (GET_MODE_SIZE (mode
) == 8
5548 || (TARGET_HARD_FLOAT
5550 && (mode
== TFmode
|| mode
== TDmode
))))
5552 else if (SPE_VECTOR_MODE (mode
)
5553 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5554 && int_size_in_bytes (type
) >= 8
5555 && int_size_in_bytes (type
) < 16))
5557 else if (ALTIVEC_VECTOR_MODE (mode
)
5558 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5559 && int_size_in_bytes (type
) >= 16))
5561 else if (rs6000_darwin64_abi
&& mode
== BLKmode
5562 && type
&& TYPE_ALIGN (type
) > 64)
5565 return PARM_BOUNDARY
;
5568 /* For a function parm of MODE and TYPE, return the starting word in
5569 the parameter area. NWORDS of the parameter area are already used. */
5572 rs6000_parm_start (enum machine_mode mode
, tree type
, unsigned int nwords
)
5575 unsigned int parm_offset
;
5577 align
= function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
5578 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
5579 return nwords
+ (-(parm_offset
+ nwords
) & align
);
5582 /* Compute the size (in words) of a function argument. */
5584 static unsigned long
5585 rs6000_arg_size (enum machine_mode mode
, tree type
)
5589 if (mode
!= BLKmode
)
5590 size
= GET_MODE_SIZE (mode
);
5592 size
= int_size_in_bytes (type
);
5595 return (size
+ 3) >> 2;
5597 return (size
+ 7) >> 3;
5600 /* Use this to flush pending int fields. */
5603 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
5604 HOST_WIDE_INT bitpos
)
5606 unsigned int startbit
, endbit
;
5607 int intregs
, intoffset
;
5608 enum machine_mode mode
;
5610 if (cum
->intoffset
== -1)
5613 intoffset
= cum
->intoffset
;
5614 cum
->intoffset
= -1;
5616 if (intoffset
% BITS_PER_WORD
!= 0)
5618 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
5620 if (mode
== BLKmode
)
5622 /* We couldn't find an appropriate mode, which happens,
5623 e.g., in packed structs when there are 3 bytes to load.
5624 Back intoffset back to the beginning of the word in this
5626 intoffset
= intoffset
& -BITS_PER_WORD
;
5630 startbit
= intoffset
& -BITS_PER_WORD
;
5631 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
5632 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
5633 cum
->words
+= intregs
;
5636 /* The darwin64 ABI calls for us to recurse down through structs,
5637 looking for elements passed in registers. Unfortunately, we have
5638 to track int register count here also because of misalignments
5639 in powerpc alignment mode. */
5642 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
5644 HOST_WIDE_INT startbitpos
)
5648 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
5649 if (TREE_CODE (f
) == FIELD_DECL
)
5651 HOST_WIDE_INT bitpos
= startbitpos
;
5652 tree ftype
= TREE_TYPE (f
);
5653 enum machine_mode mode
;
5654 if (ftype
== error_mark_node
)
5656 mode
= TYPE_MODE (ftype
);
5658 if (DECL_SIZE (f
) != 0
5659 && host_integerp (bit_position (f
), 1))
5660 bitpos
+= int_bit_position (f
);
5662 /* ??? FIXME: else assume zero offset. */
5664 if (TREE_CODE (ftype
) == RECORD_TYPE
)
5665 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
5666 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
5668 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
5669 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5670 cum
->words
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5672 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
5674 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
5678 else if (cum
->intoffset
== -1)
5679 cum
->intoffset
= bitpos
;
5683 /* Update the data in CUM to advance over an argument
5684 of mode MODE and data type TYPE.
5685 (TYPE is null for libcalls where that information may not be available.)
5687 Note that for args passed by reference, function_arg will be called
5688 with MODE and TYPE set to that of the pointer to the arg, not the arg
5692 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5693 tree type
, int named
, int depth
)
5697 /* Only tick off an argument if we're not recursing. */
5699 cum
->nargs_prototype
--;
5701 if (TARGET_ALTIVEC_ABI
5702 && (ALTIVEC_VECTOR_MODE (mode
)
5703 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5704 && int_size_in_bytes (type
) == 16)))
5708 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
5711 if (!TARGET_ALTIVEC
)
5712 error ("cannot pass argument in vector register because"
5713 " altivec instructions are disabled, use -maltivec"
5716 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
5717 even if it is going to be passed in a vector register.
5718 Darwin does the same for variable-argument functions. */
5719 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
5720 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
5730 /* Vector parameters must be 16-byte aligned. This places
5731 them at 2 mod 4 in terms of words in 32-bit mode, since
5732 the parameter save area starts at offset 24 from the
5733 stack. In 64-bit mode, they just have to start on an
5734 even word, since the parameter save area is 16-byte
5735 aligned. Space for GPRs is reserved even if the argument
5736 will be passed in memory. */
5738 align
= (2 - cum
->words
) & 3;
5740 align
= cum
->words
& 1;
5741 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
5743 if (TARGET_DEBUG_ARG
)
5745 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
5747 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
5748 cum
->nargs_prototype
, cum
->prototype
,
5749 GET_MODE_NAME (mode
));
5753 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
5755 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
5758 else if (rs6000_darwin64_abi
5760 && TREE_CODE (type
) == RECORD_TYPE
5761 && (size
= int_size_in_bytes (type
)) > 0)
5763 /* Variable sized types have size == -1 and are
5764 treated as if consisting entirely of ints.
5765 Pad to 16 byte boundary if needed. */
5766 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
5767 && (cum
->words
% 2) != 0)
5769 /* For varargs, we can just go up by the size of the struct. */
5771 cum
->words
+= (size
+ 7) / 8;
5774 /* It is tempting to say int register count just goes up by
5775 sizeof(type)/8, but this is wrong in a case such as
5776 { int; double; int; } [powerpc alignment]. We have to
5777 grovel through the fields for these too. */
5779 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
5780 rs6000_darwin64_record_arg_advance_flush (cum
,
5781 size
* BITS_PER_UNIT
);
5784 else if (DEFAULT_ABI
== ABI_V4
)
5786 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5787 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
5788 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
5789 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
5790 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
5792 /* _Decimal128 must use an even/odd register pair. This assumes
5793 that the register number is odd when fregno is odd. */
5794 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
5797 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
5798 <= FP_ARG_V4_MAX_REG
)
5799 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5802 cum
->fregno
= FP_ARG_V4_MAX_REG
+ 1;
5803 if (mode
== DFmode
|| mode
== TFmode
5804 || mode
== DDmode
|| mode
== TDmode
)
5805 cum
->words
+= cum
->words
& 1;
5806 cum
->words
+= rs6000_arg_size (mode
, type
);
5811 int n_words
= rs6000_arg_size (mode
, type
);
5812 int gregno
= cum
->sysv_gregno
;
5814 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5815 (r7,r8) or (r9,r10). As does any other 2 word item such
5816 as complex int due to a historical mistake. */
5818 gregno
+= (1 - gregno
) & 1;
5820 /* Multi-reg args are not split between registers and stack. */
5821 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5823 /* Long long and SPE vectors are aligned on the stack.
5824 So are other 2 word items such as complex int due to
5825 a historical mistake. */
5827 cum
->words
+= cum
->words
& 1;
5828 cum
->words
+= n_words
;
5831 /* Note: continuing to accumulate gregno past when we've started
5832 spilling to the stack indicates the fact that we've started
5833 spilling to the stack to expand_builtin_saveregs. */
5834 cum
->sysv_gregno
= gregno
+ n_words
;
5837 if (TARGET_DEBUG_ARG
)
5839 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
5840 cum
->words
, cum
->fregno
);
5841 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
5842 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
5843 fprintf (stderr
, "mode = %4s, named = %d\n",
5844 GET_MODE_NAME (mode
), named
);
5849 int n_words
= rs6000_arg_size (mode
, type
);
5850 int start_words
= cum
->words
;
5851 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
5853 cum
->words
= align_words
+ n_words
;
5855 if (SCALAR_FLOAT_MODE_P (mode
)
5856 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
5858 /* _Decimal128 must be passed in an even/odd float register pair.
5859 This assumes that the register number is odd when fregno is
5861 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
5863 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5866 if (TARGET_DEBUG_ARG
)
5868 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
5869 cum
->words
, cum
->fregno
);
5870 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
5871 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
5872 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
5873 named
, align_words
- start_words
, depth
);
5879 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
5886 r1
= gen_rtx_REG (DImode
, gregno
);
5887 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5888 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
5892 r1
= gen_rtx_REG (DImode
, gregno
);
5893 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5894 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
5895 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
5896 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
5899 r1
= gen_rtx_REG (DImode
, gregno
);
5900 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5901 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
5902 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
5903 r5
= gen_rtx_REG (DImode
, gregno
+ 4);
5904 r5
= gen_rtx_EXPR_LIST (VOIDmode
, r5
, GEN_INT (16));
5905 r7
= gen_rtx_REG (DImode
, gregno
+ 6);
5906 r7
= gen_rtx_EXPR_LIST (VOIDmode
, r7
, GEN_INT (24));
5907 return gen_rtx_PARALLEL (mode
, gen_rtvec (4, r1
, r3
, r5
, r7
));
5914 /* Determine where to put a SIMD argument on the SPE. */
5916 rs6000_spe_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5919 int gregno
= cum
->sysv_gregno
;
5921 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
5922 are passed and returned in a pair of GPRs for ABI compatibility. */
5923 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5924 || mode
== DCmode
|| mode
== TCmode
))
5926 int n_words
= rs6000_arg_size (mode
, type
);
5928 /* Doubles go in an odd/even register pair (r5/r6, etc). */
5930 gregno
+= (1 - gregno
) & 1;
5932 /* Multi-reg args are not split between registers and stack. */
5933 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5936 return spe_build_register_parallel (mode
, gregno
);
5940 int n_words
= rs6000_arg_size (mode
, type
);
5942 /* SPE vectors are put in odd registers. */
5943 if (n_words
== 2 && (gregno
& 1) == 0)
5946 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
5949 enum machine_mode m
= SImode
;
5951 r1
= gen_rtx_REG (m
, gregno
);
5952 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
5953 r2
= gen_rtx_REG (m
, gregno
+ 1);
5954 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
5955 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
5962 if (gregno
<= GP_ARG_MAX_REG
)
5963 return gen_rtx_REG (mode
, gregno
);
5969 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
5970 structure between cum->intoffset and bitpos to integer registers. */
5973 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
5974 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
5976 enum machine_mode mode
;
5978 unsigned int startbit
, endbit
;
5979 int this_regno
, intregs
, intoffset
;
5982 if (cum
->intoffset
== -1)
5985 intoffset
= cum
->intoffset
;
5986 cum
->intoffset
= -1;
5988 /* If this is the trailing part of a word, try to only load that
5989 much into the register. Otherwise load the whole register. Note
5990 that in the latter case we may pick up unwanted bits. It's not a
5991 problem at the moment but may wish to revisit. */
5993 if (intoffset
% BITS_PER_WORD
!= 0)
5995 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
5997 if (mode
== BLKmode
)
5999 /* We couldn't find an appropriate mode, which happens,
6000 e.g., in packed structs when there are 3 bytes to load.
6001 Back intoffset back to the beginning of the word in this
6003 intoffset
= intoffset
& -BITS_PER_WORD
;
6010 startbit
= intoffset
& -BITS_PER_WORD
;
6011 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
6012 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
6013 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
6015 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
6018 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
6022 intoffset
/= BITS_PER_UNIT
;
6025 regno
= GP_ARG_MIN_REG
+ this_regno
;
6026 reg
= gen_rtx_REG (mode
, regno
);
6028 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
6031 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
6035 while (intregs
> 0);
6038 /* Recursive workhorse for the following. */
6041 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, const_tree type
,
6042 HOST_WIDE_INT startbitpos
, rtx rvec
[],
6047 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
6048 if (TREE_CODE (f
) == FIELD_DECL
)
6050 HOST_WIDE_INT bitpos
= startbitpos
;
6051 tree ftype
= TREE_TYPE (f
);
6052 enum machine_mode mode
;
6053 if (ftype
== error_mark_node
)
6055 mode
= TYPE_MODE (ftype
);
6057 if (DECL_SIZE (f
) != 0
6058 && host_integerp (bit_position (f
), 1))
6059 bitpos
+= int_bit_position (f
);
6061 /* ??? FIXME: else assume zero offset. */
6063 if (TREE_CODE (ftype
) == RECORD_TYPE
)
6064 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
6065 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
6070 case SCmode
: mode
= SFmode
; break;
6071 case DCmode
: mode
= DFmode
; break;
6072 case TCmode
: mode
= TFmode
; break;
6076 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
6078 = gen_rtx_EXPR_LIST (VOIDmode
,
6079 gen_rtx_REG (mode
, cum
->fregno
++),
6080 GEN_INT (bitpos
/ BITS_PER_UNIT
));
6081 if (mode
== TFmode
|| mode
== TDmode
)
6084 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
6086 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
6088 = gen_rtx_EXPR_LIST (VOIDmode
,
6089 gen_rtx_REG (mode
, cum
->vregno
++),
6090 GEN_INT (bitpos
/ BITS_PER_UNIT
));
6092 else if (cum
->intoffset
== -1)
6093 cum
->intoffset
= bitpos
;
6097 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
6098 the register(s) to be used for each field and subfield of a struct
6099 being passed by value, along with the offset of where the
6100 register's value may be found in the block. FP fields go in FP
6101 register, vector fields go in vector registers, and everything
6102 else goes in int registers, packed as in memory.
6104 This code is also used for function return values. RETVAL indicates
6105 whether this is the case.
6107 Much of this is taken from the SPARC V9 port, which has a similar
6108 calling convention. */
6111 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, const_tree type
,
6112 int named
, bool retval
)
6114 rtx rvec
[FIRST_PSEUDO_REGISTER
];
6115 int k
= 1, kbase
= 1;
6116 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
6117 /* This is a copy; modifications are not visible to our caller. */
6118 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
6119 CUMULATIVE_ARGS
*cum
= ©_cum
;
6121 /* Pad to 16 byte boundary if needed. */
6122 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
6123 && (cum
->words
% 2) != 0)
6130 /* Put entries into rvec[] for individual FP and vector fields, and
6131 for the chunks of memory that go in int regs. Note we start at
6132 element 1; 0 is reserved for an indication of using memory, and
6133 may or may not be filled in below. */
6134 rs6000_darwin64_record_arg_recurse (cum
, type
, 0, rvec
, &k
);
6135 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
6137 /* If any part of the struct went on the stack put all of it there.
6138 This hack is because the generic code for
6139 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
6140 parts of the struct are not at the beginning. */
6144 return NULL_RTX
; /* doesn't go in registers at all */
6146 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
6148 if (k
> 1 || cum
->use_stack
)
6149 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
6154 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
6157 rs6000_mixed_function_arg (enum machine_mode mode
, tree type
, int align_words
)
6161 rtx rvec
[GP_ARG_NUM_REG
+ 1];
6163 if (align_words
>= GP_ARG_NUM_REG
)
6166 n_units
= rs6000_arg_size (mode
, type
);
6168 /* Optimize the simple case where the arg fits in one gpr, except in
6169 the case of BLKmode due to assign_parms assuming that registers are
6170 BITS_PER_WORD wide. */
6172 || (n_units
== 1 && mode
!= BLKmode
))
6173 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6176 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
6177 /* Not all of the arg fits in gprs. Say that it goes in memory too,
6178 using a magic NULL_RTX component.
6179 This is not strictly correct. Only some of the arg belongs in
6180 memory, not all of it. However, the normal scheme using
6181 function_arg_partial_nregs can result in unusual subregs, eg.
6182 (subreg:SI (reg:DF) 4), which are not handled well. The code to
6183 store the whole arg to memory is often more efficient than code
6184 to store pieces, and we know that space is available in the right
6185 place for the whole arg. */
6186 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
6191 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
6192 rtx off
= GEN_INT (i
++ * 4);
6193 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
6195 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
6197 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
6200 /* Determine where to put an argument to a function.
6201 Value is zero to push the argument on the stack,
6202 or a hard register in which to store the argument.
6204 MODE is the argument's machine mode.
6205 TYPE is the data type of the argument (as a tree).
6206 This is null for libcalls where that information may
6208 CUM is a variable of type CUMULATIVE_ARGS which gives info about
6209 the preceding args and about the function being called. It is
6210 not modified in this routine.
6211 NAMED is nonzero if this argument is a named parameter
6212 (otherwise it is an extra parameter matching an ellipsis).
6214 On RS/6000 the first eight words of non-FP are normally in registers
6215 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
6216 Under V.4, the first 8 FP args are in registers.
6218 If this is floating-point and no prototype is specified, we use
6219 both an FP and integer register (or possibly FP reg and stack). Library
6220 functions (when CALL_LIBCALL is set) always have the proper types for args,
6221 so we can pass the FP value just in one register. emit_library_function
6222 doesn't support PARALLEL anyway.
6224 Note that for args passed by reference, function_arg will be called
6225 with MODE and TYPE set to that of the pointer to the arg, not the arg
6229 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6230 tree type
, int named
)
6232 enum rs6000_abi abi
= DEFAULT_ABI
;
6234 /* Return a marker to indicate whether CR1 needs to set or clear the
6235 bit that V.4 uses to say fp args were passed in registers.
6236 Assume that we don't need the marker for software floating point,
6237 or compiler generated library calls. */
6238 if (mode
== VOIDmode
)
6241 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
6243 || (cum
->nargs_prototype
< 0
6244 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))))
6246 /* For the SPE, we need to crxor CR6 always. */
6248 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
6249 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
6250 return GEN_INT (cum
->call_cookie
6251 | ((cum
->fregno
== FP_ARG_MIN_REG
)
6252 ? CALL_V4_SET_FP_ARGS
6253 : CALL_V4_CLEAR_FP_ARGS
));
6256 return GEN_INT (cum
->call_cookie
);
6259 if (rs6000_darwin64_abi
&& mode
== BLKmode
6260 && TREE_CODE (type
) == RECORD_TYPE
)
6262 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, false);
6263 if (rslt
!= NULL_RTX
)
6265 /* Else fall through to usual handling. */
6268 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
6269 if (TARGET_64BIT
&& ! cum
->prototype
)
6271 /* Vector parameters get passed in vector register
6272 and also in GPRs or memory, in absence of prototype. */
6275 align_words
= (cum
->words
+ 1) & ~1;
6277 if (align_words
>= GP_ARG_NUM_REG
)
6283 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6285 return gen_rtx_PARALLEL (mode
,
6287 gen_rtx_EXPR_LIST (VOIDmode
,
6289 gen_rtx_EXPR_LIST (VOIDmode
,
6290 gen_rtx_REG (mode
, cum
->vregno
),
6294 return gen_rtx_REG (mode
, cum
->vregno
);
6295 else if (TARGET_ALTIVEC_ABI
6296 && (ALTIVEC_VECTOR_MODE (mode
)
6297 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
6298 && int_size_in_bytes (type
) == 16)))
6300 if (named
|| abi
== ABI_V4
)
6304 /* Vector parameters to varargs functions under AIX or Darwin
6305 get passed in memory and possibly also in GPRs. */
6306 int align
, align_words
, n_words
;
6307 enum machine_mode part_mode
;
6309 /* Vector parameters must be 16-byte aligned. This places them at
6310 2 mod 4 in terms of words in 32-bit mode, since the parameter
6311 save area starts at offset 24 from the stack. In 64-bit mode,
6312 they just have to start on an even word, since the parameter
6313 save area is 16-byte aligned. */
6315 align
= (2 - cum
->words
) & 3;
6317 align
= cum
->words
& 1;
6318 align_words
= cum
->words
+ align
;
6320 /* Out of registers? Memory, then. */
6321 if (align_words
>= GP_ARG_NUM_REG
)
6324 if (TARGET_32BIT
&& TARGET_POWERPC64
)
6325 return rs6000_mixed_function_arg (mode
, type
, align_words
);
6327 /* The vector value goes in GPRs. Only the part of the
6328 value in GPRs is reported here. */
6330 n_words
= rs6000_arg_size (mode
, type
);
6331 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
6332 /* Fortunately, there are only two possibilities, the value
6333 is either wholly in GPRs or half in GPRs and half not. */
6336 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
6339 else if (TARGET_SPE_ABI
&& TARGET_SPE
6340 && (SPE_VECTOR_MODE (mode
)
6341 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
6344 || mode
== TCmode
))))
6345 return rs6000_spe_function_arg (cum
, mode
, type
);
6347 else if (abi
== ABI_V4
)
6349 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
6350 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
6351 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
6352 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
6353 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
6355 /* _Decimal128 must use an even/odd register pair. This assumes
6356 that the register number is odd when fregno is odd. */
6357 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
6360 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
6361 <= FP_ARG_V4_MAX_REG
)
6362 return gen_rtx_REG (mode
, cum
->fregno
);
6368 int n_words
= rs6000_arg_size (mode
, type
);
6369 int gregno
= cum
->sysv_gregno
;
6371 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
6372 (r7,r8) or (r9,r10). As does any other 2 word item such
6373 as complex int due to a historical mistake. */
6375 gregno
+= (1 - gregno
) & 1;
6377 /* Multi-reg args are not split between registers and stack. */
6378 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
6381 if (TARGET_32BIT
&& TARGET_POWERPC64
)
6382 return rs6000_mixed_function_arg (mode
, type
,
6383 gregno
- GP_ARG_MIN_REG
);
6384 return gen_rtx_REG (mode
, gregno
);
6389 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
6391 /* _Decimal128 must be passed in an even/odd float register pair.
6392 This assumes that the register number is odd when fregno is odd. */
6393 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
6396 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
6398 rtx rvec
[GP_ARG_NUM_REG
+ 1];
6402 enum machine_mode fmode
= mode
;
6403 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
6405 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
6407 /* Currently, we only ever need one reg here because complex
6408 doubles are split. */
6409 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
6410 && (fmode
== TFmode
|| fmode
== TDmode
));
6412 /* Long double or _Decimal128 split over regs and memory. */
6413 fmode
= DECIMAL_FLOAT_MODE_P (fmode
) ? DDmode
: DFmode
;
6416 /* Do we also need to pass this arg in the parameter save
6419 && (cum
->nargs_prototype
<= 0
6420 || (DEFAULT_ABI
== ABI_AIX
6422 && align_words
>= GP_ARG_NUM_REG
)));
6424 if (!needs_psave
&& mode
== fmode
)
6425 return gen_rtx_REG (fmode
, cum
->fregno
);
6430 /* Describe the part that goes in gprs or the stack.
6431 This piece must come first, before the fprs. */
6432 if (align_words
< GP_ARG_NUM_REG
)
6434 unsigned long n_words
= rs6000_arg_size (mode
, type
);
6436 if (align_words
+ n_words
> GP_ARG_NUM_REG
6437 || (TARGET_32BIT
&& TARGET_POWERPC64
))
6439 /* If this is partially on the stack, then we only
6440 include the portion actually in registers here. */
6441 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
6444 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
6445 /* Not all of the arg fits in gprs. Say that it
6446 goes in memory too, using a magic NULL_RTX
6447 component. Also see comment in
6448 rs6000_mixed_function_arg for why the normal
6449 function_arg_partial_nregs scheme doesn't work
6451 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
6455 r
= gen_rtx_REG (rmode
,
6456 GP_ARG_MIN_REG
+ align_words
);
6457 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
6458 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
6460 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
6464 /* The whole arg fits in gprs. */
6465 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6466 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
6470 /* It's entirely in memory. */
6471 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
6474 /* Describe where this piece goes in the fprs. */
6475 r
= gen_rtx_REG (fmode
, cum
->fregno
);
6476 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
6478 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
6480 else if (align_words
< GP_ARG_NUM_REG
)
6482 if (TARGET_32BIT
&& TARGET_POWERPC64
)
6483 return rs6000_mixed_function_arg (mode
, type
, align_words
);
6485 if (mode
== BLKmode
)
6488 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6495 /* For an arg passed partly in registers and partly in memory, this is
6496 the number of bytes passed in registers. For args passed entirely in
6497 registers or entirely in memory, zero. When an arg is described by a
6498 PARALLEL, perhaps using more than one register type, this function
6499 returns the number of bytes used by the first element of the PARALLEL. */
6502 rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6503 tree type
, bool named
)
6508 if (DEFAULT_ABI
== ABI_V4
)
6511 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
6512 && cum
->nargs_prototype
>= 0)
6515 /* In this complicated case we just disable the partial_nregs code. */
6516 if (rs6000_darwin64_abi
&& mode
== BLKmode
6517 && TREE_CODE (type
) == RECORD_TYPE
6518 && int_size_in_bytes (type
) > 0)
6521 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
6523 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
6525 /* If we are passing this arg in the fixed parameter save area
6526 (gprs or memory) as well as fprs, then this function should
6527 return the number of partial bytes passed in the parameter
6528 save area rather than partial bytes passed in fprs. */
6530 && (cum
->nargs_prototype
<= 0
6531 || (DEFAULT_ABI
== ABI_AIX
6533 && align_words
>= GP_ARG_NUM_REG
)))
6535 else if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3)
6536 > FP_ARG_MAX_REG
+ 1)
6537 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
6538 else if (cum
->nargs_prototype
>= 0)
6542 if (align_words
< GP_ARG_NUM_REG
6543 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
6544 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
6546 if (ret
!= 0 && TARGET_DEBUG_ARG
)
6547 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
6552 /* A C expression that indicates when an argument must be passed by
6553 reference. If nonzero for an argument, a copy of that argument is
6554 made in memory and a pointer to the argument is passed instead of
6555 the argument itself. The pointer is passed in whatever way is
6556 appropriate for passing a pointer to that type.
6558 Under V.4, aggregates and long double are passed by reference.
6560 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
6561 reference unless the AltiVec vector extension ABI is in force.
6563 As an extension to all ABIs, variable sized types are passed by
6567 rs6000_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
6568 enum machine_mode mode
, const_tree type
,
6569 bool named ATTRIBUTE_UNUSED
)
6571 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& mode
== TFmode
)
6573 if (TARGET_DEBUG_ARG
)
6574 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
6581 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
6583 if (TARGET_DEBUG_ARG
)
6584 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
6588 if (int_size_in_bytes (type
) < 0)
6590 if (TARGET_DEBUG_ARG
)
6591 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
6595 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6596 modes only exist for GCC vector types if -maltivec. */
6597 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
6599 if (TARGET_DEBUG_ARG
)
6600 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
6604 /* Pass synthetic vectors in memory. */
6605 if (TREE_CODE (type
) == VECTOR_TYPE
6606 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
6608 static bool warned_for_pass_big_vectors
= false;
6609 if (TARGET_DEBUG_ARG
)
6610 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
6611 if (!warned_for_pass_big_vectors
)
6613 warning (0, "GCC vector passed by reference: "
6614 "non-standard ABI extension with no compatibility guarantee");
6615 warned_for_pass_big_vectors
= true;
6624 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
6627 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
6632 for (i
= 0; i
< nregs
; i
++)
6634 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
6635 if (reload_completed
)
6637 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
6640 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
6641 i
* GET_MODE_SIZE (reg_mode
));
6644 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
6648 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
6652 /* Perform any needed actions needed for a function that is receiving a
6653 variable number of arguments.
6657 MODE and TYPE are the mode and type of the current parameter.
6659 PRETEND_SIZE is a variable that should be set to the amount of stack
6660 that must be pushed by the prolog to pretend that our caller pushed
6663 Normally, this macro will push all remaining incoming registers on the
6664 stack and set PRETEND_SIZE to the length of the registers pushed. */
6667 setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6668 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
6671 CUMULATIVE_ARGS next_cum
;
6672 int reg_size
= TARGET_32BIT
? 4 : 8;
6673 rtx save_area
= NULL_RTX
, mem
;
6674 int first_reg_offset
;
6677 /* Skip the last named argument. */
6679 function_arg_advance (&next_cum
, mode
, type
, 1, 0);
6681 if (DEFAULT_ABI
== ABI_V4
)
6683 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
6687 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
6688 HOST_WIDE_INT offset
= 0;
6690 /* Try to optimize the size of the varargs save area.
6691 The ABI requires that ap.reg_save_area is doubleword
6692 aligned, but we don't need to allocate space for all
6693 the bytes, only those to which we actually will save
6695 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
6696 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
6697 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
6698 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
6699 && cfun
->va_list_fpr_size
)
6702 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
6703 * UNITS_PER_FP_WORD
;
6704 if (cfun
->va_list_fpr_size
6705 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
6706 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
6708 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
6709 * UNITS_PER_FP_WORD
;
6713 offset
= -((first_reg_offset
* reg_size
) & ~7);
6714 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
6716 gpr_reg_num
= cfun
->va_list_gpr_size
;
6717 if (reg_size
== 4 && (first_reg_offset
& 1))
6720 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
6723 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
6725 - (int) (GP_ARG_NUM_REG
* reg_size
);
6727 if (gpr_size
+ fpr_size
)
6730 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
6731 gcc_assert (GET_CODE (reg_save_area
) == MEM
);
6732 reg_save_area
= XEXP (reg_save_area
, 0);
6733 if (GET_CODE (reg_save_area
) == PLUS
)
6735 gcc_assert (XEXP (reg_save_area
, 0)
6736 == virtual_stack_vars_rtx
);
6737 gcc_assert (GET_CODE (XEXP (reg_save_area
, 1)) == CONST_INT
);
6738 offset
+= INTVAL (XEXP (reg_save_area
, 1));
6741 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
6744 cfun
->machine
->varargs_save_offset
= offset
;
6745 save_area
= plus_constant (virtual_stack_vars_rtx
, offset
);
6750 first_reg_offset
= next_cum
.words
;
6751 save_area
= virtual_incoming_args_rtx
;
6753 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
6754 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
6757 set
= get_varargs_alias_set ();
6758 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
6759 && cfun
->va_list_gpr_size
)
6761 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
6763 if (va_list_gpr_counter_field
)
6765 /* V4 va_list_gpr_size counts number of registers needed. */
6766 if (nregs
> cfun
->va_list_gpr_size
)
6767 nregs
= cfun
->va_list_gpr_size
;
6771 /* char * va_list instead counts number of bytes needed. */
6772 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
6773 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
6776 mem
= gen_rtx_MEM (BLKmode
,
6777 plus_constant (save_area
,
6778 first_reg_offset
* reg_size
));
6779 MEM_NOTRAP_P (mem
) = 1;
6780 set_mem_alias_set (mem
, set
);
6781 set_mem_align (mem
, BITS_PER_WORD
);
6783 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
6787 /* Save FP registers if needed. */
6788 if (DEFAULT_ABI
== ABI_V4
6789 && TARGET_HARD_FLOAT
&& TARGET_FPRS
6791 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
6792 && cfun
->va_list_fpr_size
)
6794 int fregno
= next_cum
.fregno
, nregs
;
6795 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
6796 rtx lab
= gen_label_rtx ();
6797 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
6798 * UNITS_PER_FP_WORD
);
6801 (gen_rtx_SET (VOIDmode
,
6803 gen_rtx_IF_THEN_ELSE (VOIDmode
,
6804 gen_rtx_NE (VOIDmode
, cr1
,
6806 gen_rtx_LABEL_REF (VOIDmode
, lab
),
6810 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
6811 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
6813 mem
= gen_rtx_MEM ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
6815 plus_constant (save_area
, off
));
6816 MEM_NOTRAP_P (mem
) = 1;
6817 set_mem_alias_set (mem
, set
);
6818 set_mem_align (mem
, GET_MODE_ALIGNMENT (
6819 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
6820 ? DFmode
: SFmode
));
6821 emit_move_insn (mem
, gen_rtx_REG (
6822 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
6823 ? DFmode
: SFmode
, fregno
));
6830 /* Create the va_list data type. */
6833 rs6000_build_builtin_va_list (void)
6835 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
6837 /* For AIX, prefer 'char *' because that's what the system
6838 header files like. */
6839 if (DEFAULT_ABI
!= ABI_V4
)
6840 return build_pointer_type (char_type_node
);
6842 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
6843 type_decl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
6844 get_identifier ("__va_list_tag"), record
);
6846 f_gpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("gpr"),
6847 unsigned_char_type_node
);
6848 f_fpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("fpr"),
6849 unsigned_char_type_node
);
6850 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
6852 f_res
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
6853 get_identifier ("reserved"), short_unsigned_type_node
);
6854 f_ovf
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
6855 get_identifier ("overflow_arg_area"),
6857 f_sav
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
6858 get_identifier ("reg_save_area"),
6861 va_list_gpr_counter_field
= f_gpr
;
6862 va_list_fpr_counter_field
= f_fpr
;
6864 DECL_FIELD_CONTEXT (f_gpr
) = record
;
6865 DECL_FIELD_CONTEXT (f_fpr
) = record
;
6866 DECL_FIELD_CONTEXT (f_res
) = record
;
6867 DECL_FIELD_CONTEXT (f_ovf
) = record
;
6868 DECL_FIELD_CONTEXT (f_sav
) = record
;
6870 TREE_CHAIN (record
) = type_decl
;
6871 TYPE_NAME (record
) = type_decl
;
6872 TYPE_FIELDS (record
) = f_gpr
;
6873 TREE_CHAIN (f_gpr
) = f_fpr
;
6874 TREE_CHAIN (f_fpr
) = f_res
;
6875 TREE_CHAIN (f_res
) = f_ovf
;
6876 TREE_CHAIN (f_ovf
) = f_sav
;
6878 layout_type (record
);
6880 /* The correct type is an array type of one element. */
6881 return build_array_type (record
, build_index_type (size_zero_node
));
6884 /* Implement va_start. */
6887 rs6000_va_start (tree valist
, rtx nextarg
)
6889 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
6890 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
6891 tree gpr
, fpr
, ovf
, sav
, t
;
6893 /* Only SVR4 needs something special. */
6894 if (DEFAULT_ABI
!= ABI_V4
)
6896 std_expand_builtin_va_start (valist
, nextarg
);
6900 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6901 f_fpr
= TREE_CHAIN (f_gpr
);
6902 f_res
= TREE_CHAIN (f_fpr
);
6903 f_ovf
= TREE_CHAIN (f_res
);
6904 f_sav
= TREE_CHAIN (f_ovf
);
6906 valist
= build_va_arg_indirect_ref (valist
);
6907 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6908 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
6910 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
6912 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
6915 /* Count number of gp and fp argument registers used. */
6916 words
= crtl
->args
.info
.words
;
6917 n_gpr
= MIN (crtl
->args
.info
.sysv_gregno
- GP_ARG_MIN_REG
,
6919 n_fpr
= MIN (crtl
->args
.info
.fregno
- FP_ARG_MIN_REG
,
6922 if (TARGET_DEBUG_ARG
)
6923 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
6924 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
6925 words
, n_gpr
, n_fpr
);
6927 if (cfun
->va_list_gpr_size
)
6929 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
6930 build_int_cst (NULL_TREE
, n_gpr
));
6931 TREE_SIDE_EFFECTS (t
) = 1;
6932 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6935 if (cfun
->va_list_fpr_size
)
6937 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
6938 build_int_cst (NULL_TREE
, n_fpr
));
6939 TREE_SIDE_EFFECTS (t
) = 1;
6940 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6943 /* Find the overflow area. */
6944 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
6946 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ovf
), t
,
6947 size_int (words
* UNITS_PER_WORD
));
6948 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
6949 TREE_SIDE_EFFECTS (t
) = 1;
6950 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6952 /* If there were no va_arg invocations, don't set up the register
6954 if (!cfun
->va_list_gpr_size
6955 && !cfun
->va_list_fpr_size
6956 && n_gpr
< GP_ARG_NUM_REG
6957 && n_fpr
< FP_ARG_V4_MAX_REG
)
6960 /* Find the register save area. */
6961 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
6962 if (cfun
->machine
->varargs_save_offset
)
6963 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (sav
), t
,
6964 size_int (cfun
->machine
->varargs_save_offset
));
6965 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
6966 TREE_SIDE_EFFECTS (t
) = 1;
6967 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6970 /* Implement va_arg. */
6973 rs6000_gimplify_va_arg (tree valist
, tree type
, gimple_seq
*pre_p
,
6976 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
6977 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
6978 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
6979 tree lab_false
, lab_over
, addr
;
6981 tree ptrtype
= build_pointer_type (type
);
6985 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
6987 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
6988 return build_va_arg_indirect_ref (t
);
6991 if (DEFAULT_ABI
!= ABI_V4
)
6993 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
6995 tree elem_type
= TREE_TYPE (type
);
6996 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
6997 int elem_size
= GET_MODE_SIZE (elem_mode
);
6999 if (elem_size
< UNITS_PER_WORD
)
7001 tree real_part
, imag_part
;
7002 gimple_seq post
= NULL
;
7004 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
7006 /* Copy the value into a temporary, lest the formal temporary
7007 be reused out from under us. */
7008 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
7009 gimple_seq_add_seq (pre_p
, post
);
7011 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
7014 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
7018 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
7021 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
7022 f_fpr
= TREE_CHAIN (f_gpr
);
7023 f_res
= TREE_CHAIN (f_fpr
);
7024 f_ovf
= TREE_CHAIN (f_res
);
7025 f_sav
= TREE_CHAIN (f_ovf
);
7027 valist
= build_va_arg_indirect_ref (valist
);
7028 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
7029 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
7031 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
7033 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
7036 size
= int_size_in_bytes (type
);
7037 rsize
= (size
+ 3) / 4;
7040 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
7041 && ((TARGET_SINGLE_FLOAT
&& TYPE_MODE (type
) == SFmode
)
7042 || (TARGET_DOUBLE_FLOAT
7043 && (TYPE_MODE (type
) == DFmode
7044 || TYPE_MODE (type
) == TFmode
7045 || TYPE_MODE (type
) == SDmode
7046 || TYPE_MODE (type
) == DDmode
7047 || TYPE_MODE (type
) == TDmode
))))
7049 /* FP args go in FP registers, if present. */
7051 n_reg
= (size
+ 7) / 8;
7052 sav_ofs
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4) * 4;
7053 sav_scale
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4);
7054 if (TYPE_MODE (type
) != SFmode
&& TYPE_MODE (type
) != SDmode
)
7059 /* Otherwise into GP registers. */
7068 /* Pull the value out of the saved registers.... */
7071 addr
= create_tmp_var (ptr_type_node
, "addr");
7072 DECL_POINTER_ALIAS_SET (addr
) = get_varargs_alias_set ();
7074 /* AltiVec vectors never go in registers when -mabi=altivec. */
7075 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
7079 lab_false
= create_artificial_label (input_location
);
7080 lab_over
= create_artificial_label (input_location
);
7082 /* Long long and SPE vectors are aligned in the registers.
7083 As are any other 2 gpr item such as complex int due to a
7084 historical mistake. */
7086 if (n_reg
== 2 && reg
== gpr
)
7089 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
7090 build_int_cst (TREE_TYPE (reg
), n_reg
- 1));
7091 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
),
7092 unshare_expr (reg
), u
);
7094 /* _Decimal128 is passed in even/odd fpr pairs; the stored
7095 reg number is 0 for f1, so we want to make it odd. */
7096 else if (reg
== fpr
&& TYPE_MODE (type
) == TDmode
)
7098 t
= build2 (BIT_IOR_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
7099 build_int_cst (TREE_TYPE (reg
), 1));
7100 u
= build2 (MODIFY_EXPR
, void_type_node
, unshare_expr (reg
), t
);
7103 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
7104 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
7105 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
7106 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
7107 gimplify_and_add (t
, pre_p
);
7111 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, sav
, size_int (sav_ofs
));
7113 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
7114 build_int_cst (TREE_TYPE (reg
), n_reg
));
7115 u
= fold_convert (sizetype
, u
);
7116 u
= build2 (MULT_EXPR
, sizetype
, u
, size_int (sav_scale
));
7117 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
, u
);
7119 /* _Decimal32 varargs are located in the second word of the 64-bit
7120 FP register for 32-bit binaries. */
7121 if (!TARGET_POWERPC64
7122 && TARGET_HARD_FLOAT
&& TARGET_FPRS
7123 && TYPE_MODE (type
) == SDmode
)
7124 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
7126 gimplify_assign (addr
, t
, pre_p
);
7128 gimple_seq_add_stmt (pre_p
, gimple_build_goto (lab_over
));
7130 stmt
= gimple_build_label (lab_false
);
7131 gimple_seq_add_stmt (pre_p
, stmt
);
7133 if ((n_reg
== 2 && !regalign
) || n_reg
> 2)
7135 /* Ensure that we don't find any more args in regs.
7136 Alignment has taken care of for special cases. */
7137 gimplify_assign (reg
, build_int_cst (TREE_TYPE (reg
), 8), pre_p
);
7141 /* ... otherwise out of the overflow area. */
7143 /* Care for on-stack alignment if needed. */
7147 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (align
- 1));
7148 t
= fold_convert (sizetype
, t
);
7149 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
7151 t
= fold_convert (TREE_TYPE (ovf
), t
);
7153 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
7155 gimplify_assign (unshare_expr (addr
), t
, pre_p
);
7157 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
7158 gimplify_assign (unshare_expr (ovf
), t
, pre_p
);
7162 stmt
= gimple_build_label (lab_over
);
7163 gimple_seq_add_stmt (pre_p
, stmt
);
7166 if (STRICT_ALIGNMENT
7167 && (TYPE_ALIGN (type
)
7168 > (unsigned) BITS_PER_UNIT
* (align
< 4 ? 4 : align
)))
7170 /* The value (of type complex double, for example) may not be
7171 aligned in memory in the saved registers, so copy via a
7172 temporary. (This is the same code as used for SPARC.) */
7173 tree tmp
= create_tmp_var (type
, "va_arg_tmp");
7174 tree dest_addr
= build_fold_addr_expr (tmp
);
7176 tree copy
= build_call_expr (implicit_built_in_decls
[BUILT_IN_MEMCPY
],
7177 3, dest_addr
, addr
, size_int (rsize
* 4));
7179 gimplify_and_add (copy
, pre_p
);
7183 addr
= fold_convert (ptrtype
, addr
);
7184 return build_va_arg_indirect_ref (addr
);
7190 def_builtin (int mask
, const char *name
, tree type
, int code
)
7192 if ((mask
& target_flags
) || TARGET_PAIRED_FLOAT
)
7194 if (rs6000_builtin_decls
[code
])
7197 rs6000_builtin_decls
[code
] =
7198 add_builtin_function (name
, type
, code
, BUILT_IN_MD
,
7203 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
7205 static const struct builtin_description bdesc_3arg
[] =
7207 { MASK_ALTIVEC
, CODE_FOR_altivec_vmaddfp
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
7208 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
7209 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
7210 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
7211 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
7212 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
7213 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
7214 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
7215 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
7216 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
7217 { MASK_ALTIVEC
, CODE_FOR_altivec_vnmsubfp
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
7218 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
7219 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
7220 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
7221 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
7222 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
7223 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
7224 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
7225 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
7226 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
7227 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
7228 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
7229 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
7231 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
7232 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
7233 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
7234 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
7235 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
7236 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
7237 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
7238 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
7239 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
7240 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
7241 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
7242 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
7243 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
7244 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
7245 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
7247 { 0, CODE_FOR_paired_msub
, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB
},
7248 { 0, CODE_FOR_paired_madd
, "__builtin_paired_madd", PAIRED_BUILTIN_MADD
},
7249 { 0, CODE_FOR_paired_madds0
, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0
},
7250 { 0, CODE_FOR_paired_madds1
, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1
},
7251 { 0, CODE_FOR_paired_nmsub
, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB
},
7252 { 0, CODE_FOR_paired_nmadd
, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD
},
7253 { 0, CODE_FOR_paired_sum0
, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0
},
7254 { 0, CODE_FOR_paired_sum1
, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1
},
7255 { 0, CODE_FOR_selv2sf4
, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4
},
7258 /* DST operations: void foo (void *, const int, const char). */
7260 static const struct builtin_description bdesc_dst
[] =
7262 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
7263 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
7264 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
7265 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
7267 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
7268 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
7269 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
7270 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
7273 /* Simple binary operations: VECc = foo (VECa, VECb). */
7275 static struct builtin_description bdesc_2arg
[] =
7277 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
7278 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
7279 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
7280 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
7281 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
7282 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
7283 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
7284 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
7285 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
7286 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
7287 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
7288 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
7289 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
7290 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
7291 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
7292 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
7293 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
7294 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
7295 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
7296 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
7297 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
7298 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
7299 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequb
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
7300 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequh
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
7301 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequw
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
7302 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpeqfp
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
7303 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgefp
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
7304 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtub
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
7305 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsb
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
7306 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuh
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
7307 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsh
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
7308 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuw
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
7309 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsw
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
7310 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtfp
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
7311 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
7312 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
7313 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
7314 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
7315 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
7316 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
7317 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
7318 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
7319 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
7320 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
7321 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
7322 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
7323 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
7324 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
7325 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
7326 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
7327 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
7328 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
7329 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
7330 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
7331 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
7332 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
7333 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
7334 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
7335 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
7336 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
7337 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
7338 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
7339 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
7340 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
7341 { MASK_ALTIVEC
, CODE_FOR_altivec_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
7342 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
7343 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
7344 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
7345 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
7346 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
7347 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
7348 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
7349 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
7350 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
7351 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
7352 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlb
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
7353 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlh
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
7354 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlw
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
7355 { MASK_ALTIVEC
, CODE_FOR_vashlv16qi3
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
7356 { MASK_ALTIVEC
, CODE_FOR_vashlv8hi3
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
7357 { MASK_ALTIVEC
, CODE_FOR_vashlv4si3
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
7358 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
7359 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
7360 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
7361 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
7362 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
7363 { MASK_ALTIVEC
, CODE_FOR_vlshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
7364 { MASK_ALTIVEC
, CODE_FOR_vlshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
7365 { MASK_ALTIVEC
, CODE_FOR_vlshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
7366 { MASK_ALTIVEC
, CODE_FOR_vashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
7367 { MASK_ALTIVEC
, CODE_FOR_vashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
7368 { MASK_ALTIVEC
, CODE_FOR_vashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
7369 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
7370 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
7371 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
7372 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
7373 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
7374 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
7375 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
7376 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
7377 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
7378 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
7379 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
7380 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
7381 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
7382 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
7383 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
7384 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
7385 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
7386 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
7387 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
7389 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
7390 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
7391 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
7392 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
7393 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
7394 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
7395 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
7396 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
7397 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
7398 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
7399 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
7400 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
7401 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
7402 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
7403 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
7404 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
7405 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
7406 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
7407 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
7408 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
7409 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
7410 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
7411 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
7412 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
7413 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
7414 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
7415 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
7416 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
7417 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
7418 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
7419 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
7420 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
7421 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
7422 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
7423 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
7424 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
7425 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
7426 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
7427 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
7428 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
7429 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
7430 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
7431 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
7432 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
7433 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
7434 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
7435 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
7436 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
7437 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
7438 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
7439 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
7440 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
7441 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
7442 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
7443 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
7444 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
7445 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
7446 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
7447 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
7448 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
7449 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
7450 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
7451 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
7452 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
7453 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
7454 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
7455 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
7456 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
7457 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
7458 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
7459 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
7460 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
7461 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
7462 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
7463 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
7464 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
7465 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
7466 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
7467 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
7468 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
7469 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
7470 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
7471 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
7472 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
7473 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
7474 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
7475 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
7476 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
7477 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
7478 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
7479 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
7480 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
7481 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
7482 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
7483 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
7484 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
7485 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
7486 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
7487 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
7488 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
7489 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
7490 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
7491 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
7492 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
7493 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
7494 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
7495 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
7496 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
7497 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
7498 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
7499 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
7500 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
7501 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
7502 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
7503 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
7504 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
7505 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
7506 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
7507 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
7508 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
7509 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
7510 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
7511 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
7512 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
7513 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
7514 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
7515 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
7517 { 0, CODE_FOR_divv2sf3
, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3
},
7518 { 0, CODE_FOR_addv2sf3
, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3
},
7519 { 0, CODE_FOR_subv2sf3
, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3
},
7520 { 0, CODE_FOR_mulv2sf3
, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3
},
7521 { 0, CODE_FOR_paired_muls0
, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0
},
7522 { 0, CODE_FOR_paired_muls1
, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1
},
7523 { 0, CODE_FOR_paired_merge00
, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00
},
7524 { 0, CODE_FOR_paired_merge01
, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01
},
7525 { 0, CODE_FOR_paired_merge10
, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10
},
7526 { 0, CODE_FOR_paired_merge11
, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11
},
7528 /* Place holder, leave as first spe builtin. */
7529 { 0, CODE_FOR_spe_evaddw
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
7530 { 0, CODE_FOR_spe_evand
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
7531 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
7532 { 0, CODE_FOR_spe_evdivws
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
7533 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
7534 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
7535 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
7536 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
7537 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
7538 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
7539 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
7540 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
7541 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
7542 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
7543 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
7544 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
7545 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
7546 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
7547 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
7548 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
7549 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
7550 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
7551 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
7552 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
7553 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
7554 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
7555 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
7556 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
7557 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
7558 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
7559 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
7560 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
7561 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
7562 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
7563 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
7564 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
7565 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
7566 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
7567 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
7568 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
7569 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
7570 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
7571 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
7572 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
7573 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
7574 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
7575 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
7576 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
7577 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
7578 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
7579 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
7580 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
7581 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
7582 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
7583 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
7584 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
7585 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
7586 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
7587 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
7588 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
7589 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
7590 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
7591 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
7592 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
7593 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
7594 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
7595 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
7596 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
7597 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
7598 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
7599 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
7600 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
7601 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
7602 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
7603 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
7604 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
7605 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
7606 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
7607 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
7608 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
7609 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
7610 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
7611 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
7612 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
7613 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
7614 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
7615 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
7616 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
7617 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
7618 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
7619 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
7620 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
7621 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
7622 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
7623 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
7624 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
7625 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
7626 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
7627 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
7628 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
7629 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
7630 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
7631 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
7632 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
7633 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
7634 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
7635 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
7636 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
7637 { 0, CODE_FOR_spe_evsubfw
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
7639 /* SPE binary operations expecting a 5-bit unsigned literal. */
7640 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
7642 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
7643 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
7644 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
7645 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
7646 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
7647 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
7648 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
7649 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
7650 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
7651 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
7652 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
7653 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
7654 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
7655 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
7656 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
7657 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
7658 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
7659 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
7660 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
7661 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
7662 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
7663 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
7664 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
7665 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
7666 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
7667 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
7669 /* Place-holder. Leave as last binary SPE builtin. */
7670 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
7673 /* AltiVec predicates. */
7675 struct builtin_description_predicates
7677 const unsigned int mask
;
7678 const enum insn_code icode
;
7680 const char *const name
;
7681 const enum rs6000_builtins code
;
7684 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
7686 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P
},
7687 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
7688 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
7689 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
7690 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P
},
7691 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P
},
7692 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P
},
7693 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P
},
7694 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P
},
7695 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P
},
7696 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P
},
7697 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P
},
7698 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P
},
7700 { MASK_ALTIVEC
, CODE_FOR_nothing
, NULL
, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P
},
7701 { MASK_ALTIVEC
, CODE_FOR_nothing
, NULL
, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P
},
7702 { MASK_ALTIVEC
, CODE_FOR_nothing
, NULL
, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P
}
7705 /* SPE predicates. */
7706 static struct builtin_description bdesc_spe_predicates
[] =
7708 /* Place-holder. Leave as first. */
7709 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
7710 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
7711 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
7712 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
7713 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
7714 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
7715 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
7716 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
7717 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
7718 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
7719 /* Place-holder. Leave as last. */
7720 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
7723 /* SPE evsel predicates. */
7724 static struct builtin_description bdesc_spe_evsel
[] =
7726 /* Place-holder. Leave as first. */
7727 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
7728 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
7729 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
7730 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
7731 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
7732 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
7733 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
7734 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
7735 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
7736 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
7737 /* Place-holder. Leave as last. */
7738 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
7741 /* PAIRED predicates. */
7742 static const struct builtin_description bdesc_paired_preds
[] =
7744 /* Place-holder. Leave as first. */
7745 { 0, CODE_FOR_paired_cmpu0
, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0
},
7746 /* Place-holder. Leave as last. */
7747 { 0, CODE_FOR_paired_cmpu1
, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1
},
7750 /* ABS* operations. */
7752 static const struct builtin_description bdesc_abs
[] =
7754 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
7755 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
7756 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
7757 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
7758 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
7759 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
7760 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
}
7763 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
7766 static struct builtin_description bdesc_1arg
[] =
7768 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
7769 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
7770 { MASK_ALTIVEC
, CODE_FOR_altivec_vrefp
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
7771 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfim
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
7772 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
7773 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfip
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
7774 { MASK_ALTIVEC
, CODE_FOR_ftruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
7775 { MASK_ALTIVEC
, CODE_FOR_altivec_vrsqrtefp
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
7776 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
7777 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
7778 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
7779 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
7780 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
7781 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
7782 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
7783 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
7784 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
7786 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
7787 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
7788 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
7789 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
7790 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
7791 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
7792 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
7793 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
7794 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
7795 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
7796 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
7797 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
7798 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
7799 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
7800 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
7801 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
7802 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
7803 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
7804 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
7806 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
7807 end with SPE_BUILTIN_EVSUBFUSIAAW. */
7808 { 0, CODE_FOR_spe_evabs
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
7809 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
7810 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
7811 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
7812 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
7813 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
7814 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
7815 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
7816 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
7817 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
7818 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
7819 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
7820 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
7821 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
7822 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
7823 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
7824 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
7825 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
7826 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
7827 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
7828 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
7829 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
7830 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
7831 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
7832 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
7833 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
7834 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
7835 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
7837 /* Place-holder. Leave as last unary SPE builtin. */
7838 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
},
7840 { 0, CODE_FOR_absv2sf2
, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2
},
7841 { 0, CODE_FOR_nabsv2sf2
, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2
},
7842 { 0, CODE_FOR_negv2sf2
, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2
},
7843 { 0, CODE_FOR_sqrtv2sf2
, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2
},
7844 { 0, CODE_FOR_resv2sf2
, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2
}
7848 rs6000_expand_unop_builtin (enum insn_code icode
, tree exp
, rtx target
)
7851 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7852 rtx op0
= expand_normal (arg0
);
7853 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7854 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7856 if (icode
== CODE_FOR_nothing
)
7857 /* Builtin not supported on this processor. */
7860 /* If we got invalid arguments bail out before generating bad rtl. */
7861 if (arg0
== error_mark_node
)
7864 if (icode
== CODE_FOR_altivec_vspltisb
7865 || icode
== CODE_FOR_altivec_vspltish
7866 || icode
== CODE_FOR_altivec_vspltisw
7867 || icode
== CODE_FOR_spe_evsplatfi
7868 || icode
== CODE_FOR_spe_evsplati
)
7870 /* Only allow 5-bit *signed* literals. */
7871 if (GET_CODE (op0
) != CONST_INT
7872 || INTVAL (op0
) > 15
7873 || INTVAL (op0
) < -16)
7875 error ("argument 1 must be a 5-bit signed literal");
7881 || GET_MODE (target
) != tmode
7882 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7883 target
= gen_reg_rtx (tmode
);
7885 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7886 op0
= copy_to_mode_reg (mode0
, op0
);
7888 pat
= GEN_FCN (icode
) (target
, op0
);
7897 altivec_expand_abs_builtin (enum insn_code icode
, tree exp
, rtx target
)
7899 rtx pat
, scratch1
, scratch2
;
7900 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7901 rtx op0
= expand_normal (arg0
);
7902 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7903 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7905 /* If we have invalid arguments, bail out before generating bad rtl. */
7906 if (arg0
== error_mark_node
)
7910 || GET_MODE (target
) != tmode
7911 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7912 target
= gen_reg_rtx (tmode
);
7914 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7915 op0
= copy_to_mode_reg (mode0
, op0
);
7917 scratch1
= gen_reg_rtx (mode0
);
7918 scratch2
= gen_reg_rtx (mode0
);
7920 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
7929 rs6000_expand_binop_builtin (enum insn_code icode
, tree exp
, rtx target
)
7932 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7933 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7934 rtx op0
= expand_normal (arg0
);
7935 rtx op1
= expand_normal (arg1
);
7936 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7937 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7938 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7940 if (icode
== CODE_FOR_nothing
)
7941 /* Builtin not supported on this processor. */
7944 /* If we got invalid arguments bail out before generating bad rtl. */
7945 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7948 if (icode
== CODE_FOR_altivec_vcfux
7949 || icode
== CODE_FOR_altivec_vcfsx
7950 || icode
== CODE_FOR_altivec_vctsxs
7951 || icode
== CODE_FOR_altivec_vctuxs
7952 || icode
== CODE_FOR_altivec_vspltb
7953 || icode
== CODE_FOR_altivec_vsplth
7954 || icode
== CODE_FOR_altivec_vspltw
7955 || icode
== CODE_FOR_spe_evaddiw
7956 || icode
== CODE_FOR_spe_evldd
7957 || icode
== CODE_FOR_spe_evldh
7958 || icode
== CODE_FOR_spe_evldw
7959 || icode
== CODE_FOR_spe_evlhhesplat
7960 || icode
== CODE_FOR_spe_evlhhossplat
7961 || icode
== CODE_FOR_spe_evlhhousplat
7962 || icode
== CODE_FOR_spe_evlwhe
7963 || icode
== CODE_FOR_spe_evlwhos
7964 || icode
== CODE_FOR_spe_evlwhou
7965 || icode
== CODE_FOR_spe_evlwhsplat
7966 || icode
== CODE_FOR_spe_evlwwsplat
7967 || icode
== CODE_FOR_spe_evrlwi
7968 || icode
== CODE_FOR_spe_evslwi
7969 || icode
== CODE_FOR_spe_evsrwis
7970 || icode
== CODE_FOR_spe_evsubifw
7971 || icode
== CODE_FOR_spe_evsrwiu
)
7973 /* Only allow 5-bit unsigned literals. */
7975 if (TREE_CODE (arg1
) != INTEGER_CST
7976 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
7978 error ("argument 2 must be a 5-bit unsigned literal");
7984 || GET_MODE (target
) != tmode
7985 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7986 target
= gen_reg_rtx (tmode
);
7988 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7989 op0
= copy_to_mode_reg (mode0
, op0
);
7990 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7991 op1
= copy_to_mode_reg (mode1
, op1
);
7993 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
8002 altivec_expand_predicate_builtin (enum insn_code icode
, const char *opcode
,
8003 tree exp
, rtx target
)
8006 tree cr6_form
= CALL_EXPR_ARG (exp
, 0);
8007 tree arg0
= CALL_EXPR_ARG (exp
, 1);
8008 tree arg1
= CALL_EXPR_ARG (exp
, 2);
8009 rtx op0
= expand_normal (arg0
);
8010 rtx op1
= expand_normal (arg1
);
8011 enum machine_mode tmode
= SImode
;
8012 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8013 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8016 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
8018 error ("argument 1 of __builtin_altivec_predicate must be a constant");
8022 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
8024 gcc_assert (mode0
== mode1
);
8026 /* If we have invalid arguments, bail out before generating bad rtl. */
8027 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
8031 || GET_MODE (target
) != tmode
8032 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8033 target
= gen_reg_rtx (tmode
);
8035 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8036 op0
= copy_to_mode_reg (mode0
, op0
);
8037 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
8038 op1
= copy_to_mode_reg (mode1
, op1
);
8040 scratch
= gen_reg_rtx (mode0
);
8042 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
,
8043 gen_rtx_SYMBOL_REF (Pmode
, opcode
));
8048 /* The vec_any* and vec_all* predicates use the same opcodes for two
8049 different operations, but the bits in CR6 will be different
8050 depending on what information we want. So we have to play tricks
8051 with CR6 to get the right bits out.
8053 If you think this is disgusting, look at the specs for the
8054 AltiVec predicates. */
8056 switch (cr6_form_int
)
8059 emit_insn (gen_cr6_test_for_zero (target
));
8062 emit_insn (gen_cr6_test_for_zero_reverse (target
));
8065 emit_insn (gen_cr6_test_for_lt (target
));
8068 emit_insn (gen_cr6_test_for_lt_reverse (target
));
8071 error ("argument 1 of __builtin_altivec_predicate is out of range");
8079 paired_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
)
8082 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8083 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8084 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8085 enum machine_mode mode0
= Pmode
;
8086 enum machine_mode mode1
= Pmode
;
8087 rtx op0
= expand_normal (arg0
);
8088 rtx op1
= expand_normal (arg1
);
8090 if (icode
== CODE_FOR_nothing
)
8091 /* Builtin not supported on this processor. */
8094 /* If we got invalid arguments bail out before generating bad rtl. */
8095 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
8099 || GET_MODE (target
) != tmode
8100 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8101 target
= gen_reg_rtx (tmode
);
8103 op1
= copy_to_mode_reg (mode1
, op1
);
8105 if (op0
== const0_rtx
)
8107 addr
= gen_rtx_MEM (tmode
, op1
);
8111 op0
= copy_to_mode_reg (mode0
, op0
);
8112 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
8115 pat
= GEN_FCN (icode
) (target
, addr
);
8125 altivec_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
, bool blk
)
8128 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8129 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8130 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8131 enum machine_mode mode0
= Pmode
;
8132 enum machine_mode mode1
= Pmode
;
8133 rtx op0
= expand_normal (arg0
);
8134 rtx op1
= expand_normal (arg1
);
8136 if (icode
== CODE_FOR_nothing
)
8137 /* Builtin not supported on this processor. */
8140 /* If we got invalid arguments bail out before generating bad rtl. */
8141 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
8145 || GET_MODE (target
) != tmode
8146 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8147 target
= gen_reg_rtx (tmode
);
8149 op1
= copy_to_mode_reg (mode1
, op1
);
8151 if (op0
== const0_rtx
)
8153 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, op1
);
8157 op0
= copy_to_mode_reg (mode0
, op0
);
8158 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
8161 pat
= GEN_FCN (icode
) (target
, addr
);
8171 spe_expand_stv_builtin (enum insn_code icode
, tree exp
)
8173 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8174 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8175 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8176 rtx op0
= expand_normal (arg0
);
8177 rtx op1
= expand_normal (arg1
);
8178 rtx op2
= expand_normal (arg2
);
8180 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
8181 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
8182 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
8184 /* Invalid arguments. Bail before doing anything stoopid! */
8185 if (arg0
== error_mark_node
8186 || arg1
== error_mark_node
8187 || arg2
== error_mark_node
)
8190 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
8191 op0
= copy_to_mode_reg (mode2
, op0
);
8192 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
8193 op1
= copy_to_mode_reg (mode0
, op1
);
8194 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
8195 op2
= copy_to_mode_reg (mode1
, op2
);
8197 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
8204 paired_expand_stv_builtin (enum insn_code icode
, tree exp
)
8206 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8207 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8208 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8209 rtx op0
= expand_normal (arg0
);
8210 rtx op1
= expand_normal (arg1
);
8211 rtx op2
= expand_normal (arg2
);
8213 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8214 enum machine_mode mode1
= Pmode
;
8215 enum machine_mode mode2
= Pmode
;
8217 /* Invalid arguments. Bail before doing anything stoopid! */
8218 if (arg0
== error_mark_node
8219 || arg1
== error_mark_node
8220 || arg2
== error_mark_node
)
8223 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
8224 op0
= copy_to_mode_reg (tmode
, op0
);
8226 op2
= copy_to_mode_reg (mode2
, op2
);
8228 if (op1
== const0_rtx
)
8230 addr
= gen_rtx_MEM (tmode
, op2
);
8234 op1
= copy_to_mode_reg (mode1
, op1
);
8235 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
8238 pat
= GEN_FCN (icode
) (addr
, op0
);
8245 altivec_expand_stv_builtin (enum insn_code icode
, tree exp
)
8247 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8248 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8249 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8250 rtx op0
= expand_normal (arg0
);
8251 rtx op1
= expand_normal (arg1
);
8252 rtx op2
= expand_normal (arg2
);
8254 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8255 enum machine_mode mode1
= Pmode
;
8256 enum machine_mode mode2
= Pmode
;
8258 /* Invalid arguments. Bail before doing anything stoopid! */
8259 if (arg0
== error_mark_node
8260 || arg1
== error_mark_node
8261 || arg2
== error_mark_node
)
8264 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
8265 op0
= copy_to_mode_reg (tmode
, op0
);
8267 op2
= copy_to_mode_reg (mode2
, op2
);
8269 if (op1
== const0_rtx
)
8271 addr
= gen_rtx_MEM (tmode
, op2
);
8275 op1
= copy_to_mode_reg (mode1
, op1
);
8276 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
8279 pat
= GEN_FCN (icode
) (addr
, op0
);
8286 rs6000_expand_ternop_builtin (enum insn_code icode
, tree exp
, rtx target
)
8289 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8290 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8291 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8292 rtx op0
= expand_normal (arg0
);
8293 rtx op1
= expand_normal (arg1
);
8294 rtx op2
= expand_normal (arg2
);
8295 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8296 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8297 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8298 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
8300 if (icode
== CODE_FOR_nothing
)
8301 /* Builtin not supported on this processor. */
8304 /* If we got invalid arguments bail out before generating bad rtl. */
8305 if (arg0
== error_mark_node
8306 || arg1
== error_mark_node
8307 || arg2
== error_mark_node
)
8310 if (icode
== CODE_FOR_altivec_vsldoi_v4sf
8311 || icode
== CODE_FOR_altivec_vsldoi_v4si
8312 || icode
== CODE_FOR_altivec_vsldoi_v8hi
8313 || icode
== CODE_FOR_altivec_vsldoi_v16qi
)
8315 /* Only allow 4-bit unsigned literals. */
8317 if (TREE_CODE (arg2
) != INTEGER_CST
8318 || TREE_INT_CST_LOW (arg2
) & ~0xf)
8320 error ("argument 3 must be a 4-bit unsigned literal");
8326 || GET_MODE (target
) != tmode
8327 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8328 target
= gen_reg_rtx (tmode
);
8330 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8331 op0
= copy_to_mode_reg (mode0
, op0
);
8332 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
8333 op1
= copy_to_mode_reg (mode1
, op1
);
8334 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
8335 op2
= copy_to_mode_reg (mode2
, op2
);
8337 if (TARGET_PAIRED_FLOAT
&& icode
== CODE_FOR_selv2sf4
)
8338 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
, CONST0_RTX (SFmode
));
8340 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
8348 /* Expand the lvx builtins. */
8350 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
8352 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8353 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8355 enum machine_mode tmode
, mode0
;
8357 enum insn_code icode
;
8361 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
8362 icode
= CODE_FOR_altivec_lvx_v16qi
;
8364 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
8365 icode
= CODE_FOR_altivec_lvx_v8hi
;
8367 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
8368 icode
= CODE_FOR_altivec_lvx_v4si
;
8370 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
8371 icode
= CODE_FOR_altivec_lvx_v4sf
;
8380 arg0
= CALL_EXPR_ARG (exp
, 0);
8381 op0
= expand_normal (arg0
);
8382 tmode
= insn_data
[icode
].operand
[0].mode
;
8383 mode0
= insn_data
[icode
].operand
[1].mode
;
8386 || GET_MODE (target
) != tmode
8387 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8388 target
= gen_reg_rtx (tmode
);
8390 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8391 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
8393 pat
= GEN_FCN (icode
) (target
, op0
);
8400 /* Expand the stvx builtins. */
8402 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
8405 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8406 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8408 enum machine_mode mode0
, mode1
;
8410 enum insn_code icode
;
8414 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
8415 icode
= CODE_FOR_altivec_stvx_v16qi
;
8417 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
8418 icode
= CODE_FOR_altivec_stvx_v8hi
;
8420 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
8421 icode
= CODE_FOR_altivec_stvx_v4si
;
8423 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
8424 icode
= CODE_FOR_altivec_stvx_v4sf
;
8431 arg0
= CALL_EXPR_ARG (exp
, 0);
8432 arg1
= CALL_EXPR_ARG (exp
, 1);
8433 op0
= expand_normal (arg0
);
8434 op1
= expand_normal (arg1
);
8435 mode0
= insn_data
[icode
].operand
[0].mode
;
8436 mode1
= insn_data
[icode
].operand
[1].mode
;
8438 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8439 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
8440 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
8441 op1
= copy_to_mode_reg (mode1
, op1
);
8443 pat
= GEN_FCN (icode
) (op0
, op1
);
8451 /* Expand the dst builtins. */
8453 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
8456 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8457 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8458 tree arg0
, arg1
, arg2
;
8459 enum machine_mode mode0
, mode1
, mode2
;
8460 rtx pat
, op0
, op1
, op2
;
8461 const struct builtin_description
*d
;
8466 /* Handle DST variants. */
8468 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
8469 if (d
->code
== fcode
)
8471 arg0
= CALL_EXPR_ARG (exp
, 0);
8472 arg1
= CALL_EXPR_ARG (exp
, 1);
8473 arg2
= CALL_EXPR_ARG (exp
, 2);
8474 op0
= expand_normal (arg0
);
8475 op1
= expand_normal (arg1
);
8476 op2
= expand_normal (arg2
);
8477 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8478 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
8479 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
8481 /* Invalid arguments, bail out before generating bad rtl. */
8482 if (arg0
== error_mark_node
8483 || arg1
== error_mark_node
8484 || arg2
== error_mark_node
)
8489 if (TREE_CODE (arg2
) != INTEGER_CST
8490 || TREE_INT_CST_LOW (arg2
) & ~0x3)
8492 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
8496 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
8497 op0
= copy_to_mode_reg (Pmode
, op0
);
8498 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
8499 op1
= copy_to_mode_reg (mode1
, op1
);
8501 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
8511 /* Expand vec_init builtin. */
8513 altivec_expand_vec_init_builtin (tree type
, tree exp
, rtx target
)
8515 enum machine_mode tmode
= TYPE_MODE (type
);
8516 enum machine_mode inner_mode
= GET_MODE_INNER (tmode
);
8517 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
8518 rtvec v
= rtvec_alloc (n_elt
);
8520 gcc_assert (VECTOR_MODE_P (tmode
));
8521 gcc_assert (n_elt
== call_expr_nargs (exp
));
8523 for (i
= 0; i
< n_elt
; ++i
)
8525 rtx x
= expand_normal (CALL_EXPR_ARG (exp
, i
));
8526 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
8529 if (!target
|| !register_operand (target
, tmode
))
8530 target
= gen_reg_rtx (tmode
);
8532 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
8536 /* Return the integer constant in ARG. Constrain it to be in the range
8537 of the subparts of VEC_TYPE; issue an error if not. */
8540 get_element_number (tree vec_type
, tree arg
)
8542 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
8544 if (!host_integerp (arg
, 1)
8545 || (elt
= tree_low_cst (arg
, 1), elt
> max
))
8547 error ("selector must be an integer constant in the range 0..%wi", max
);
8554 /* Expand vec_set builtin. */
8556 altivec_expand_vec_set_builtin (tree exp
)
8558 enum machine_mode tmode
, mode1
;
8559 tree arg0
, arg1
, arg2
;
8563 arg0
= CALL_EXPR_ARG (exp
, 0);
8564 arg1
= CALL_EXPR_ARG (exp
, 1);
8565 arg2
= CALL_EXPR_ARG (exp
, 2);
8567 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
8568 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
8569 gcc_assert (VECTOR_MODE_P (tmode
));
8571 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, EXPAND_NORMAL
);
8572 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, EXPAND_NORMAL
);
8573 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
8575 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
8576 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
8578 op0
= force_reg (tmode
, op0
);
8579 op1
= force_reg (mode1
, op1
);
8581 rs6000_expand_vector_set (op0
, op1
, elt
);
8586 /* Expand vec_ext builtin. */
8588 altivec_expand_vec_ext_builtin (tree exp
, rtx target
)
8590 enum machine_mode tmode
, mode0
;
8595 arg0
= CALL_EXPR_ARG (exp
, 0);
8596 arg1
= CALL_EXPR_ARG (exp
, 1);
8598 op0
= expand_normal (arg0
);
8599 elt
= get_element_number (TREE_TYPE (arg0
), arg1
);
8601 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
8602 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
8603 gcc_assert (VECTOR_MODE_P (mode0
));
8605 op0
= force_reg (mode0
, op0
);
8607 if (optimize
|| !target
|| !register_operand (target
, tmode
))
8608 target
= gen_reg_rtx (tmode
);
8610 rs6000_expand_vector_extract (target
, op0
, elt
);
8615 /* Expand the builtin in EXP and store the result in TARGET. Store
8616 true in *EXPANDEDP if we found a builtin to expand. */
8618 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
8620 const struct builtin_description
*d
;
8621 const struct builtin_description_predicates
*dp
;
8623 enum insn_code icode
;
8624 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8627 enum machine_mode tmode
, mode0
;
8628 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8630 if (fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8631 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
8634 error ("unresolved overload for Altivec builtin %qF", fndecl
);
8638 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
8642 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
8646 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
8654 case ALTIVEC_BUILTIN_STVX
:
8655 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx
, exp
);
8656 case ALTIVEC_BUILTIN_STVEBX
:
8657 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, exp
);
8658 case ALTIVEC_BUILTIN_STVEHX
:
8659 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, exp
);
8660 case ALTIVEC_BUILTIN_STVEWX
:
8661 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, exp
);
8662 case ALTIVEC_BUILTIN_STVXL
:
8663 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, exp
);
8665 case ALTIVEC_BUILTIN_STVLX
:
8666 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx
, exp
);
8667 case ALTIVEC_BUILTIN_STVLXL
:
8668 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl
, exp
);
8669 case ALTIVEC_BUILTIN_STVRX
:
8670 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx
, exp
);
8671 case ALTIVEC_BUILTIN_STVRXL
:
8672 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl
, exp
);
8674 case ALTIVEC_BUILTIN_MFVSCR
:
8675 icode
= CODE_FOR_altivec_mfvscr
;
8676 tmode
= insn_data
[icode
].operand
[0].mode
;
8679 || GET_MODE (target
) != tmode
8680 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8681 target
= gen_reg_rtx (tmode
);
8683 pat
= GEN_FCN (icode
) (target
);
8689 case ALTIVEC_BUILTIN_MTVSCR
:
8690 icode
= CODE_FOR_altivec_mtvscr
;
8691 arg0
= CALL_EXPR_ARG (exp
, 0);
8692 op0
= expand_normal (arg0
);
8693 mode0
= insn_data
[icode
].operand
[0].mode
;
8695 /* If we got invalid arguments bail out before generating bad rtl. */
8696 if (arg0
== error_mark_node
)
8699 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8700 op0
= copy_to_mode_reg (mode0
, op0
);
8702 pat
= GEN_FCN (icode
) (op0
);
8707 case ALTIVEC_BUILTIN_DSSALL
:
8708 emit_insn (gen_altivec_dssall ());
8711 case ALTIVEC_BUILTIN_DSS
:
8712 icode
= CODE_FOR_altivec_dss
;
8713 arg0
= CALL_EXPR_ARG (exp
, 0);
8715 op0
= expand_normal (arg0
);
8716 mode0
= insn_data
[icode
].operand
[0].mode
;
8718 /* If we got invalid arguments bail out before generating bad rtl. */
8719 if (arg0
== error_mark_node
)
8722 if (TREE_CODE (arg0
) != INTEGER_CST
8723 || TREE_INT_CST_LOW (arg0
) & ~0x3)
8725 error ("argument to dss must be a 2-bit unsigned literal");
8729 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8730 op0
= copy_to_mode_reg (mode0
, op0
);
8732 emit_insn (gen_altivec_dss (op0
));
8735 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
8736 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
8737 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
8738 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
8739 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), exp
, target
);
8741 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
8742 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
8743 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
8744 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
8745 return altivec_expand_vec_set_builtin (exp
);
8747 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
8748 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
8749 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
8750 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
8751 return altivec_expand_vec_ext_builtin (exp
, target
);
8758 /* Expand abs* operations. */
8760 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
8761 if (d
->code
== fcode
)
8762 return altivec_expand_abs_builtin (d
->icode
, exp
, target
);
8764 /* Expand the AltiVec predicates. */
8765 dp
= bdesc_altivec_preds
;
8766 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
8767 if (dp
->code
== fcode
)
8768 return altivec_expand_predicate_builtin (dp
->icode
, dp
->opcode
,
8771 /* LV* are funky. We initialized them differently. */
8774 case ALTIVEC_BUILTIN_LVSL
:
8775 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
8776 exp
, target
, false);
8777 case ALTIVEC_BUILTIN_LVSR
:
8778 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
8779 exp
, target
, false);
8780 case ALTIVEC_BUILTIN_LVEBX
:
8781 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
8782 exp
, target
, false);
8783 case ALTIVEC_BUILTIN_LVEHX
:
8784 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
8785 exp
, target
, false);
8786 case ALTIVEC_BUILTIN_LVEWX
:
8787 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
8788 exp
, target
, false);
8789 case ALTIVEC_BUILTIN_LVXL
:
8790 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
8791 exp
, target
, false);
8792 case ALTIVEC_BUILTIN_LVX
:
8793 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx
,
8794 exp
, target
, false);
8795 case ALTIVEC_BUILTIN_LVLX
:
8796 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx
,
8798 case ALTIVEC_BUILTIN_LVLXL
:
8799 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl
,
8801 case ALTIVEC_BUILTIN_LVRX
:
8802 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx
,
8804 case ALTIVEC_BUILTIN_LVRXL
:
8805 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl
,
8816 /* Expand the builtin in EXP and store the result in TARGET. Store
8817 true in *EXPANDEDP if we found a builtin to expand. */
8819 paired_expand_builtin (tree exp
, rtx target
, bool * expandedp
)
8821 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8822 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8823 const struct builtin_description
*d
;
8830 case PAIRED_BUILTIN_STX
:
8831 return paired_expand_stv_builtin (CODE_FOR_paired_stx
, exp
);
8832 case PAIRED_BUILTIN_LX
:
8833 return paired_expand_lv_builtin (CODE_FOR_paired_lx
, exp
, target
);
8839 /* Expand the paired predicates. */
8840 d
= bdesc_paired_preds
;
8841 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); i
++, d
++)
8842 if (d
->code
== fcode
)
8843 return paired_expand_predicate_builtin (d
->icode
, exp
, target
);
8849 /* Binops that need to be initialized manually, but can be expanded
8850 automagically by rs6000_expand_binop_builtin. */
8851 static struct builtin_description bdesc_2arg_spe
[] =
8853 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
8854 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
8855 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
8856 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
8857 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
8858 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
8859 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
8860 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
8861 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
8862 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
8863 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
8864 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
8865 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
8866 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
8867 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
8868 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
8869 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
8870 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
8871 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
8872 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
8873 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
8874 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
8877 /* Expand the builtin in EXP and store the result in TARGET. Store
8878 true in *EXPANDEDP if we found a builtin to expand.
8880 This expands the SPE builtins that are not simple unary and binary
8883 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
8885 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8887 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8888 enum insn_code icode
;
8889 enum machine_mode tmode
, mode0
;
8891 struct builtin_description
*d
;
8896 /* Syntax check for a 5-bit unsigned immediate. */
8899 case SPE_BUILTIN_EVSTDD
:
8900 case SPE_BUILTIN_EVSTDH
:
8901 case SPE_BUILTIN_EVSTDW
:
8902 case SPE_BUILTIN_EVSTWHE
:
8903 case SPE_BUILTIN_EVSTWHO
:
8904 case SPE_BUILTIN_EVSTWWE
:
8905 case SPE_BUILTIN_EVSTWWO
:
8906 arg1
= CALL_EXPR_ARG (exp
, 2);
8907 if (TREE_CODE (arg1
) != INTEGER_CST
8908 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
8910 error ("argument 2 must be a 5-bit unsigned literal");
8918 /* The evsplat*i instructions are not quite generic. */
8921 case SPE_BUILTIN_EVSPLATFI
:
8922 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
8924 case SPE_BUILTIN_EVSPLATI
:
8925 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
8931 d
= (struct builtin_description
*) bdesc_2arg_spe
;
8932 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
8933 if (d
->code
== fcode
)
8934 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
8936 d
= (struct builtin_description
*) bdesc_spe_predicates
;
8937 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
8938 if (d
->code
== fcode
)
8939 return spe_expand_predicate_builtin (d
->icode
, exp
, target
);
8941 d
= (struct builtin_description
*) bdesc_spe_evsel
;
8942 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
8943 if (d
->code
== fcode
)
8944 return spe_expand_evsel_builtin (d
->icode
, exp
, target
);
8948 case SPE_BUILTIN_EVSTDDX
:
8949 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, exp
);
8950 case SPE_BUILTIN_EVSTDHX
:
8951 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, exp
);
8952 case SPE_BUILTIN_EVSTDWX
:
8953 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, exp
);
8954 case SPE_BUILTIN_EVSTWHEX
:
8955 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, exp
);
8956 case SPE_BUILTIN_EVSTWHOX
:
8957 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, exp
);
8958 case SPE_BUILTIN_EVSTWWEX
:
8959 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, exp
);
8960 case SPE_BUILTIN_EVSTWWOX
:
8961 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, exp
);
8962 case SPE_BUILTIN_EVSTDD
:
8963 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, exp
);
8964 case SPE_BUILTIN_EVSTDH
:
8965 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, exp
);
8966 case SPE_BUILTIN_EVSTDW
:
8967 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, exp
);
8968 case SPE_BUILTIN_EVSTWHE
:
8969 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, exp
);
8970 case SPE_BUILTIN_EVSTWHO
:
8971 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, exp
);
8972 case SPE_BUILTIN_EVSTWWE
:
8973 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, exp
);
8974 case SPE_BUILTIN_EVSTWWO
:
8975 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, exp
);
8976 case SPE_BUILTIN_MFSPEFSCR
:
8977 icode
= CODE_FOR_spe_mfspefscr
;
8978 tmode
= insn_data
[icode
].operand
[0].mode
;
8981 || GET_MODE (target
) != tmode
8982 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8983 target
= gen_reg_rtx (tmode
);
8985 pat
= GEN_FCN (icode
) (target
);
8990 case SPE_BUILTIN_MTSPEFSCR
:
8991 icode
= CODE_FOR_spe_mtspefscr
;
8992 arg0
= CALL_EXPR_ARG (exp
, 0);
8993 op0
= expand_normal (arg0
);
8994 mode0
= insn_data
[icode
].operand
[0].mode
;
8996 if (arg0
== error_mark_node
)
8999 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
9000 op0
= copy_to_mode_reg (mode0
, op0
);
9002 pat
= GEN_FCN (icode
) (op0
);
9015 paired_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
9017 rtx pat
, scratch
, tmp
;
9018 tree form
= CALL_EXPR_ARG (exp
, 0);
9019 tree arg0
= CALL_EXPR_ARG (exp
, 1);
9020 tree arg1
= CALL_EXPR_ARG (exp
, 2);
9021 rtx op0
= expand_normal (arg0
);
9022 rtx op1
= expand_normal (arg1
);
9023 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
9024 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
9028 if (TREE_CODE (form
) != INTEGER_CST
)
9030 error ("argument 1 of __builtin_paired_predicate must be a constant");
9034 form_int
= TREE_INT_CST_LOW (form
);
9036 gcc_assert (mode0
== mode1
);
9038 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
9042 || GET_MODE (target
) != SImode
9043 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
9044 target
= gen_reg_rtx (SImode
);
9045 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
9046 op0
= copy_to_mode_reg (mode0
, op0
);
9047 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
9048 op1
= copy_to_mode_reg (mode1
, op1
);
9050 scratch
= gen_reg_rtx (CCFPmode
);
9052 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
9074 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
9077 error ("argument 1 of __builtin_paired_predicate is out of range");
9081 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
9082 emit_move_insn (target
, tmp
);
9087 spe_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
9089 rtx pat
, scratch
, tmp
;
9090 tree form
= CALL_EXPR_ARG (exp
, 0);
9091 tree arg0
= CALL_EXPR_ARG (exp
, 1);
9092 tree arg1
= CALL_EXPR_ARG (exp
, 2);
9093 rtx op0
= expand_normal (arg0
);
9094 rtx op1
= expand_normal (arg1
);
9095 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
9096 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
9100 if (TREE_CODE (form
) != INTEGER_CST
)
9102 error ("argument 1 of __builtin_spe_predicate must be a constant");
9106 form_int
= TREE_INT_CST_LOW (form
);
9108 gcc_assert (mode0
== mode1
);
9110 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
9114 || GET_MODE (target
) != SImode
9115 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
9116 target
= gen_reg_rtx (SImode
);
9118 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
9119 op0
= copy_to_mode_reg (mode0
, op0
);
9120 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
9121 op1
= copy_to_mode_reg (mode1
, op1
);
9123 scratch
= gen_reg_rtx (CCmode
);
9125 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
9130 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
9131 _lower_. We use one compare, but look in different bits of the
9132 CR for each variant.
9134 There are 2 elements in each SPE simd type (upper/lower). The CR
9135 bits are set as follows:
9137 BIT0 | BIT 1 | BIT 2 | BIT 3
9138 U | L | (U | L) | (U & L)
9140 So, for an "all" relationship, BIT 3 would be set.
9141 For an "any" relationship, BIT 2 would be set. Etc.
9143 Following traditional nomenclature, these bits map to:
9145 BIT0 | BIT 1 | BIT 2 | BIT 3
9148 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
9153 /* All variant. OV bit. */
9155 /* We need to get to the OV bit, which is the ORDERED bit. We
9156 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
9157 that's ugly and will make validate_condition_mode die.
9158 So let's just use another pattern. */
9159 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
9161 /* Any variant. EQ bit. */
9165 /* Upper variant. LT bit. */
9169 /* Lower variant. GT bit. */
9174 error ("argument 1 of __builtin_spe_predicate is out of range");
9178 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
9179 emit_move_insn (target
, tmp
);
9184 /* The evsel builtins look like this:
9186 e = __builtin_spe_evsel_OP (a, b, c, d);
9190 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
9191 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
9195 spe_expand_evsel_builtin (enum insn_code icode
, tree exp
, rtx target
)
9198 tree arg0
= CALL_EXPR_ARG (exp
, 0);
9199 tree arg1
= CALL_EXPR_ARG (exp
, 1);
9200 tree arg2
= CALL_EXPR_ARG (exp
, 2);
9201 tree arg3
= CALL_EXPR_ARG (exp
, 3);
9202 rtx op0
= expand_normal (arg0
);
9203 rtx op1
= expand_normal (arg1
);
9204 rtx op2
= expand_normal (arg2
);
9205 rtx op3
= expand_normal (arg3
);
9206 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
9207 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
9209 gcc_assert (mode0
== mode1
);
9211 if (arg0
== error_mark_node
|| arg1
== error_mark_node
9212 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
9216 || GET_MODE (target
) != mode0
9217 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
9218 target
= gen_reg_rtx (mode0
);
9220 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
9221 op0
= copy_to_mode_reg (mode0
, op0
);
9222 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
9223 op1
= copy_to_mode_reg (mode0
, op1
);
9224 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
9225 op2
= copy_to_mode_reg (mode0
, op2
);
9226 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
9227 op3
= copy_to_mode_reg (mode0
, op3
);
9229 /* Generate the compare. */
9230 scratch
= gen_reg_rtx (CCmode
);
9231 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
9236 if (mode0
== V2SImode
)
9237 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
9239 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
9244 /* Expand an expression EXP that calls a built-in function,
9245 with result going to TARGET if that's convenient
9246 (and in mode MODE if that's convenient).
9247 SUBTARGET may be used as the target for computing one of EXP's operands.
9248 IGNORE is nonzero if the value is to be ignored. */
9251 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
9252 enum machine_mode mode ATTRIBUTE_UNUSED
,
9253 int ignore ATTRIBUTE_UNUSED
)
9255 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
9256 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
9257 const struct builtin_description
*d
;
9262 if (fcode
== RS6000_BUILTIN_RECIP
)
9263 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3
, exp
, target
);
9265 if (fcode
== RS6000_BUILTIN_RECIPF
)
9266 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3
, exp
, target
);
9268 if (fcode
== RS6000_BUILTIN_RSQRTF
)
9269 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2
, exp
, target
);
9271 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_LOAD
9272 || fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
9274 int icode
= (int) CODE_FOR_altivec_lvsr
;
9275 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
9276 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
9280 gcc_assert (TARGET_ALTIVEC
);
9282 arg
= CALL_EXPR_ARG (exp
, 0);
9283 gcc_assert (TREE_CODE (TREE_TYPE (arg
)) == POINTER_TYPE
);
9284 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
9285 addr
= memory_address (mode
, op
);
9286 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
9290 /* For the load case need to negate the address. */
9291 op
= gen_reg_rtx (GET_MODE (addr
));
9292 emit_insn (gen_rtx_SET (VOIDmode
, op
,
9293 gen_rtx_NEG (GET_MODE (addr
), addr
)));
9295 op
= gen_rtx_MEM (mode
, op
);
9298 || GET_MODE (target
) != tmode
9299 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
9300 target
= gen_reg_rtx (tmode
);
9302 /*pat = gen_altivec_lvsr (target, op);*/
9303 pat
= GEN_FCN (icode
) (target
, op
);
9311 /* FIXME: There's got to be a nicer way to handle this case than
9312 constructing a new CALL_EXPR. */
9313 if (fcode
== ALTIVEC_BUILTIN_VCFUX
9314 || fcode
== ALTIVEC_BUILTIN_VCFSX
9315 || fcode
== ALTIVEC_BUILTIN_VCTUXS
9316 || fcode
== ALTIVEC_BUILTIN_VCTSXS
)
9318 if (call_expr_nargs (exp
) == 1)
9319 exp
= build_call_nary (TREE_TYPE (exp
), CALL_EXPR_FN (exp
),
9320 2, CALL_EXPR_ARG (exp
, 0), integer_zero_node
);
9325 ret
= altivec_expand_builtin (exp
, target
, &success
);
9332 ret
= spe_expand_builtin (exp
, target
, &success
);
9337 if (TARGET_PAIRED_FLOAT
)
9339 ret
= paired_expand_builtin (exp
, target
, &success
);
9345 gcc_assert (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
);
9347 /* Handle simple unary operations. */
9348 d
= (struct builtin_description
*) bdesc_1arg
;
9349 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
9350 if (d
->code
== fcode
)
9351 return rs6000_expand_unop_builtin (d
->icode
, exp
, target
);
9353 /* Handle simple binary operations. */
9354 d
= (struct builtin_description
*) bdesc_2arg
;
9355 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
9356 if (d
->code
== fcode
)
9357 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
9359 /* Handle simple ternary operations. */
9361 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
9362 if (d
->code
== fcode
)
9363 return rs6000_expand_ternop_builtin (d
->icode
, exp
, target
);
9369 rs6000_init_builtins (void)
9373 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
9374 V2SF_type_node
= build_vector_type (float_type_node
, 2);
9375 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
9376 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
9377 V4SF_type_node
= build_vector_type (float_type_node
, 4);
9378 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
9379 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
9381 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
9382 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
9383 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
9385 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
9386 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
9387 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
9388 opaque_V4SI_type_node
= build_opaque_vector_type (intSI_type_node
, 4);
9390 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
9391 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
9392 'vector unsigned short'. */
9394 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
9395 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
9396 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
9397 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
9399 long_integer_type_internal_node
= long_integer_type_node
;
9400 long_unsigned_type_internal_node
= long_unsigned_type_node
;
9401 intQI_type_internal_node
= intQI_type_node
;
9402 uintQI_type_internal_node
= unsigned_intQI_type_node
;
9403 intHI_type_internal_node
= intHI_type_node
;
9404 uintHI_type_internal_node
= unsigned_intHI_type_node
;
9405 intSI_type_internal_node
= intSI_type_node
;
9406 uintSI_type_internal_node
= unsigned_intSI_type_node
;
9407 float_type_internal_node
= float_type_node
;
9408 void_type_internal_node
= void_type_node
;
9410 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
9411 get_identifier ("__bool char"),
9412 bool_char_type_node
);
9413 TYPE_NAME (bool_char_type_node
) = tdecl
;
9414 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9415 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
9416 get_identifier ("__bool short"),
9417 bool_short_type_node
);
9418 TYPE_NAME (bool_short_type_node
) = tdecl
;
9419 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9420 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
9421 get_identifier ("__bool int"),
9422 bool_int_type_node
);
9423 TYPE_NAME (bool_int_type_node
) = tdecl
;
9424 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9425 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
, get_identifier ("__pixel"),
9427 TYPE_NAME (pixel_type_node
) = tdecl
;
9428 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9430 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
9431 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
9432 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
9433 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
9435 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
9436 get_identifier ("__vector unsigned char"),
9437 unsigned_V16QI_type_node
);
9438 TYPE_NAME (unsigned_V16QI_type_node
) = tdecl
;
9439 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9440 tdecl
= build_decl (BUILTINS_LOCATION
,
9441 TYPE_DECL
, get_identifier ("__vector signed char"),
9443 TYPE_NAME (V16QI_type_node
) = tdecl
;
9444 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9445 tdecl
= build_decl (BUILTINS_LOCATION
,
9446 TYPE_DECL
, get_identifier ("__vector __bool char"),
9447 bool_V16QI_type_node
);
9448 TYPE_NAME ( bool_V16QI_type_node
) = tdecl
;
9449 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9451 tdecl
= build_decl (BUILTINS_LOCATION
,
9452 TYPE_DECL
, get_identifier ("__vector unsigned short"),
9453 unsigned_V8HI_type_node
);
9454 TYPE_NAME (unsigned_V8HI_type_node
) = tdecl
;
9455 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9456 tdecl
= build_decl (BUILTINS_LOCATION
,
9457 TYPE_DECL
, get_identifier ("__vector signed short"),
9459 TYPE_NAME (V8HI_type_node
) = tdecl
;
9460 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9461 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
9462 get_identifier ("__vector __bool short"),
9463 bool_V8HI_type_node
);
9464 TYPE_NAME (bool_V8HI_type_node
) = tdecl
;
9465 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9467 tdecl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
9468 get_identifier ("__vector unsigned int"),
9469 unsigned_V4SI_type_node
);
9470 TYPE_NAME (unsigned_V4SI_type_node
) = tdecl
;
9471 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9472 tdecl
= build_decl (BUILTINS_LOCATION
,
9473 TYPE_DECL
, get_identifier ("__vector signed int"),
9475 TYPE_NAME (V4SI_type_node
) = tdecl
;
9476 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9477 tdecl
= build_decl (BUILTINS_LOCATION
,
9478 TYPE_DECL
, get_identifier ("__vector __bool int"),
9479 bool_V4SI_type_node
);
9480 TYPE_NAME (bool_V4SI_type_node
) = tdecl
;
9481 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9483 tdecl
= build_decl (BUILTINS_LOCATION
,
9484 TYPE_DECL
, get_identifier ("__vector float"),
9486 TYPE_NAME (V4SF_type_node
) = tdecl
;
9487 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9488 tdecl
= build_decl (BUILTINS_LOCATION
,
9489 TYPE_DECL
, get_identifier ("__vector __pixel"),
9490 pixel_V8HI_type_node
);
9491 TYPE_NAME (pixel_V8HI_type_node
) = tdecl
;
9492 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9494 if (TARGET_PAIRED_FLOAT
)
9495 paired_init_builtins ();
9497 spe_init_builtins ();
9499 altivec_init_builtins ();
9500 if (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
)
9501 rs6000_common_init_builtins ();
9502 if (TARGET_PPC_GFXOPT
)
9504 tree ftype
= build_function_type_list (float_type_node
,
9508 def_builtin (MASK_PPC_GFXOPT
, "__builtin_recipdivf", ftype
,
9509 RS6000_BUILTIN_RECIPF
);
9511 ftype
= build_function_type_list (float_type_node
,
9514 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrtf", ftype
,
9515 RS6000_BUILTIN_RSQRTF
);
9519 tree ftype
= build_function_type_list (double_type_node
,
9523 def_builtin (MASK_POPCNTB
, "__builtin_recipdiv", ftype
,
9524 RS6000_BUILTIN_RECIP
);
9529 /* AIX libm provides clog as __clog. */
9530 if (built_in_decls
[BUILT_IN_CLOG
])
9531 set_user_assembler_name (built_in_decls
[BUILT_IN_CLOG
], "__clog");
9534 #ifdef SUBTARGET_INIT_BUILTINS
9535 SUBTARGET_INIT_BUILTINS
;
9539 /* Search through a set of builtins and enable the mask bits.
9540 DESC is an array of builtins.
9541 SIZE is the total number of builtins.
9542 START is the builtin enum at which to start.
9543 END is the builtin enum at which to end. */
9545 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
9546 enum rs6000_builtins start
,
9547 enum rs6000_builtins end
)
9551 for (i
= 0; i
< size
; ++i
)
9552 if (desc
[i
].code
== start
)
9558 for (; i
< size
; ++i
)
9560 /* Flip all the bits on. */
9561 desc
[i
].mask
= target_flags
;
9562 if (desc
[i
].code
== end
)
9568 spe_init_builtins (void)
9570 tree endlink
= void_list_node
;
9571 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
9572 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
9573 struct builtin_description
*d
;
9576 tree v2si_ftype_4_v2si
9577 = build_function_type
9578 (opaque_V2SI_type_node
,
9579 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9580 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9581 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9582 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9585 tree v2sf_ftype_4_v2sf
9586 = build_function_type
9587 (opaque_V2SF_type_node
,
9588 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9589 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9590 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9591 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9594 tree int_ftype_int_v2si_v2si
9595 = build_function_type
9597 tree_cons (NULL_TREE
, integer_type_node
,
9598 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9599 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9602 tree int_ftype_int_v2sf_v2sf
9603 = build_function_type
9605 tree_cons (NULL_TREE
, integer_type_node
,
9606 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9607 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9610 tree void_ftype_v2si_puint_int
9611 = build_function_type (void_type_node
,
9612 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9613 tree_cons (NULL_TREE
, puint_type_node
,
9614 tree_cons (NULL_TREE
,
9618 tree void_ftype_v2si_puint_char
9619 = build_function_type (void_type_node
,
9620 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9621 tree_cons (NULL_TREE
, puint_type_node
,
9622 tree_cons (NULL_TREE
,
9626 tree void_ftype_v2si_pv2si_int
9627 = build_function_type (void_type_node
,
9628 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9629 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
9630 tree_cons (NULL_TREE
,
9634 tree void_ftype_v2si_pv2si_char
9635 = build_function_type (void_type_node
,
9636 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9637 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
9638 tree_cons (NULL_TREE
,
9643 = build_function_type (void_type_node
,
9644 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
9647 = build_function_type (integer_type_node
, endlink
);
9649 tree v2si_ftype_pv2si_int
9650 = build_function_type (opaque_V2SI_type_node
,
9651 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
9652 tree_cons (NULL_TREE
, integer_type_node
,
9655 tree v2si_ftype_puint_int
9656 = build_function_type (opaque_V2SI_type_node
,
9657 tree_cons (NULL_TREE
, puint_type_node
,
9658 tree_cons (NULL_TREE
, integer_type_node
,
9661 tree v2si_ftype_pushort_int
9662 = build_function_type (opaque_V2SI_type_node
,
9663 tree_cons (NULL_TREE
, pushort_type_node
,
9664 tree_cons (NULL_TREE
, integer_type_node
,
9667 tree v2si_ftype_signed_char
9668 = build_function_type (opaque_V2SI_type_node
,
9669 tree_cons (NULL_TREE
, signed_char_type_node
,
9672 /* The initialization of the simple binary and unary builtins is
9673 done in rs6000_common_init_builtins, but we have to enable the
9674 mask bits here manually because we have run out of `target_flags'
9675 bits. We really need to redesign this mask business. */
9677 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
9678 ARRAY_SIZE (bdesc_2arg
),
9681 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
9682 ARRAY_SIZE (bdesc_1arg
),
9684 SPE_BUILTIN_EVSUBFUSIAAW
);
9685 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
9686 ARRAY_SIZE (bdesc_spe_predicates
),
9687 SPE_BUILTIN_EVCMPEQ
,
9688 SPE_BUILTIN_EVFSTSTLT
);
9689 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
9690 ARRAY_SIZE (bdesc_spe_evsel
),
9691 SPE_BUILTIN_EVSEL_CMPGTS
,
9692 SPE_BUILTIN_EVSEL_FSTSTEQ
);
9694 (*lang_hooks
.decls
.pushdecl
)
9695 (build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
9696 get_identifier ("__ev64_opaque__"),
9697 opaque_V2SI_type_node
));
9699 /* Initialize irregular SPE builtins. */
9701 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
9702 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
9703 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
9704 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
9705 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
9706 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
9707 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
9708 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
9709 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
9710 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
9711 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
9712 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
9713 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
9714 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
9715 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
9716 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
9717 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
9718 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
9721 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
9722 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
9723 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
9724 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
9725 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
9726 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
9727 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
9728 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
9729 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
9730 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
9731 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
9732 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
9733 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
9734 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
9735 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
9736 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
9737 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
9738 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
9739 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
9740 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
9741 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
9742 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
9745 d
= (struct builtin_description
*) bdesc_spe_predicates
;
9746 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
9750 switch (insn_data
[d
->icode
].operand
[1].mode
)
9753 type
= int_ftype_int_v2si_v2si
;
9756 type
= int_ftype_int_v2sf_v2sf
;
9762 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9765 /* Evsel predicates. */
9766 d
= (struct builtin_description
*) bdesc_spe_evsel
;
9767 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
9771 switch (insn_data
[d
->icode
].operand
[1].mode
)
9774 type
= v2si_ftype_4_v2si
;
9777 type
= v2sf_ftype_4_v2sf
;
9783 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9788 paired_init_builtins (void)
9790 const struct builtin_description
*d
;
9792 tree endlink
= void_list_node
;
9794 tree int_ftype_int_v2sf_v2sf
9795 = build_function_type
9797 tree_cons (NULL_TREE
, integer_type_node
,
9798 tree_cons (NULL_TREE
, V2SF_type_node
,
9799 tree_cons (NULL_TREE
, V2SF_type_node
,
9801 tree pcfloat_type_node
=
9802 build_pointer_type (build_qualified_type
9803 (float_type_node
, TYPE_QUAL_CONST
));
9805 tree v2sf_ftype_long_pcfloat
= build_function_type_list (V2SF_type_node
,
9806 long_integer_type_node
,
9809 tree void_ftype_v2sf_long_pcfloat
=
9810 build_function_type_list (void_type_node
,
9812 long_integer_type_node
,
9817 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat
,
9821 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat
,
9822 PAIRED_BUILTIN_STX
);
9825 d
= bdesc_paired_preds
;
9826 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); ++i
, d
++)
9830 switch (insn_data
[d
->icode
].operand
[1].mode
)
9833 type
= int_ftype_int_v2sf_v2sf
;
9839 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9844 altivec_init_builtins (void)
9846 const struct builtin_description
*d
;
9847 const struct builtin_description_predicates
*dp
;
9851 tree pfloat_type_node
= build_pointer_type (float_type_node
);
9852 tree pint_type_node
= build_pointer_type (integer_type_node
);
9853 tree pshort_type_node
= build_pointer_type (short_integer_type_node
);
9854 tree pchar_type_node
= build_pointer_type (char_type_node
);
9856 tree pvoid_type_node
= build_pointer_type (void_type_node
);
9858 tree pcfloat_type_node
= build_pointer_type (build_qualified_type (float_type_node
, TYPE_QUAL_CONST
));
9859 tree pcint_type_node
= build_pointer_type (build_qualified_type (integer_type_node
, TYPE_QUAL_CONST
));
9860 tree pcshort_type_node
= build_pointer_type (build_qualified_type (short_integer_type_node
, TYPE_QUAL_CONST
));
9861 tree pcchar_type_node
= build_pointer_type (build_qualified_type (char_type_node
, TYPE_QUAL_CONST
));
9863 tree pcvoid_type_node
= build_pointer_type (build_qualified_type (void_type_node
, TYPE_QUAL_CONST
));
9865 tree int_ftype_opaque
9866 = build_function_type_list (integer_type_node
,
9867 opaque_V4SI_type_node
, NULL_TREE
);
9868 tree opaque_ftype_opaque
9869 = build_function_type (integer_type_node
,
9871 tree opaque_ftype_opaque_int
9872 = build_function_type_list (opaque_V4SI_type_node
,
9873 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
9874 tree opaque_ftype_opaque_opaque_int
9875 = build_function_type_list (opaque_V4SI_type_node
,
9876 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
9877 integer_type_node
, NULL_TREE
);
9878 tree int_ftype_int_opaque_opaque
9879 = build_function_type_list (integer_type_node
,
9880 integer_type_node
, opaque_V4SI_type_node
,
9881 opaque_V4SI_type_node
, NULL_TREE
);
9882 tree int_ftype_int_v4si_v4si
9883 = build_function_type_list (integer_type_node
,
9884 integer_type_node
, V4SI_type_node
,
9885 V4SI_type_node
, NULL_TREE
);
9886 tree v4sf_ftype_pcfloat
9887 = build_function_type_list (V4SF_type_node
, pcfloat_type_node
, NULL_TREE
);
9888 tree void_ftype_pfloat_v4sf
9889 = build_function_type_list (void_type_node
,
9890 pfloat_type_node
, V4SF_type_node
, NULL_TREE
);
9891 tree v4si_ftype_pcint
9892 = build_function_type_list (V4SI_type_node
, pcint_type_node
, NULL_TREE
);
9893 tree void_ftype_pint_v4si
9894 = build_function_type_list (void_type_node
,
9895 pint_type_node
, V4SI_type_node
, NULL_TREE
);
9896 tree v8hi_ftype_pcshort
9897 = build_function_type_list (V8HI_type_node
, pcshort_type_node
, NULL_TREE
);
9898 tree void_ftype_pshort_v8hi
9899 = build_function_type_list (void_type_node
,
9900 pshort_type_node
, V8HI_type_node
, NULL_TREE
);
9901 tree v16qi_ftype_pcchar
9902 = build_function_type_list (V16QI_type_node
, pcchar_type_node
, NULL_TREE
);
9903 tree void_ftype_pchar_v16qi
9904 = build_function_type_list (void_type_node
,
9905 pchar_type_node
, V16QI_type_node
, NULL_TREE
);
9906 tree void_ftype_v4si
9907 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
9908 tree v8hi_ftype_void
9909 = build_function_type (V8HI_type_node
, void_list_node
);
9910 tree void_ftype_void
9911 = build_function_type (void_type_node
, void_list_node
);
9913 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
9915 tree opaque_ftype_long_pcvoid
9916 = build_function_type_list (opaque_V4SI_type_node
,
9917 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9918 tree v16qi_ftype_long_pcvoid
9919 = build_function_type_list (V16QI_type_node
,
9920 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9921 tree v8hi_ftype_long_pcvoid
9922 = build_function_type_list (V8HI_type_node
,
9923 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9924 tree v4si_ftype_long_pcvoid
9925 = build_function_type_list (V4SI_type_node
,
9926 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9928 tree void_ftype_opaque_long_pvoid
9929 = build_function_type_list (void_type_node
,
9930 opaque_V4SI_type_node
, long_integer_type_node
,
9931 pvoid_type_node
, NULL_TREE
);
9932 tree void_ftype_v4si_long_pvoid
9933 = build_function_type_list (void_type_node
,
9934 V4SI_type_node
, long_integer_type_node
,
9935 pvoid_type_node
, NULL_TREE
);
9936 tree void_ftype_v16qi_long_pvoid
9937 = build_function_type_list (void_type_node
,
9938 V16QI_type_node
, long_integer_type_node
,
9939 pvoid_type_node
, NULL_TREE
);
9940 tree void_ftype_v8hi_long_pvoid
9941 = build_function_type_list (void_type_node
,
9942 V8HI_type_node
, long_integer_type_node
,
9943 pvoid_type_node
, NULL_TREE
);
9944 tree int_ftype_int_v8hi_v8hi
9945 = build_function_type_list (integer_type_node
,
9946 integer_type_node
, V8HI_type_node
,
9947 V8HI_type_node
, NULL_TREE
);
9948 tree int_ftype_int_v16qi_v16qi
9949 = build_function_type_list (integer_type_node
,
9950 integer_type_node
, V16QI_type_node
,
9951 V16QI_type_node
, NULL_TREE
);
9952 tree int_ftype_int_v4sf_v4sf
9953 = build_function_type_list (integer_type_node
,
9954 integer_type_node
, V4SF_type_node
,
9955 V4SF_type_node
, NULL_TREE
);
9956 tree v4si_ftype_v4si
9957 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
9958 tree v8hi_ftype_v8hi
9959 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
9960 tree v16qi_ftype_v16qi
9961 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
9962 tree v4sf_ftype_v4sf
9963 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
9964 tree void_ftype_pcvoid_int_int
9965 = build_function_type_list (void_type_node
,
9966 pcvoid_type_node
, integer_type_node
,
9967 integer_type_node
, NULL_TREE
);
9969 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat
,
9970 ALTIVEC_BUILTIN_LD_INTERNAL_4sf
);
9971 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf
,
9972 ALTIVEC_BUILTIN_ST_INTERNAL_4sf
);
9973 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint
,
9974 ALTIVEC_BUILTIN_LD_INTERNAL_4si
);
9975 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si
,
9976 ALTIVEC_BUILTIN_ST_INTERNAL_4si
);
9977 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort
,
9978 ALTIVEC_BUILTIN_LD_INTERNAL_8hi
);
9979 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi
,
9980 ALTIVEC_BUILTIN_ST_INTERNAL_8hi
);
9981 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar
,
9982 ALTIVEC_BUILTIN_LD_INTERNAL_16qi
);
9983 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi
,
9984 ALTIVEC_BUILTIN_ST_INTERNAL_16qi
);
9985 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
9986 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
9987 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
9988 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
9989 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
9990 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
9991 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
9992 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
9993 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
9994 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
9995 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
9996 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
9997 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
9998 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
9999 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
10000 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
10001 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
10002 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
10003 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
10004 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
10005 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
10006 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
10007 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
10008 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
10009 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
10010 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
10011 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
10012 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
10013 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
10014 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
10016 if (rs6000_cpu
== PROCESSOR_CELL
)
10018 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLX
);
10019 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLXL
);
10020 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRX
);
10021 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRXL
);
10023 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLX
);
10024 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLXL
);
10025 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRX
);
10026 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRXL
);
10028 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLX
);
10029 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLXL
);
10030 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRX
);
10031 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRXL
);
10033 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLX
);
10034 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLXL
);
10035 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRX
);
10036 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRXL
);
10038 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
10039 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splats", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_SPLATS
);
10040 def_builtin (MASK_ALTIVEC
, "__builtin_vec_promote", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_PROMOTE
);
10042 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
10043 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
10044 def_builtin (MASK_ALTIVEC
, "__builtin_vec_extract", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_EXTRACT
);
10045 def_builtin (MASK_ALTIVEC
, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_INSERT
);
10046 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
10047 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
10048 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
10049 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
10050 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
10051 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
10052 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
10053 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
10055 /* Add the DST variants. */
10057 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
10058 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
10060 /* Initialize the predicates. */
10061 dp
= bdesc_altivec_preds
;
10062 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
10064 enum machine_mode mode1
;
10066 bool is_overloaded
= dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10067 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10072 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
10077 type
= int_ftype_int_opaque_opaque
;
10080 type
= int_ftype_int_v4si_v4si
;
10083 type
= int_ftype_int_v8hi_v8hi
;
10086 type
= int_ftype_int_v16qi_v16qi
;
10089 type
= int_ftype_int_v4sf_v4sf
;
10092 gcc_unreachable ();
10095 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
10098 /* Initialize the abs* operators. */
10100 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
10102 enum machine_mode mode0
;
10105 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10110 type
= v4si_ftype_v4si
;
10113 type
= v8hi_ftype_v8hi
;
10116 type
= v16qi_ftype_v16qi
;
10119 type
= v4sf_ftype_v4sf
;
10122 gcc_unreachable ();
10125 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10128 if (TARGET_ALTIVEC
)
10132 /* Initialize target builtin that implements
10133 targetm.vectorize.builtin_mask_for_load. */
10135 decl
= add_builtin_function ("__builtin_altivec_mask_for_load",
10136 v16qi_ftype_long_pcvoid
,
10137 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
10138 BUILT_IN_MD
, NULL
, NULL_TREE
);
10139 TREE_READONLY (decl
) = 1;
10140 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
10141 altivec_builtin_mask_for_load
= decl
;
10144 /* Access to the vec_init patterns. */
10145 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
10146 integer_type_node
, integer_type_node
,
10147 integer_type_node
, NULL_TREE
);
10148 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4si", ftype
,
10149 ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
10151 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
10152 short_integer_type_node
,
10153 short_integer_type_node
,
10154 short_integer_type_node
,
10155 short_integer_type_node
,
10156 short_integer_type_node
,
10157 short_integer_type_node
,
10158 short_integer_type_node
, NULL_TREE
);
10159 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v8hi", ftype
,
10160 ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
10162 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
10163 char_type_node
, char_type_node
,
10164 char_type_node
, char_type_node
,
10165 char_type_node
, char_type_node
,
10166 char_type_node
, char_type_node
,
10167 char_type_node
, char_type_node
,
10168 char_type_node
, char_type_node
,
10169 char_type_node
, char_type_node
,
10170 char_type_node
, NULL_TREE
);
10171 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v16qi", ftype
,
10172 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
10174 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
10175 float_type_node
, float_type_node
,
10176 float_type_node
, NULL_TREE
);
10177 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4sf", ftype
,
10178 ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
10180 /* Access to the vec_set patterns. */
10181 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
10183 integer_type_node
, NULL_TREE
);
10184 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4si", ftype
,
10185 ALTIVEC_BUILTIN_VEC_SET_V4SI
);
10187 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
10189 integer_type_node
, NULL_TREE
);
10190 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v8hi", ftype
,
10191 ALTIVEC_BUILTIN_VEC_SET_V8HI
);
10193 ftype
= build_function_type_list (V8HI_type_node
, V16QI_type_node
,
10195 integer_type_node
, NULL_TREE
);
10196 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v16qi", ftype
,
10197 ALTIVEC_BUILTIN_VEC_SET_V16QI
);
10199 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
10201 integer_type_node
, NULL_TREE
);
10202 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4sf", ftype
,
10203 ALTIVEC_BUILTIN_VEC_SET_V4SF
);
10205 /* Access to the vec_extract patterns. */
10206 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
10207 integer_type_node
, NULL_TREE
);
10208 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4si", ftype
,
10209 ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
10211 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
10212 integer_type_node
, NULL_TREE
);
10213 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v8hi", ftype
,
10214 ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
10216 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
10217 integer_type_node
, NULL_TREE
);
10218 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v16qi", ftype
,
10219 ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
10221 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
10222 integer_type_node
, NULL_TREE
);
10223 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4sf", ftype
,
10224 ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
10228 rs6000_common_init_builtins (void)
10230 const struct builtin_description
*d
;
10233 tree v2sf_ftype_v2sf_v2sf_v2sf
10234 = build_function_type_list (V2SF_type_node
,
10235 V2SF_type_node
, V2SF_type_node
,
10236 V2SF_type_node
, NULL_TREE
);
10238 tree v4sf_ftype_v4sf_v4sf_v16qi
10239 = build_function_type_list (V4SF_type_node
,
10240 V4SF_type_node
, V4SF_type_node
,
10241 V16QI_type_node
, NULL_TREE
);
10242 tree v4si_ftype_v4si_v4si_v16qi
10243 = build_function_type_list (V4SI_type_node
,
10244 V4SI_type_node
, V4SI_type_node
,
10245 V16QI_type_node
, NULL_TREE
);
10246 tree v8hi_ftype_v8hi_v8hi_v16qi
10247 = build_function_type_list (V8HI_type_node
,
10248 V8HI_type_node
, V8HI_type_node
,
10249 V16QI_type_node
, NULL_TREE
);
10250 tree v16qi_ftype_v16qi_v16qi_v16qi
10251 = build_function_type_list (V16QI_type_node
,
10252 V16QI_type_node
, V16QI_type_node
,
10253 V16QI_type_node
, NULL_TREE
);
10254 tree v4si_ftype_int
10255 = build_function_type_list (V4SI_type_node
, integer_type_node
, NULL_TREE
);
10256 tree v8hi_ftype_int
10257 = build_function_type_list (V8HI_type_node
, integer_type_node
, NULL_TREE
);
10258 tree v16qi_ftype_int
10259 = build_function_type_list (V16QI_type_node
, integer_type_node
, NULL_TREE
);
10260 tree v8hi_ftype_v16qi
10261 = build_function_type_list (V8HI_type_node
, V16QI_type_node
, NULL_TREE
);
10262 tree v4sf_ftype_v4sf
10263 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10265 tree v2si_ftype_v2si_v2si
10266 = build_function_type_list (opaque_V2SI_type_node
,
10267 opaque_V2SI_type_node
,
10268 opaque_V2SI_type_node
, NULL_TREE
);
10270 tree v2sf_ftype_v2sf_v2sf_spe
10271 = build_function_type_list (opaque_V2SF_type_node
,
10272 opaque_V2SF_type_node
,
10273 opaque_V2SF_type_node
, NULL_TREE
);
10275 tree v2sf_ftype_v2sf_v2sf
10276 = build_function_type_list (V2SF_type_node
,
10278 V2SF_type_node
, NULL_TREE
);
10281 tree v2si_ftype_int_int
10282 = build_function_type_list (opaque_V2SI_type_node
,
10283 integer_type_node
, integer_type_node
,
10286 tree opaque_ftype_opaque
10287 = build_function_type_list (opaque_V4SI_type_node
,
10288 opaque_V4SI_type_node
, NULL_TREE
);
10290 tree v2si_ftype_v2si
10291 = build_function_type_list (opaque_V2SI_type_node
,
10292 opaque_V2SI_type_node
, NULL_TREE
);
10294 tree v2sf_ftype_v2sf_spe
10295 = build_function_type_list (opaque_V2SF_type_node
,
10296 opaque_V2SF_type_node
, NULL_TREE
);
10298 tree v2sf_ftype_v2sf
10299 = build_function_type_list (V2SF_type_node
,
10300 V2SF_type_node
, NULL_TREE
);
10302 tree v2sf_ftype_v2si
10303 = build_function_type_list (opaque_V2SF_type_node
,
10304 opaque_V2SI_type_node
, NULL_TREE
);
10306 tree v2si_ftype_v2sf
10307 = build_function_type_list (opaque_V2SI_type_node
,
10308 opaque_V2SF_type_node
, NULL_TREE
);
10310 tree v2si_ftype_v2si_char
10311 = build_function_type_list (opaque_V2SI_type_node
,
10312 opaque_V2SI_type_node
,
10313 char_type_node
, NULL_TREE
);
10315 tree v2si_ftype_int_char
10316 = build_function_type_list (opaque_V2SI_type_node
,
10317 integer_type_node
, char_type_node
, NULL_TREE
);
10319 tree v2si_ftype_char
10320 = build_function_type_list (opaque_V2SI_type_node
,
10321 char_type_node
, NULL_TREE
);
10323 tree int_ftype_int_int
10324 = build_function_type_list (integer_type_node
,
10325 integer_type_node
, integer_type_node
,
10328 tree opaque_ftype_opaque_opaque
10329 = build_function_type_list (opaque_V4SI_type_node
,
10330 opaque_V4SI_type_node
, opaque_V4SI_type_node
, NULL_TREE
);
10331 tree v4si_ftype_v4si_v4si
10332 = build_function_type_list (V4SI_type_node
,
10333 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
10334 tree v4sf_ftype_v4si_int
10335 = build_function_type_list (V4SF_type_node
,
10336 V4SI_type_node
, integer_type_node
, NULL_TREE
);
10337 tree v4si_ftype_v4sf_int
10338 = build_function_type_list (V4SI_type_node
,
10339 V4SF_type_node
, integer_type_node
, NULL_TREE
);
10340 tree v4si_ftype_v4si_int
10341 = build_function_type_list (V4SI_type_node
,
10342 V4SI_type_node
, integer_type_node
, NULL_TREE
);
10343 tree v8hi_ftype_v8hi_int
10344 = build_function_type_list (V8HI_type_node
,
10345 V8HI_type_node
, integer_type_node
, NULL_TREE
);
10346 tree v16qi_ftype_v16qi_int
10347 = build_function_type_list (V16QI_type_node
,
10348 V16QI_type_node
, integer_type_node
, NULL_TREE
);
10349 tree v16qi_ftype_v16qi_v16qi_int
10350 = build_function_type_list (V16QI_type_node
,
10351 V16QI_type_node
, V16QI_type_node
,
10352 integer_type_node
, NULL_TREE
);
10353 tree v8hi_ftype_v8hi_v8hi_int
10354 = build_function_type_list (V8HI_type_node
,
10355 V8HI_type_node
, V8HI_type_node
,
10356 integer_type_node
, NULL_TREE
);
10357 tree v4si_ftype_v4si_v4si_int
10358 = build_function_type_list (V4SI_type_node
,
10359 V4SI_type_node
, V4SI_type_node
,
10360 integer_type_node
, NULL_TREE
);
10361 tree v4sf_ftype_v4sf_v4sf_int
10362 = build_function_type_list (V4SF_type_node
,
10363 V4SF_type_node
, V4SF_type_node
,
10364 integer_type_node
, NULL_TREE
);
10365 tree v4sf_ftype_v4sf_v4sf
10366 = build_function_type_list (V4SF_type_node
,
10367 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10368 tree opaque_ftype_opaque_opaque_opaque
10369 = build_function_type_list (opaque_V4SI_type_node
,
10370 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
10371 opaque_V4SI_type_node
, NULL_TREE
);
10372 tree v4sf_ftype_v4sf_v4sf_v4si
10373 = build_function_type_list (V4SF_type_node
,
10374 V4SF_type_node
, V4SF_type_node
,
10375 V4SI_type_node
, NULL_TREE
);
10376 tree v4sf_ftype_v4sf_v4sf_v4sf
10377 = build_function_type_list (V4SF_type_node
,
10378 V4SF_type_node
, V4SF_type_node
,
10379 V4SF_type_node
, NULL_TREE
);
10380 tree v4si_ftype_v4si_v4si_v4si
10381 = build_function_type_list (V4SI_type_node
,
10382 V4SI_type_node
, V4SI_type_node
,
10383 V4SI_type_node
, NULL_TREE
);
10384 tree v8hi_ftype_v8hi_v8hi
10385 = build_function_type_list (V8HI_type_node
,
10386 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10387 tree v8hi_ftype_v8hi_v8hi_v8hi
10388 = build_function_type_list (V8HI_type_node
,
10389 V8HI_type_node
, V8HI_type_node
,
10390 V8HI_type_node
, NULL_TREE
);
10391 tree v4si_ftype_v8hi_v8hi_v4si
10392 = build_function_type_list (V4SI_type_node
,
10393 V8HI_type_node
, V8HI_type_node
,
10394 V4SI_type_node
, NULL_TREE
);
10395 tree v4si_ftype_v16qi_v16qi_v4si
10396 = build_function_type_list (V4SI_type_node
,
10397 V16QI_type_node
, V16QI_type_node
,
10398 V4SI_type_node
, NULL_TREE
);
10399 tree v16qi_ftype_v16qi_v16qi
10400 = build_function_type_list (V16QI_type_node
,
10401 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10402 tree v4si_ftype_v4sf_v4sf
10403 = build_function_type_list (V4SI_type_node
,
10404 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10405 tree v8hi_ftype_v16qi_v16qi
10406 = build_function_type_list (V8HI_type_node
,
10407 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10408 tree v4si_ftype_v8hi_v8hi
10409 = build_function_type_list (V4SI_type_node
,
10410 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10411 tree v8hi_ftype_v4si_v4si
10412 = build_function_type_list (V8HI_type_node
,
10413 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
10414 tree v16qi_ftype_v8hi_v8hi
10415 = build_function_type_list (V16QI_type_node
,
10416 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10417 tree v4si_ftype_v16qi_v4si
10418 = build_function_type_list (V4SI_type_node
,
10419 V16QI_type_node
, V4SI_type_node
, NULL_TREE
);
10420 tree v4si_ftype_v16qi_v16qi
10421 = build_function_type_list (V4SI_type_node
,
10422 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10423 tree v4si_ftype_v8hi_v4si
10424 = build_function_type_list (V4SI_type_node
,
10425 V8HI_type_node
, V4SI_type_node
, NULL_TREE
);
10426 tree v4si_ftype_v8hi
10427 = build_function_type_list (V4SI_type_node
, V8HI_type_node
, NULL_TREE
);
10428 tree int_ftype_v4si_v4si
10429 = build_function_type_list (integer_type_node
,
10430 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
10431 tree int_ftype_v4sf_v4sf
10432 = build_function_type_list (integer_type_node
,
10433 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10434 tree int_ftype_v16qi_v16qi
10435 = build_function_type_list (integer_type_node
,
10436 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10437 tree int_ftype_v8hi_v8hi
10438 = build_function_type_list (integer_type_node
,
10439 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10441 /* Add the simple ternary operators. */
10443 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
10445 enum machine_mode mode0
, mode1
, mode2
, mode3
;
10447 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10448 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10459 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
10462 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10463 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10464 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
10465 mode3
= insn_data
[d
->icode
].operand
[3].mode
;
10468 /* When all four are of the same mode. */
10469 if (mode0
== mode1
&& mode1
== mode2
&& mode2
== mode3
)
10474 type
= opaque_ftype_opaque_opaque_opaque
;
10477 type
= v4si_ftype_v4si_v4si_v4si
;
10480 type
= v4sf_ftype_v4sf_v4sf_v4sf
;
10483 type
= v8hi_ftype_v8hi_v8hi_v8hi
;
10486 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
10489 type
= v2sf_ftype_v2sf_v2sf_v2sf
;
10492 gcc_unreachable ();
10495 else if (mode0
== mode1
&& mode1
== mode2
&& mode3
== V16QImode
)
10500 type
= v4si_ftype_v4si_v4si_v16qi
;
10503 type
= v4sf_ftype_v4sf_v4sf_v16qi
;
10506 type
= v8hi_ftype_v8hi_v8hi_v16qi
;
10509 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
10512 gcc_unreachable ();
10515 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
10516 && mode3
== V4SImode
)
10517 type
= v4si_ftype_v16qi_v16qi_v4si
;
10518 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
10519 && mode3
== V4SImode
)
10520 type
= v4si_ftype_v8hi_v8hi_v4si
;
10521 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
10522 && mode3
== V4SImode
)
10523 type
= v4sf_ftype_v4sf_v4sf_v4si
;
10525 /* vchar, vchar, vchar, 4-bit literal. */
10526 else if (mode0
== V16QImode
&& mode1
== mode0
&& mode2
== mode0
10527 && mode3
== QImode
)
10528 type
= v16qi_ftype_v16qi_v16qi_int
;
10530 /* vshort, vshort, vshort, 4-bit literal. */
10531 else if (mode0
== V8HImode
&& mode1
== mode0
&& mode2
== mode0
10532 && mode3
== QImode
)
10533 type
= v8hi_ftype_v8hi_v8hi_int
;
10535 /* vint, vint, vint, 4-bit literal. */
10536 else if (mode0
== V4SImode
&& mode1
== mode0
&& mode2
== mode0
10537 && mode3
== QImode
)
10538 type
= v4si_ftype_v4si_v4si_int
;
10540 /* vfloat, vfloat, vfloat, 4-bit literal. */
10541 else if (mode0
== V4SFmode
&& mode1
== mode0
&& mode2
== mode0
10542 && mode3
== QImode
)
10543 type
= v4sf_ftype_v4sf_v4sf_int
;
10546 gcc_unreachable ();
10548 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10551 /* Add the simple binary operators. */
10552 d
= (struct builtin_description
*) bdesc_2arg
;
10553 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
10555 enum machine_mode mode0
, mode1
, mode2
;
10557 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10558 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10568 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
10571 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10572 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10573 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
10576 /* When all three operands are of the same mode. */
10577 if (mode0
== mode1
&& mode1
== mode2
)
10582 type
= opaque_ftype_opaque_opaque
;
10585 type
= v4sf_ftype_v4sf_v4sf
;
10588 type
= v4si_ftype_v4si_v4si
;
10591 type
= v16qi_ftype_v16qi_v16qi
;
10594 type
= v8hi_ftype_v8hi_v8hi
;
10597 type
= v2si_ftype_v2si_v2si
;
10600 if (TARGET_PAIRED_FLOAT
)
10601 type
= v2sf_ftype_v2sf_v2sf
;
10603 type
= v2sf_ftype_v2sf_v2sf_spe
;
10606 type
= int_ftype_int_int
;
10609 gcc_unreachable ();
10613 /* A few other combos we really don't want to do manually. */
10615 /* vint, vfloat, vfloat. */
10616 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
)
10617 type
= v4si_ftype_v4sf_v4sf
;
10619 /* vshort, vchar, vchar. */
10620 else if (mode0
== V8HImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
10621 type
= v8hi_ftype_v16qi_v16qi
;
10623 /* vint, vshort, vshort. */
10624 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
10625 type
= v4si_ftype_v8hi_v8hi
;
10627 /* vshort, vint, vint. */
10628 else if (mode0
== V8HImode
&& mode1
== V4SImode
&& mode2
== V4SImode
)
10629 type
= v8hi_ftype_v4si_v4si
;
10631 /* vchar, vshort, vshort. */
10632 else if (mode0
== V16QImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
10633 type
= v16qi_ftype_v8hi_v8hi
;
10635 /* vint, vchar, vint. */
10636 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V4SImode
)
10637 type
= v4si_ftype_v16qi_v4si
;
10639 /* vint, vchar, vchar. */
10640 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
10641 type
= v4si_ftype_v16qi_v16qi
;
10643 /* vint, vshort, vint. */
10644 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V4SImode
)
10645 type
= v4si_ftype_v8hi_v4si
;
10647 /* vint, vint, 5-bit literal. */
10648 else if (mode0
== V4SImode
&& mode1
== V4SImode
&& mode2
== QImode
)
10649 type
= v4si_ftype_v4si_int
;
10651 /* vshort, vshort, 5-bit literal. */
10652 else if (mode0
== V8HImode
&& mode1
== V8HImode
&& mode2
== QImode
)
10653 type
= v8hi_ftype_v8hi_int
;
10655 /* vchar, vchar, 5-bit literal. */
10656 else if (mode0
== V16QImode
&& mode1
== V16QImode
&& mode2
== QImode
)
10657 type
= v16qi_ftype_v16qi_int
;
10659 /* vfloat, vint, 5-bit literal. */
10660 else if (mode0
== V4SFmode
&& mode1
== V4SImode
&& mode2
== QImode
)
10661 type
= v4sf_ftype_v4si_int
;
10663 /* vint, vfloat, 5-bit literal. */
10664 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== QImode
)
10665 type
= v4si_ftype_v4sf_int
;
10667 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== SImode
)
10668 type
= v2si_ftype_int_int
;
10670 else if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
10671 type
= v2si_ftype_v2si_char
;
10673 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== QImode
)
10674 type
= v2si_ftype_int_char
;
10679 gcc_assert (mode0
== SImode
);
10683 type
= int_ftype_v4si_v4si
;
10686 type
= int_ftype_v4sf_v4sf
;
10689 type
= int_ftype_v16qi_v16qi
;
10692 type
= int_ftype_v8hi_v8hi
;
10695 gcc_unreachable ();
10699 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10702 /* Add the simple unary operators. */
10703 d
= (struct builtin_description
*) bdesc_1arg
;
10704 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
10706 enum machine_mode mode0
, mode1
;
10708 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10709 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10718 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
10721 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10722 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10725 if (mode0
== V4SImode
&& mode1
== QImode
)
10726 type
= v4si_ftype_int
;
10727 else if (mode0
== V8HImode
&& mode1
== QImode
)
10728 type
= v8hi_ftype_int
;
10729 else if (mode0
== V16QImode
&& mode1
== QImode
)
10730 type
= v16qi_ftype_int
;
10731 else if (mode0
== VOIDmode
&& mode1
== VOIDmode
)
10732 type
= opaque_ftype_opaque
;
10733 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
)
10734 type
= v4sf_ftype_v4sf
;
10735 else if (mode0
== V8HImode
&& mode1
== V16QImode
)
10736 type
= v8hi_ftype_v16qi
;
10737 else if (mode0
== V4SImode
&& mode1
== V8HImode
)
10738 type
= v4si_ftype_v8hi
;
10739 else if (mode0
== V2SImode
&& mode1
== V2SImode
)
10740 type
= v2si_ftype_v2si
;
10741 else if (mode0
== V2SFmode
&& mode1
== V2SFmode
)
10743 if (TARGET_PAIRED_FLOAT
)
10744 type
= v2sf_ftype_v2sf
;
10746 type
= v2sf_ftype_v2sf_spe
;
10748 else if (mode0
== V2SFmode
&& mode1
== V2SImode
)
10749 type
= v2sf_ftype_v2si
;
10750 else if (mode0
== V2SImode
&& mode1
== V2SFmode
)
10751 type
= v2si_ftype_v2sf
;
10752 else if (mode0
== V2SImode
&& mode1
== QImode
)
10753 type
= v2si_ftype_char
;
10755 gcc_unreachable ();
10757 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10762 rs6000_init_libfuncs (void)
10764 if (DEFAULT_ABI
!= ABI_V4
&& TARGET_XCOFF
10765 && !TARGET_POWER2
&& !TARGET_POWERPC
)
10767 /* AIX library routines for float->int conversion. */
10768 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
10769 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
10770 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
10771 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
10774 if (!TARGET_IEEEQUAD
)
10775 /* AIX/Darwin/64-bit Linux quad floating point routines. */
10776 if (!TARGET_XL_COMPAT
)
10778 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
10779 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
10780 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
10781 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
10783 if (!(TARGET_HARD_FLOAT
&& (TARGET_FPRS
|| TARGET_E500_DOUBLE
)))
10785 set_optab_libfunc (neg_optab
, TFmode
, "__gcc_qneg");
10786 set_optab_libfunc (eq_optab
, TFmode
, "__gcc_qeq");
10787 set_optab_libfunc (ne_optab
, TFmode
, "__gcc_qne");
10788 set_optab_libfunc (gt_optab
, TFmode
, "__gcc_qgt");
10789 set_optab_libfunc (ge_optab
, TFmode
, "__gcc_qge");
10790 set_optab_libfunc (lt_optab
, TFmode
, "__gcc_qlt");
10791 set_optab_libfunc (le_optab
, TFmode
, "__gcc_qle");
10793 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "__gcc_stoq");
10794 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "__gcc_dtoq");
10795 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "__gcc_qtos");
10796 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "__gcc_qtod");
10797 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "__gcc_qtoi");
10798 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "__gcc_qtou");
10799 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "__gcc_itoq");
10800 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "__gcc_utoq");
10803 if (!(TARGET_HARD_FLOAT
&& TARGET_FPRS
))
10804 set_optab_libfunc (unord_optab
, TFmode
, "__gcc_qunord");
10808 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
10809 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
10810 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
10811 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
10815 /* 32-bit SVR4 quad floating point routines. */
10817 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
10818 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
10819 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
10820 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
10821 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
10822 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
10823 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
10825 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
10826 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
10827 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
10828 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
10829 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
10830 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
10832 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
10833 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
10834 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
10835 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
10836 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
10837 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
10838 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
10839 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "_q_utoq");
10844 /* Expand a block clear operation, and return 1 if successful. Return 0
10845 if we should let the compiler generate normal code.
10847 operands[0] is the destination
10848 operands[1] is the length
10849 operands[3] is the alignment */
10852 expand_block_clear (rtx operands
[])
10854 rtx orig_dest
= operands
[0];
10855 rtx bytes_rtx
= operands
[1];
10856 rtx align_rtx
= operands
[3];
10857 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
10858 HOST_WIDE_INT align
;
10859 HOST_WIDE_INT bytes
;
10864 /* If this is not a fixed size move, just call memcpy */
10868 /* This must be a fixed size alignment */
10869 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
10870 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
10872 /* Anything to clear? */
10873 bytes
= INTVAL (bytes_rtx
);
10877 /* Use the builtin memset after a point, to avoid huge code bloat.
10878 When optimize_size, avoid any significant code bloat; calling
10879 memset is about 4 instructions, so allow for one instruction to
10880 load zero and three to do clearing. */
10881 if (TARGET_ALTIVEC
&& align
>= 128)
10883 else if (TARGET_POWERPC64
&& align
>= 32)
10885 else if (TARGET_SPE
&& align
>= 64)
10890 if (optimize_size
&& bytes
> 3 * clear_step
)
10892 if (! optimize_size
&& bytes
> 8 * clear_step
)
10895 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
10897 enum machine_mode mode
= BLKmode
;
10900 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
10905 else if (bytes
>= 8 && TARGET_SPE
&& align
>= 64)
10910 else if (bytes
>= 8 && TARGET_POWERPC64
10911 /* 64-bit loads and stores require word-aligned
10913 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
10918 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
10919 { /* move 4 bytes */
10923 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
10924 { /* move 2 bytes */
10928 else /* move 1 byte at a time */
10934 dest
= adjust_address (orig_dest
, mode
, offset
);
10936 emit_move_insn (dest
, CONST0_RTX (mode
));
10943 /* Expand a block move operation, and return 1 if successful. Return 0
10944 if we should let the compiler generate normal code.
10946 operands[0] is the destination
10947 operands[1] is the source
10948 operands[2] is the length
10949 operands[3] is the alignment */
10951 #define MAX_MOVE_REG 4
10954 expand_block_move (rtx operands
[])
10956 rtx orig_dest
= operands
[0];
10957 rtx orig_src
= operands
[1];
10958 rtx bytes_rtx
= operands
[2];
10959 rtx align_rtx
= operands
[3];
10960 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
10965 rtx stores
[MAX_MOVE_REG
];
10968 /* If this is not a fixed size move, just call memcpy */
10972 /* This must be a fixed size alignment */
10973 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
10974 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
10976 /* Anything to move? */
10977 bytes
= INTVAL (bytes_rtx
);
10981 /* store_one_arg depends on expand_block_move to handle at least the size of
10982 reg_parm_stack_space. */
10983 if (bytes
> (TARGET_POWERPC64
? 64 : 32))
10986 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
10989 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
10990 rtx (*mov
) (rtx
, rtx
);
10992 enum machine_mode mode
= BLKmode
;
10995 /* Altivec first, since it will be faster than a string move
10996 when it applies, and usually not significantly larger. */
10997 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
11001 gen_func
.mov
= gen_movv4si
;
11003 else if (TARGET_SPE
&& bytes
>= 8 && align
>= 64)
11007 gen_func
.mov
= gen_movv2si
;
11009 else if (TARGET_STRING
11010 && bytes
> 24 /* move up to 32 bytes at a time */
11016 && ! fixed_regs
[10]
11017 && ! fixed_regs
[11]
11018 && ! fixed_regs
[12])
11020 move_bytes
= (bytes
> 32) ? 32 : bytes
;
11021 gen_func
.movmemsi
= gen_movmemsi_8reg
;
11023 else if (TARGET_STRING
11024 && bytes
> 16 /* move up to 24 bytes at a time */
11030 && ! fixed_regs
[10])
11032 move_bytes
= (bytes
> 24) ? 24 : bytes
;
11033 gen_func
.movmemsi
= gen_movmemsi_6reg
;
11035 else if (TARGET_STRING
11036 && bytes
> 8 /* move up to 16 bytes at a time */
11040 && ! fixed_regs
[8])
11042 move_bytes
= (bytes
> 16) ? 16 : bytes
;
11043 gen_func
.movmemsi
= gen_movmemsi_4reg
;
11045 else if (bytes
>= 8 && TARGET_POWERPC64
11046 /* 64-bit loads and stores require word-aligned
11048 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
11052 gen_func
.mov
= gen_movdi
;
11054 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
11055 { /* move up to 8 bytes at a time */
11056 move_bytes
= (bytes
> 8) ? 8 : bytes
;
11057 gen_func
.movmemsi
= gen_movmemsi_2reg
;
11059 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
11060 { /* move 4 bytes */
11063 gen_func
.mov
= gen_movsi
;
11065 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
11066 { /* move 2 bytes */
11069 gen_func
.mov
= gen_movhi
;
11071 else if (TARGET_STRING
&& bytes
> 1)
11072 { /* move up to 4 bytes at a time */
11073 move_bytes
= (bytes
> 4) ? 4 : bytes
;
11074 gen_func
.movmemsi
= gen_movmemsi_1reg
;
11076 else /* move 1 byte at a time */
11080 gen_func
.mov
= gen_movqi
;
11083 src
= adjust_address (orig_src
, mode
, offset
);
11084 dest
= adjust_address (orig_dest
, mode
, offset
);
11086 if (mode
!= BLKmode
)
11088 rtx tmp_reg
= gen_reg_rtx (mode
);
11090 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
11091 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
11094 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
11097 for (i
= 0; i
< num_reg
; i
++)
11098 emit_insn (stores
[i
]);
11102 if (mode
== BLKmode
)
11104 /* Move the address into scratch registers. The movmemsi
11105 patterns require zero offset. */
11106 if (!REG_P (XEXP (src
, 0)))
11108 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
11109 src
= replace_equiv_address (src
, src_reg
);
11111 set_mem_size (src
, GEN_INT (move_bytes
));
11113 if (!REG_P (XEXP (dest
, 0)))
11115 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
11116 dest
= replace_equiv_address (dest
, dest_reg
);
11118 set_mem_size (dest
, GEN_INT (move_bytes
));
11120 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
11121 GEN_INT (move_bytes
& 31),
11130 /* Return a string to perform a load_multiple operation.
11131 operands[0] is the vector.
11132 operands[1] is the source address.
11133 operands[2] is the first destination register. */
11136 rs6000_output_load_multiple (rtx operands
[3])
11138 /* We have to handle the case where the pseudo used to contain the address
11139 is assigned to one of the output registers. */
11141 int words
= XVECLEN (operands
[0], 0);
11144 if (XVECLEN (operands
[0], 0) == 1)
11145 return "{l|lwz} %2,0(%1)";
11147 for (i
= 0; i
< words
; i
++)
11148 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
11149 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
11153 xop
[0] = GEN_INT (4 * (words
-1));
11154 xop
[1] = operands
[1];
11155 xop
[2] = operands
[2];
11156 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
11161 xop
[0] = GEN_INT (4 * (words
-1));
11162 xop
[1] = operands
[1];
11163 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
11164 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
);
11169 for (j
= 0; j
< words
; j
++)
11172 xop
[0] = GEN_INT (j
* 4);
11173 xop
[1] = operands
[1];
11174 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
11175 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
11177 xop
[0] = GEN_INT (i
* 4);
11178 xop
[1] = operands
[1];
11179 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
11184 return "{lsi|lswi} %2,%1,%N0";
11188 /* A validation routine: say whether CODE, a condition code, and MODE
11189 match. The other alternatives either don't make sense or should
11190 never be generated. */
11193 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
11195 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
11196 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
11197 && GET_MODE_CLASS (mode
) == MODE_CC
);
11199 /* These don't make sense. */
11200 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
11201 || mode
!= CCUNSmode
);
11203 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
11204 || mode
== CCUNSmode
);
11206 gcc_assert (mode
== CCFPmode
11207 || (code
!= ORDERED
&& code
!= UNORDERED
11208 && code
!= UNEQ
&& code
!= LTGT
11209 && code
!= UNGT
&& code
!= UNLT
11210 && code
!= UNGE
&& code
!= UNLE
));
11212 /* These should never be generated except for
11213 flag_finite_math_only. */
11214 gcc_assert (mode
!= CCFPmode
11215 || flag_finite_math_only
11216 || (code
!= LE
&& code
!= GE
11217 && code
!= UNEQ
&& code
!= LTGT
11218 && code
!= UNGT
&& code
!= UNLT
));
11220 /* These are invalid; the information is not there. */
11221 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
11225 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
11226 mask required to convert the result of a rotate insn into a shift
11227 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
11230 includes_lshift_p (rtx shiftop
, rtx andop
)
11232 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
11234 shift_mask
<<= INTVAL (shiftop
);
11236 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
11239 /* Similar, but for right shift. */
11242 includes_rshift_p (rtx shiftop
, rtx andop
)
11244 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
11246 shift_mask
>>= INTVAL (shiftop
);
11248 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
11251 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
11252 to perform a left shift. It must have exactly SHIFTOP least
11253 significant 0's, then one or more 1's, then zero or more 0's. */
11256 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
11258 if (GET_CODE (andop
) == CONST_INT
)
11260 HOST_WIDE_INT c
, lsb
, shift_mask
;
11262 c
= INTVAL (andop
);
11263 if (c
== 0 || c
== ~0)
11267 shift_mask
<<= INTVAL (shiftop
);
11269 /* Find the least significant one bit. */
11272 /* It must coincide with the LSB of the shift mask. */
11273 if (-lsb
!= shift_mask
)
11276 /* Invert to look for the next transition (if any). */
11279 /* Remove the low group of ones (originally low group of zeros). */
11282 /* Again find the lsb, and check we have all 1's above. */
11286 else if (GET_CODE (andop
) == CONST_DOUBLE
11287 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
11289 HOST_WIDE_INT low
, high
, lsb
;
11290 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
11292 low
= CONST_DOUBLE_LOW (andop
);
11293 if (HOST_BITS_PER_WIDE_INT
< 64)
11294 high
= CONST_DOUBLE_HIGH (andop
);
11296 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
11297 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
11300 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
11302 shift_mask_high
= ~0;
11303 if (INTVAL (shiftop
) > 32)
11304 shift_mask_high
<<= INTVAL (shiftop
) - 32;
11306 lsb
= high
& -high
;
11308 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
11314 lsb
= high
& -high
;
11315 return high
== -lsb
;
11318 shift_mask_low
= ~0;
11319 shift_mask_low
<<= INTVAL (shiftop
);
11323 if (-lsb
!= shift_mask_low
)
11326 if (HOST_BITS_PER_WIDE_INT
< 64)
11331 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
11333 lsb
= high
& -high
;
11334 return high
== -lsb
;
11338 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
11344 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
11345 to perform a left shift. It must have SHIFTOP or more least
11346 significant 0's, with the remainder of the word 1's. */
11349 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
11351 if (GET_CODE (andop
) == CONST_INT
)
11353 HOST_WIDE_INT c
, lsb
, shift_mask
;
11356 shift_mask
<<= INTVAL (shiftop
);
11357 c
= INTVAL (andop
);
11359 /* Find the least significant one bit. */
11362 /* It must be covered by the shift mask.
11363 This test also rejects c == 0. */
11364 if ((lsb
& shift_mask
) == 0)
11367 /* Check we have all 1's above the transition, and reject all 1's. */
11368 return c
== -lsb
&& lsb
!= 1;
11370 else if (GET_CODE (andop
) == CONST_DOUBLE
11371 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
11373 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
11375 low
= CONST_DOUBLE_LOW (andop
);
11377 if (HOST_BITS_PER_WIDE_INT
< 64)
11379 HOST_WIDE_INT high
, shift_mask_high
;
11381 high
= CONST_DOUBLE_HIGH (andop
);
11385 shift_mask_high
= ~0;
11386 if (INTVAL (shiftop
) > 32)
11387 shift_mask_high
<<= INTVAL (shiftop
) - 32;
11389 lsb
= high
& -high
;
11391 if ((lsb
& shift_mask_high
) == 0)
11394 return high
== -lsb
;
11400 shift_mask_low
= ~0;
11401 shift_mask_low
<<= INTVAL (shiftop
);
11405 if ((lsb
& shift_mask_low
) == 0)
11408 return low
== -lsb
&& lsb
!= 1;
11414 /* Return 1 if operands will generate a valid arguments to rlwimi
11415 instruction for insert with right shift in 64-bit mode. The mask may
11416 not start on the first bit or stop on the last bit because wrap-around
11417 effects of instruction do not correspond to semantics of RTL insn. */
11420 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
11422 if (INTVAL (startop
) > 32
11423 && INTVAL (startop
) < 64
11424 && INTVAL (sizeop
) > 1
11425 && INTVAL (sizeop
) + INTVAL (startop
) < 64
11426 && INTVAL (shiftop
) > 0
11427 && INTVAL (sizeop
) + INTVAL (shiftop
) < 32
11428 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
11434 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
11435 for lfq and stfq insns iff the registers are hard registers. */
11438 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
11440 /* We might have been passed a SUBREG. */
11441 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
11444 /* We might have been passed non floating point registers. */
11445 if (!FP_REGNO_P (REGNO (reg1
))
11446 || !FP_REGNO_P (REGNO (reg2
)))
11449 return (REGNO (reg1
) == REGNO (reg2
) - 1);
11452 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
11453 addr1 and addr2 must be in consecutive memory locations
11454 (addr2 == addr1 + 8). */
11457 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
11460 unsigned int reg1
, reg2
;
11461 int offset1
, offset2
;
11463 /* The mems cannot be volatile. */
11464 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
11467 addr1
= XEXP (mem1
, 0);
11468 addr2
= XEXP (mem2
, 0);
11470 /* Extract an offset (if used) from the first addr. */
11471 if (GET_CODE (addr1
) == PLUS
)
11473 /* If not a REG, return zero. */
11474 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
11478 reg1
= REGNO (XEXP (addr1
, 0));
11479 /* The offset must be constant! */
11480 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
11482 offset1
= INTVAL (XEXP (addr1
, 1));
11485 else if (GET_CODE (addr1
) != REG
)
11489 reg1
= REGNO (addr1
);
11490 /* This was a simple (mem (reg)) expression. Offset is 0. */
11494 /* And now for the second addr. */
11495 if (GET_CODE (addr2
) == PLUS
)
11497 /* If not a REG, return zero. */
11498 if (GET_CODE (XEXP (addr2
, 0)) != REG
)
11502 reg2
= REGNO (XEXP (addr2
, 0));
11503 /* The offset must be constant. */
11504 if (GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
11506 offset2
= INTVAL (XEXP (addr2
, 1));
11509 else if (GET_CODE (addr2
) != REG
)
11513 reg2
= REGNO (addr2
);
11514 /* This was a simple (mem (reg)) expression. Offset is 0. */
11518 /* Both of these must have the same base register. */
11522 /* The offset for the second addr must be 8 more than the first addr. */
11523 if (offset2
!= offset1
+ 8)
11526 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
11533 rs6000_secondary_memory_needed_rtx (enum machine_mode mode
)
11535 static bool eliminated
= false;
11536 if (mode
!= SDmode
)
11537 return assign_stack_local (mode
, GET_MODE_SIZE (mode
), 0);
11540 rtx mem
= cfun
->machine
->sdmode_stack_slot
;
11541 gcc_assert (mem
!= NULL_RTX
);
11545 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
11546 cfun
->machine
->sdmode_stack_slot
= mem
;
11554 rs6000_check_sdmode (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
11556 /* Don't walk into types. */
11557 if (*tp
== NULL_TREE
|| *tp
== error_mark_node
|| TYPE_P (*tp
))
11559 *walk_subtrees
= 0;
11563 switch (TREE_CODE (*tp
))
11572 case ALIGN_INDIRECT_REF
:
11573 case MISALIGNED_INDIRECT_REF
:
11574 case VIEW_CONVERT_EXPR
:
11575 if (TYPE_MODE (TREE_TYPE (*tp
)) == SDmode
)
11586 /* Allocate a 64-bit stack slot to be used for copying SDmode
11587 values through if this function has any SDmode references. */
11590 rs6000_alloc_sdmode_stack_slot (void)
11594 gimple_stmt_iterator gsi
;
11596 gcc_assert (cfun
->machine
->sdmode_stack_slot
== NULL_RTX
);
11599 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
11601 tree ret
= walk_gimple_op (gsi_stmt (gsi
), rs6000_check_sdmode
, NULL
);
11604 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
11605 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
11611 /* Check for any SDmode parameters of the function. */
11612 for (t
= DECL_ARGUMENTS (cfun
->decl
); t
; t
= TREE_CHAIN (t
))
11614 if (TREE_TYPE (t
) == error_mark_node
)
11617 if (TYPE_MODE (TREE_TYPE (t
)) == SDmode
11618 || TYPE_MODE (DECL_ARG_TYPE (t
)) == SDmode
)
11620 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
11621 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
11629 rs6000_instantiate_decls (void)
11631 if (cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
11632 instantiate_decl_rtl (cfun
->machine
->sdmode_stack_slot
);
11635 /* Return the register class of a scratch register needed to copy IN into
11636 or out of a register in RCLASS in MODE. If it can be done directly,
11637 NO_REGS is returned. */
11640 rs6000_secondary_reload_class (enum reg_class rclass
,
11641 enum machine_mode mode ATTRIBUTE_UNUSED
,
11646 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
11648 && MACHOPIC_INDIRECT
11652 /* We cannot copy a symbolic operand directly into anything
11653 other than BASE_REGS for TARGET_ELF. So indicate that a
11654 register from BASE_REGS is needed as an intermediate
11657 On Darwin, pic addresses require a load from memory, which
11658 needs a base register. */
11659 if (rclass
!= BASE_REGS
11660 && (GET_CODE (in
) == SYMBOL_REF
11661 || GET_CODE (in
) == HIGH
11662 || GET_CODE (in
) == LABEL_REF
11663 || GET_CODE (in
) == CONST
))
11667 if (GET_CODE (in
) == REG
)
11669 regno
= REGNO (in
);
11670 if (regno
>= FIRST_PSEUDO_REGISTER
)
11672 regno
= true_regnum (in
);
11673 if (regno
>= FIRST_PSEUDO_REGISTER
)
11677 else if (GET_CODE (in
) == SUBREG
)
11679 regno
= true_regnum (in
);
11680 if (regno
>= FIRST_PSEUDO_REGISTER
)
11686 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
11688 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
11689 || (regno
>= 0 && INT_REGNO_P (regno
)))
11692 /* Constants, memory, and FP registers can go into FP registers. */
11693 if ((regno
== -1 || FP_REGNO_P (regno
))
11694 && (rclass
== FLOAT_REGS
|| rclass
== NON_SPECIAL_REGS
))
11695 return (mode
!= SDmode
) ? NO_REGS
: GENERAL_REGS
;
11697 /* Memory, and AltiVec registers can go into AltiVec registers. */
11698 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
11699 && rclass
== ALTIVEC_REGS
)
11702 /* We can copy among the CR registers. */
11703 if ((rclass
== CR_REGS
|| rclass
== CR0_REGS
)
11704 && regno
>= 0 && CR_REGNO_P (regno
))
11707 /* Otherwise, we need GENERAL_REGS. */
11708 return GENERAL_REGS
;
11711 /* Given a comparison operation, return the bit number in CCR to test. We
11712 know this is a valid comparison.
11714 SCC_P is 1 if this is for an scc. That means that %D will have been
11715 used instead of %C, so the bits will be in different places.
11717 Return -1 if OP isn't a valid comparison for some reason. */
11720 ccr_bit (rtx op
, int scc_p
)
11722 enum rtx_code code
= GET_CODE (op
);
11723 enum machine_mode cc_mode
;
11728 if (!COMPARISON_P (op
))
11731 reg
= XEXP (op
, 0);
11733 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
11735 cc_mode
= GET_MODE (reg
);
11736 cc_regnum
= REGNO (reg
);
11737 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
11739 validate_condition_mode (code
, cc_mode
);
11741 /* When generating a sCOND operation, only positive conditions are
11744 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
11745 || code
== GTU
|| code
== LTU
);
11750 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
11752 return base_bit
+ 2;
11753 case GT
: case GTU
: case UNLE
:
11754 return base_bit
+ 1;
11755 case LT
: case LTU
: case UNGE
:
11757 case ORDERED
: case UNORDERED
:
11758 return base_bit
+ 3;
11761 /* If scc, we will have done a cror to put the bit in the
11762 unordered position. So test that bit. For integer, this is ! LT
11763 unless this is an scc insn. */
11764 return scc_p
? base_bit
+ 3 : base_bit
;
11767 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
11770 gcc_unreachable ();
11774 /* Return the GOT register. */
11777 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
11779 /* The second flow pass currently (June 1999) can't update
11780 regs_ever_live without disturbing other parts of the compiler, so
11781 update it here to make the prolog/epilogue code happy. */
11782 if (!can_create_pseudo_p ()
11783 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
))
11784 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM
, true);
11786 crtl
->uses_pic_offset_table
= 1;
11788 return pic_offset_table_rtx
;
11791 /* Function to init struct machine_function.
11792 This will be called, via a pointer variable,
11793 from push_function_context. */
11795 static struct machine_function
*
11796 rs6000_init_machine_status (void)
11798 return GGC_CNEW (machine_function
);
11801 /* These macros test for integers and extract the low-order bits. */
11803 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
11804 && GET_MODE (X) == VOIDmode)
11806 #define INT_LOWPART(X) \
11807 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
11810 extract_MB (rtx op
)
11813 unsigned long val
= INT_LOWPART (op
);
11815 /* If the high bit is zero, the value is the first 1 bit we find
11817 if ((val
& 0x80000000) == 0)
11819 gcc_assert (val
& 0xffffffff);
11822 while (((val
<<= 1) & 0x80000000) == 0)
11827 /* If the high bit is set and the low bit is not, or the mask is all
11828 1's, the value is zero. */
11829 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
11832 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11835 while (((val
>>= 1) & 1) != 0)
11842 extract_ME (rtx op
)
11845 unsigned long val
= INT_LOWPART (op
);
11847 /* If the low bit is zero, the value is the first 1 bit we find from
11849 if ((val
& 1) == 0)
11851 gcc_assert (val
& 0xffffffff);
11854 while (((val
>>= 1) & 1) == 0)
11860 /* If the low bit is set and the high bit is not, or the mask is all
11861 1's, the value is 31. */
11862 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
11865 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11868 while (((val
<<= 1) & 0x80000000) != 0)
11874 /* Locate some local-dynamic symbol still in use by this function
11875 so that we can print its name in some tls_ld pattern. */
11877 static const char *
11878 rs6000_get_some_local_dynamic_name (void)
11882 if (cfun
->machine
->some_ld_name
)
11883 return cfun
->machine
->some_ld_name
;
11885 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
11887 && for_each_rtx (&PATTERN (insn
),
11888 rs6000_get_some_local_dynamic_name_1
, 0))
11889 return cfun
->machine
->some_ld_name
;
11891 gcc_unreachable ();
11894 /* Helper function for rs6000_get_some_local_dynamic_name. */
11897 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
11901 if (GET_CODE (x
) == SYMBOL_REF
)
11903 const char *str
= XSTR (x
, 0);
11904 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
11906 cfun
->machine
->some_ld_name
= str
;
11914 /* Write out a function code label. */
11917 rs6000_output_function_entry (FILE *file
, const char *fname
)
11919 if (fname
[0] != '.')
11921 switch (DEFAULT_ABI
)
11924 gcc_unreachable ();
11930 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
11939 RS6000_OUTPUT_BASENAME (file
, fname
);
11941 assemble_name (file
, fname
);
11944 /* Print an operand. Recognize special options, documented below. */
11947 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
11948 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
11950 #define SMALL_DATA_RELOC "sda21"
11951 #define SMALL_DATA_REG 0
11955 print_operand (FILE *file
, rtx x
, int code
)
11959 unsigned HOST_WIDE_INT uval
;
11964 /* Write out an instruction after the call which may be replaced
11965 with glue code by the loader. This depends on the AIX version. */
11966 asm_fprintf (file
, RS6000_CALL_GLUE
);
11969 /* %a is output_address. */
11972 /* If X is a constant integer whose low-order 5 bits are zero,
11973 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
11974 in the AIX assembler where "sri" with a zero shift count
11975 writes a trash instruction. */
11976 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
11983 /* If constant, low-order 16 bits of constant, unsigned.
11984 Otherwise, write normally. */
11986 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
11988 print_operand (file
, x
, 0);
11992 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
11993 for 64-bit mask direction. */
11994 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
11997 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
12001 /* X is a CR register. Print the number of the GT bit of the CR. */
12002 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
12003 output_operand_lossage ("invalid %%E value");
12005 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
12009 /* Like 'J' but get to the GT bit only. */
12010 gcc_assert (GET_CODE (x
) == REG
);
12012 /* Bit 1 is GT bit. */
12013 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 1;
12015 /* Add one for shift count in rlinm for scc. */
12016 fprintf (file
, "%d", i
+ 1);
12020 /* X is a CR register. Print the number of the EQ bit of the CR */
12021 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
12022 output_operand_lossage ("invalid %%E value");
12024 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
12028 /* X is a CR register. Print the shift count needed to move it
12029 to the high-order four bits. */
12030 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
12031 output_operand_lossage ("invalid %%f value");
12033 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
12037 /* Similar, but print the count for the rotate in the opposite
12039 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
12040 output_operand_lossage ("invalid %%F value");
12042 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
12046 /* X is a constant integer. If it is negative, print "m",
12047 otherwise print "z". This is to make an aze or ame insn. */
12048 if (GET_CODE (x
) != CONST_INT
)
12049 output_operand_lossage ("invalid %%G value");
12050 else if (INTVAL (x
) >= 0)
12057 /* If constant, output low-order five bits. Otherwise, write
12060 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
12062 print_operand (file
, x
, 0);
12066 /* If constant, output low-order six bits. Otherwise, write
12069 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
12071 print_operand (file
, x
, 0);
12075 /* Print `i' if this is a constant, else nothing. */
12081 /* Write the bit number in CCR for jump. */
12082 i
= ccr_bit (x
, 0);
12084 output_operand_lossage ("invalid %%j code");
12086 fprintf (file
, "%d", i
);
12090 /* Similar, but add one for shift count in rlinm for scc and pass
12091 scc flag to `ccr_bit'. */
12092 i
= ccr_bit (x
, 1);
12094 output_operand_lossage ("invalid %%J code");
12096 /* If we want bit 31, write a shift count of zero, not 32. */
12097 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
12101 /* X must be a constant. Write the 1's complement of the
12104 output_operand_lossage ("invalid %%k value");
12106 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
12110 /* X must be a symbolic constant on ELF. Write an
12111 expression suitable for an 'addi' that adds in the low 16
12112 bits of the MEM. */
12113 if (GET_CODE (x
) != CONST
)
12115 print_operand_address (file
, x
);
12116 fputs ("@l", file
);
12120 if (GET_CODE (XEXP (x
, 0)) != PLUS
12121 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
12122 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
12123 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
12124 output_operand_lossage ("invalid %%K value");
12125 print_operand_address (file
, XEXP (XEXP (x
, 0), 0));
12126 fputs ("@l", file
);
12127 /* For GNU as, there must be a non-alphanumeric character
12128 between 'l' and the number. The '-' is added by
12129 print_operand() already. */
12130 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
12132 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
12136 /* %l is output_asm_label. */
12139 /* Write second word of DImode or DFmode reference. Works on register
12140 or non-indexed memory only. */
12141 if (GET_CODE (x
) == REG
)
12142 fputs (reg_names
[REGNO (x
) + 1], file
);
12143 else if (GET_CODE (x
) == MEM
)
12145 /* Handle possible auto-increment. Since it is pre-increment and
12146 we have already done it, we can just use an offset of word. */
12147 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
12148 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12149 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
12151 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12152 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
12155 output_address (XEXP (adjust_address_nv (x
, SImode
,
12159 if (small_data_operand (x
, GET_MODE (x
)))
12160 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12161 reg_names
[SMALL_DATA_REG
]);
12166 /* MB value for a mask operand. */
12167 if (! mask_operand (x
, SImode
))
12168 output_operand_lossage ("invalid %%m value");
12170 fprintf (file
, "%d", extract_MB (x
));
12174 /* ME value for a mask operand. */
12175 if (! mask_operand (x
, SImode
))
12176 output_operand_lossage ("invalid %%M value");
12178 fprintf (file
, "%d", extract_ME (x
));
12181 /* %n outputs the negative of its operand. */
12184 /* Write the number of elements in the vector times 4. */
12185 if (GET_CODE (x
) != PARALLEL
)
12186 output_operand_lossage ("invalid %%N value");
12188 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
12192 /* Similar, but subtract 1 first. */
12193 if (GET_CODE (x
) != PARALLEL
)
12194 output_operand_lossage ("invalid %%O value");
12196 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
12200 /* X is a CONST_INT that is a power of two. Output the logarithm. */
12202 || INT_LOWPART (x
) < 0
12203 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
12204 output_operand_lossage ("invalid %%p value");
12206 fprintf (file
, "%d", i
);
12210 /* The operand must be an indirect memory reference. The result
12211 is the register name. */
12212 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
12213 || REGNO (XEXP (x
, 0)) >= 32)
12214 output_operand_lossage ("invalid %%P value");
12216 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
12220 /* This outputs the logical code corresponding to a boolean
12221 expression. The expression may have one or both operands
12222 negated (if one, only the first one). For condition register
12223 logical operations, it will also treat the negated
12224 CR codes as NOTs, but not handle NOTs of them. */
12226 const char *const *t
= 0;
12228 enum rtx_code code
= GET_CODE (x
);
12229 static const char * const tbl
[3][3] = {
12230 { "and", "andc", "nor" },
12231 { "or", "orc", "nand" },
12232 { "xor", "eqv", "xor" } };
12236 else if (code
== IOR
)
12238 else if (code
== XOR
)
12241 output_operand_lossage ("invalid %%q value");
12243 if (GET_CODE (XEXP (x
, 0)) != NOT
)
12247 if (GET_CODE (XEXP (x
, 1)) == NOT
)
12265 /* X is a CR register. Print the mask for `mtcrf'. */
12266 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
12267 output_operand_lossage ("invalid %%R value");
12269 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
12273 /* Low 5 bits of 32 - value */
12275 output_operand_lossage ("invalid %%s value");
12277 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
12281 /* PowerPC64 mask position. All 0's is excluded.
12282 CONST_INT 32-bit mask is considered sign-extended so any
12283 transition must occur within the CONST_INT, not on the boundary. */
12284 if (! mask64_operand (x
, DImode
))
12285 output_operand_lossage ("invalid %%S value");
12287 uval
= INT_LOWPART (x
);
12289 if (uval
& 1) /* Clear Left */
12291 #if HOST_BITS_PER_WIDE_INT > 64
12292 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
12296 else /* Clear Right */
12299 #if HOST_BITS_PER_WIDE_INT > 64
12300 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
12306 gcc_assert (i
>= 0);
12307 fprintf (file
, "%d", i
);
12311 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
12312 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
12314 /* Bit 3 is OV bit. */
12315 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
12317 /* If we want bit 31, write a shift count of zero, not 32. */
12318 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
12322 /* Print the symbolic name of a branch target register. */
12323 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LR_REGNO
12324 && REGNO (x
) != CTR_REGNO
))
12325 output_operand_lossage ("invalid %%T value");
12326 else if (REGNO (x
) == LR_REGNO
)
12327 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
12329 fputs ("ctr", file
);
12333 /* High-order 16 bits of constant for use in unsigned operand. */
12335 output_operand_lossage ("invalid %%u value");
12337 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
12338 (INT_LOWPART (x
) >> 16) & 0xffff);
12342 /* High-order 16 bits of constant for use in signed operand. */
12344 output_operand_lossage ("invalid %%v value");
12346 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
12347 (INT_LOWPART (x
) >> 16) & 0xffff);
12351 /* Print `u' if this has an auto-increment or auto-decrement. */
12352 if (GET_CODE (x
) == MEM
12353 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
12354 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
12355 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
))
12360 /* Print the trap code for this operand. */
12361 switch (GET_CODE (x
))
12364 fputs ("eq", file
); /* 4 */
12367 fputs ("ne", file
); /* 24 */
12370 fputs ("lt", file
); /* 16 */
12373 fputs ("le", file
); /* 20 */
12376 fputs ("gt", file
); /* 8 */
12379 fputs ("ge", file
); /* 12 */
12382 fputs ("llt", file
); /* 2 */
12385 fputs ("lle", file
); /* 6 */
12388 fputs ("lgt", file
); /* 1 */
12391 fputs ("lge", file
); /* 5 */
12394 gcc_unreachable ();
12399 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
12402 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
12403 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
12405 print_operand (file
, x
, 0);
12409 /* MB value for a PowerPC64 rldic operand. */
12410 val
= (GET_CODE (x
) == CONST_INT
12411 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
12416 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
12417 if ((val
<<= 1) < 0)
12420 #if HOST_BITS_PER_WIDE_INT == 32
12421 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
12422 i
+= 32; /* zero-extend high-part was all 0's */
12423 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
12425 val
= CONST_DOUBLE_LOW (x
);
12431 for ( ; i
< 64; i
++)
12432 if ((val
<<= 1) < 0)
12437 fprintf (file
, "%d", i
+ 1);
12441 if (GET_CODE (x
) == MEM
12442 && (legitimate_indexed_address_p (XEXP (x
, 0), 0)
12443 || (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
12444 && legitimate_indexed_address_p (XEXP (XEXP (x
, 0), 1), 0))))
12449 /* Like 'L', for third word of TImode */
12450 if (GET_CODE (x
) == REG
)
12451 fputs (reg_names
[REGNO (x
) + 2], file
);
12452 else if (GET_CODE (x
) == MEM
)
12454 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
12455 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12456 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
12457 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12458 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
12460 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
12461 if (small_data_operand (x
, GET_MODE (x
)))
12462 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12463 reg_names
[SMALL_DATA_REG
]);
12468 /* X is a SYMBOL_REF. Write out the name preceded by a
12469 period and without any trailing data in brackets. Used for function
12470 names. If we are configured for System V (or the embedded ABI) on
12471 the PowerPC, do not emit the period, since those systems do not use
12472 TOCs and the like. */
12473 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
12475 /* Mark the decl as referenced so that cgraph will output the
12477 if (SYMBOL_REF_DECL (x
))
12478 mark_decl_referenced (SYMBOL_REF_DECL (x
));
12480 /* For macho, check to see if we need a stub. */
12483 const char *name
= XSTR (x
, 0);
12485 if (MACHOPIC_INDIRECT
12486 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
12487 name
= machopic_indirection_name (x
, /*stub_p=*/true);
12489 assemble_name (file
, name
);
12491 else if (!DOT_SYMBOLS
)
12492 assemble_name (file
, XSTR (x
, 0));
12494 rs6000_output_function_entry (file
, XSTR (x
, 0));
12498 /* Like 'L', for last word of TImode. */
12499 if (GET_CODE (x
) == REG
)
12500 fputs (reg_names
[REGNO (x
) + 3], file
);
12501 else if (GET_CODE (x
) == MEM
)
12503 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
12504 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12505 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
12506 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12507 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
12509 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
12510 if (small_data_operand (x
, GET_MODE (x
)))
12511 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12512 reg_names
[SMALL_DATA_REG
]);
12516 /* Print AltiVec or SPE memory operand. */
12521 gcc_assert (GET_CODE (x
) == MEM
);
12525 /* Ugly hack because %y is overloaded. */
12526 if ((TARGET_SPE
|| TARGET_E500_DOUBLE
)
12527 && (GET_MODE_SIZE (GET_MODE (x
)) == 8
12528 || GET_MODE (x
) == TFmode
12529 || GET_MODE (x
) == TImode
))
12531 /* Handle [reg]. */
12532 if (GET_CODE (tmp
) == REG
)
12534 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
12537 /* Handle [reg+UIMM]. */
12538 else if (GET_CODE (tmp
) == PLUS
&&
12539 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
12543 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
12545 x
= INTVAL (XEXP (tmp
, 1));
12546 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
12550 /* Fall through. Must be [reg+reg]. */
12553 && GET_CODE (tmp
) == AND
12554 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
12555 && INTVAL (XEXP (tmp
, 1)) == -16)
12556 tmp
= XEXP (tmp
, 0);
12557 if (GET_CODE (tmp
) == REG
)
12558 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
12561 if (!GET_CODE (tmp
) == PLUS
12562 || !REG_P (XEXP (tmp
, 0))
12563 || !REG_P (XEXP (tmp
, 1)))
12565 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
12569 if (REGNO (XEXP (tmp
, 0)) == 0)
12570 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
12571 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
12573 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
12574 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
12580 if (GET_CODE (x
) == REG
)
12581 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
12582 else if (GET_CODE (x
) == MEM
)
12584 /* We need to handle PRE_INC and PRE_DEC here, since we need to
12585 know the width from the mode. */
12586 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
12587 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
12588 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
12589 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12590 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
12591 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
12592 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12593 output_address (XEXP (XEXP (x
, 0), 1));
12595 output_address (XEXP (x
, 0));
12598 output_addr_const (file
, x
);
12602 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
12606 output_operand_lossage ("invalid %%xn code");
12610 /* Print the address of an operand. */
12613 print_operand_address (FILE *file
, rtx x
)
12615 if (GET_CODE (x
) == REG
)
12616 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
12617 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
12618 || GET_CODE (x
) == LABEL_REF
)
12620 output_addr_const (file
, x
);
12621 if (small_data_operand (x
, GET_MODE (x
)))
12622 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12623 reg_names
[SMALL_DATA_REG
]);
12625 gcc_assert (!TARGET_TOC
);
12627 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
12629 gcc_assert (REG_P (XEXP (x
, 0)));
12630 if (REGNO (XEXP (x
, 0)) == 0)
12631 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
12632 reg_names
[ REGNO (XEXP (x
, 0)) ]);
12634 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
12635 reg_names
[ REGNO (XEXP (x
, 1)) ]);
12637 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
12638 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
12639 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
12641 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
12642 && CONSTANT_P (XEXP (x
, 1)))
12644 output_addr_const (file
, XEXP (x
, 1));
12645 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
12649 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
12650 && CONSTANT_P (XEXP (x
, 1)))
12652 fprintf (file
, "lo16(");
12653 output_addr_const (file
, XEXP (x
, 1));
12654 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
12657 else if (legitimate_constant_pool_address_p (x
))
12659 output_addr_const (file
, XEXP (x
, 1));
12660 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
12663 gcc_unreachable ();
12666 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
12669 rs6000_output_addr_const_extra (FILE *file
, rtx x
)
12671 if (GET_CODE (x
) == UNSPEC
)
12672 switch (XINT (x
, 1))
12674 case UNSPEC_TOCREL
:
12675 x
= XVECEXP (x
, 0, 0);
12676 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
12677 output_addr_const (file
, x
);
12678 if (!TARGET_AIX
|| (TARGET_ELF
&& TARGET_MINIMAL_TOC
))
12681 assemble_name (file
, toc_label_name
);
12683 else if (TARGET_ELF
)
12684 fputs ("@toc", file
);
12688 case UNSPEC_MACHOPIC_OFFSET
:
12689 output_addr_const (file
, XVECEXP (x
, 0, 0));
12691 machopic_output_function_base_name (file
);
12698 /* Target hook for assembling integer objects. The PowerPC version has
12699 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
12700 is defined. It also needs to handle DI-mode objects on 64-bit
12704 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
12706 #ifdef RELOCATABLE_NEEDS_FIXUP
12707 /* Special handling for SI values. */
12708 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
12710 static int recurse
= 0;
12712 /* For -mrelocatable, we mark all addresses that need to be fixed up
12713 in the .fixup section. */
12714 if (TARGET_RELOCATABLE
12715 && in_section
!= toc_section
12716 && in_section
!= text_section
12717 && !unlikely_text_section_p (in_section
)
12719 && GET_CODE (x
) != CONST_INT
12720 && GET_CODE (x
) != CONST_DOUBLE
12726 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
12728 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
12729 fprintf (asm_out_file
, "\t.long\t(");
12730 output_addr_const (asm_out_file
, x
);
12731 fprintf (asm_out_file
, ")@fixup\n");
12732 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
12733 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
12734 fprintf (asm_out_file
, "\t.long\t");
12735 assemble_name (asm_out_file
, buf
);
12736 fprintf (asm_out_file
, "\n\t.previous\n");
12740 /* Remove initial .'s to turn a -mcall-aixdesc function
12741 address into the address of the descriptor, not the function
12743 else if (GET_CODE (x
) == SYMBOL_REF
12744 && XSTR (x
, 0)[0] == '.'
12745 && DEFAULT_ABI
== ABI_AIX
)
12747 const char *name
= XSTR (x
, 0);
12748 while (*name
== '.')
12751 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
12755 #endif /* RELOCATABLE_NEEDS_FIXUP */
12756 return default_assemble_integer (x
, size
, aligned_p
);
12759 #ifdef HAVE_GAS_HIDDEN
12760 /* Emit an assembler directive to set symbol visibility for DECL to
12761 VISIBILITY_TYPE. */
12764 rs6000_assemble_visibility (tree decl
, int vis
)
12766 /* Functions need to have their entry point symbol visibility set as
12767 well as their descriptor symbol visibility. */
12768 if (DEFAULT_ABI
== ABI_AIX
12770 && TREE_CODE (decl
) == FUNCTION_DECL
)
12772 static const char * const visibility_types
[] = {
12773 NULL
, "internal", "hidden", "protected"
12776 const char *name
, *type
;
12778 name
= ((* targetm
.strip_name_encoding
)
12779 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
12780 type
= visibility_types
[vis
];
12782 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
12783 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
12786 default_assemble_visibility (decl
, vis
);
12791 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
12793 /* Reversal of FP compares takes care -- an ordered compare
12794 becomes an unordered compare and vice versa. */
12795 if (mode
== CCFPmode
12796 && (!flag_finite_math_only
12797 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
12798 || code
== UNEQ
|| code
== LTGT
))
12799 return reverse_condition_maybe_unordered (code
);
12801 return reverse_condition (code
);
12804 /* Generate a compare for CODE. Return a brand-new rtx that
12805 represents the result of the compare. */
12808 rs6000_generate_compare (rtx cmp
, enum machine_mode mode
)
12810 enum machine_mode comp_mode
;
12811 rtx compare_result
;
12812 enum rtx_code code
= GET_CODE (cmp
);
12813 rtx op0
= XEXP (cmp
, 0);
12814 rtx op1
= XEXP (cmp
, 1);
12816 if (FLOAT_MODE_P (mode
))
12817 comp_mode
= CCFPmode
;
12818 else if (code
== GTU
|| code
== LTU
12819 || code
== GEU
|| code
== LEU
)
12820 comp_mode
= CCUNSmode
;
12821 else if ((code
== EQ
|| code
== NE
)
12822 && GET_CODE (op0
) == SUBREG
12823 && GET_CODE (op1
) == SUBREG
12824 && SUBREG_PROMOTED_UNSIGNED_P (op0
)
12825 && SUBREG_PROMOTED_UNSIGNED_P (op1
))
12826 /* These are unsigned values, perhaps there will be a later
12827 ordering compare that can be shared with this one.
12828 Unfortunately we cannot detect the signedness of the operands
12829 for non-subregs. */
12830 comp_mode
= CCUNSmode
;
12832 comp_mode
= CCmode
;
12834 /* First, the compare. */
12835 compare_result
= gen_reg_rtx (comp_mode
);
12837 /* E500 FP compare instructions on the GPRs. Yuck! */
12838 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
)
12839 && FLOAT_MODE_P (mode
))
12841 rtx cmp
, or_result
, compare_result2
;
12842 enum machine_mode op_mode
= GET_MODE (op0
);
12844 if (op_mode
== VOIDmode
)
12845 op_mode
= GET_MODE (op1
);
12847 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
12848 This explains the following mess. */
12852 case EQ
: case UNEQ
: case NE
: case LTGT
:
12856 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12857 ? gen_tstsfeq_gpr (compare_result
, op0
, op1
)
12858 : gen_cmpsfeq_gpr (compare_result
, op0
, op1
);
12862 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12863 ? gen_tstdfeq_gpr (compare_result
, op0
, op1
)
12864 : gen_cmpdfeq_gpr (compare_result
, op0
, op1
);
12868 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12869 ? gen_tsttfeq_gpr (compare_result
, op0
, op1
)
12870 : gen_cmptfeq_gpr (compare_result
, op0
, op1
);
12874 gcc_unreachable ();
12878 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
12882 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12883 ? gen_tstsfgt_gpr (compare_result
, op0
, op1
)
12884 : gen_cmpsfgt_gpr (compare_result
, op0
, op1
);
12888 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12889 ? gen_tstdfgt_gpr (compare_result
, op0
, op1
)
12890 : gen_cmpdfgt_gpr (compare_result
, op0
, op1
);
12894 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12895 ? gen_tsttfgt_gpr (compare_result
, op0
, op1
)
12896 : gen_cmptfgt_gpr (compare_result
, op0
, op1
);
12900 gcc_unreachable ();
12904 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
12908 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12909 ? gen_tstsflt_gpr (compare_result
, op0
, op1
)
12910 : gen_cmpsflt_gpr (compare_result
, op0
, op1
);
12914 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12915 ? gen_tstdflt_gpr (compare_result
, op0
, op1
)
12916 : gen_cmpdflt_gpr (compare_result
, op0
, op1
);
12920 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12921 ? gen_tsttflt_gpr (compare_result
, op0
, op1
)
12922 : gen_cmptflt_gpr (compare_result
, op0
, op1
);
12926 gcc_unreachable ();
12930 gcc_unreachable ();
12933 /* Synthesize LE and GE from LT/GT || EQ. */
12934 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
12940 case LE
: code
= LT
; break;
12941 case GE
: code
= GT
; break;
12942 case LEU
: code
= LT
; break;
12943 case GEU
: code
= GT
; break;
12944 default: gcc_unreachable ();
12947 compare_result2
= gen_reg_rtx (CCFPmode
);
12953 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12954 ? gen_tstsfeq_gpr (compare_result2
, op0
, op1
)
12955 : gen_cmpsfeq_gpr (compare_result2
, op0
, op1
);
12959 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12960 ? gen_tstdfeq_gpr (compare_result2
, op0
, op1
)
12961 : gen_cmpdfeq_gpr (compare_result2
, op0
, op1
);
12965 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12966 ? gen_tsttfeq_gpr (compare_result2
, op0
, op1
)
12967 : gen_cmptfeq_gpr (compare_result2
, op0
, op1
);
12971 gcc_unreachable ();
12975 /* OR them together. */
12976 or_result
= gen_reg_rtx (CCFPmode
);
12977 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
12979 compare_result
= or_result
;
12984 if (code
== NE
|| code
== LTGT
)
12994 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
12995 CLOBBERs to match cmptf_internal2 pattern. */
12996 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
12997 && GET_MODE (op0
) == TFmode
12998 && !TARGET_IEEEQUAD
12999 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
13000 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
13002 gen_rtx_SET (VOIDmode
,
13004 gen_rtx_COMPARE (comp_mode
, op0
, op1
)),
13005 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
13006 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
13007 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
13008 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
13009 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
13010 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
13011 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
13012 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)))));
13013 else if (GET_CODE (op1
) == UNSPEC
13014 && XINT (op1
, 1) == UNSPEC_SP_TEST
)
13016 rtx op1b
= XVECEXP (op1
, 0, 0);
13017 comp_mode
= CCEQmode
;
13018 compare_result
= gen_reg_rtx (CCEQmode
);
13020 emit_insn (gen_stack_protect_testdi (compare_result
, op0
, op1b
));
13022 emit_insn (gen_stack_protect_testsi (compare_result
, op0
, op1b
));
13025 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
13026 gen_rtx_COMPARE (comp_mode
, op0
, op1
)));
13029 /* Some kinds of FP comparisons need an OR operation;
13030 under flag_finite_math_only we don't bother. */
13031 if (FLOAT_MODE_P (mode
)
13032 && !flag_finite_math_only
13033 && !(TARGET_HARD_FLOAT
&& !TARGET_FPRS
)
13034 && (code
== LE
|| code
== GE
13035 || code
== UNEQ
|| code
== LTGT
13036 || code
== UNGT
|| code
== UNLT
))
13038 enum rtx_code or1
, or2
;
13039 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
13040 rtx or_result
= gen_reg_rtx (CCEQmode
);
13044 case LE
: or1
= LT
; or2
= EQ
; break;
13045 case GE
: or1
= GT
; or2
= EQ
; break;
13046 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
13047 case LTGT
: or1
= LT
; or2
= GT
; break;
13048 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
13049 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
13050 default: gcc_unreachable ();
13052 validate_condition_mode (or1
, comp_mode
);
13053 validate_condition_mode (or2
, comp_mode
);
13054 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
13055 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
13056 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
13057 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
13059 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
13061 compare_result
= or_result
;
13065 validate_condition_mode (code
, GET_MODE (compare_result
));
13067 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
13071 /* Emit the RTL for an sCOND pattern. */
13074 rs6000_emit_sCOND (enum machine_mode mode
, rtx operands
[])
13077 enum machine_mode op_mode
;
13078 enum rtx_code cond_code
;
13079 rtx result
= operands
[0];
13081 condition_rtx
= rs6000_generate_compare (operands
[1], mode
);
13082 cond_code
= GET_CODE (condition_rtx
);
13084 if (FLOAT_MODE_P (mode
)
13085 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
13089 PUT_MODE (condition_rtx
, SImode
);
13090 t
= XEXP (condition_rtx
, 0);
13092 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
13094 if (cond_code
== NE
)
13095 emit_insn (gen_e500_flip_gt_bit (t
, t
));
13097 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
13101 if (cond_code
== NE
13102 || cond_code
== GE
|| cond_code
== LE
13103 || cond_code
== GEU
|| cond_code
== LEU
13104 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
13106 rtx not_result
= gen_reg_rtx (CCEQmode
);
13107 rtx not_op
, rev_cond_rtx
;
13108 enum machine_mode cc_mode
;
13110 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
13112 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
13113 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
13114 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
13115 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
13116 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
13119 op_mode
= GET_MODE (XEXP (operands
[1], 0));
13120 if (op_mode
== VOIDmode
)
13121 op_mode
= GET_MODE (XEXP (operands
[1], 1));
13123 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| FLOAT_MODE_P (mode
)))
13125 PUT_MODE (condition_rtx
, DImode
);
13126 convert_move (result
, condition_rtx
, 0);
13130 PUT_MODE (condition_rtx
, SImode
);
13131 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
13135 /* Emit a branch of kind CODE to location LOC. */
13138 rs6000_emit_cbranch (enum machine_mode mode
, rtx operands
[])
13140 rtx condition_rtx
, loc_ref
;
13142 condition_rtx
= rs6000_generate_compare (operands
[0], mode
);
13143 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
13144 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
13145 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
13146 loc_ref
, pc_rtx
)));
13149 /* Return the string to output a conditional branch to LABEL, which is
13150 the operand number of the label, or -1 if the branch is really a
13151 conditional return.
13153 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
13154 condition code register and its mode specifies what kind of
13155 comparison we made.
13157 REVERSED is nonzero if we should reverse the sense of the comparison.
13159 INSN is the insn. */
13162 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
13164 static char string
[64];
13165 enum rtx_code code
= GET_CODE (op
);
13166 rtx cc_reg
= XEXP (op
, 0);
13167 enum machine_mode mode
= GET_MODE (cc_reg
);
13168 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
13169 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
13170 int really_reversed
= reversed
^ need_longbranch
;
13176 validate_condition_mode (code
, mode
);
13178 /* Work out which way this really branches. We could use
13179 reverse_condition_maybe_unordered here always but this
13180 makes the resulting assembler clearer. */
13181 if (really_reversed
)
13183 /* Reversal of FP compares takes care -- an ordered compare
13184 becomes an unordered compare and vice versa. */
13185 if (mode
== CCFPmode
)
13186 code
= reverse_condition_maybe_unordered (code
);
13188 code
= reverse_condition (code
);
13191 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
13193 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
13198 /* Opposite of GT. */
13207 gcc_unreachable ();
13213 /* Not all of these are actually distinct opcodes, but
13214 we distinguish them for clarity of the resulting assembler. */
13215 case NE
: case LTGT
:
13216 ccode
= "ne"; break;
13217 case EQ
: case UNEQ
:
13218 ccode
= "eq"; break;
13220 ccode
= "ge"; break;
13221 case GT
: case GTU
: case UNGT
:
13222 ccode
= "gt"; break;
13224 ccode
= "le"; break;
13225 case LT
: case LTU
: case UNLT
:
13226 ccode
= "lt"; break;
13227 case UNORDERED
: ccode
= "un"; break;
13228 case ORDERED
: ccode
= "nu"; break;
13229 case UNGE
: ccode
= "nl"; break;
13230 case UNLE
: ccode
= "ng"; break;
13232 gcc_unreachable ();
13235 /* Maybe we have a guess as to how likely the branch is.
13236 The old mnemonics don't have a way to specify this information. */
13238 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
13239 if (note
!= NULL_RTX
)
13241 /* PROB is the difference from 50%. */
13242 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
13244 /* Only hint for highly probable/improbable branches on newer
13245 cpus as static prediction overrides processor dynamic
13246 prediction. For older cpus we may as well always hint, but
13247 assume not taken for branches that are very close to 50% as a
13248 mispredicted taken branch is more expensive than a
13249 mispredicted not-taken branch. */
13250 if (rs6000_always_hint
13251 || (abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48
13252 && br_prob_note_reliable_p (note
)))
13254 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
13255 && ((prob
> 0) ^ need_longbranch
))
13263 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
13265 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
13267 /* We need to escape any '%' characters in the reg_names string.
13268 Assume they'd only be the first character.... */
13269 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
13271 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
13275 /* If the branch distance was too far, we may have to use an
13276 unconditional branch to go the distance. */
13277 if (need_longbranch
)
13278 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
13280 s
+= sprintf (s
, ",%s", label
);
13286 /* Return the string to flip the GT bit on a CR. */
13288 output_e500_flip_gt_bit (rtx dst
, rtx src
)
13290 static char string
[64];
13293 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
13294 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
13297 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
13298 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
13300 sprintf (string
, "crnot %d,%d", a
, b
);
13304 /* Return insn index for the vector compare instruction for given CODE,
13305 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
13309 get_vec_cmp_insn (enum rtx_code code
,
13310 enum machine_mode dest_mode
,
13311 enum machine_mode op_mode
)
13313 if (!TARGET_ALTIVEC
)
13314 return INSN_NOT_AVAILABLE
;
13319 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
13320 return UNSPEC_VCMPEQUB
;
13321 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
13322 return UNSPEC_VCMPEQUH
;
13323 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
13324 return UNSPEC_VCMPEQUW
;
13325 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
13326 return UNSPEC_VCMPEQFP
;
13329 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
13330 return UNSPEC_VCMPGEFP
;
13332 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
13333 return UNSPEC_VCMPGTSB
;
13334 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
13335 return UNSPEC_VCMPGTSH
;
13336 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
13337 return UNSPEC_VCMPGTSW
;
13338 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
13339 return UNSPEC_VCMPGTFP
;
13342 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
13343 return UNSPEC_VCMPGTUB
;
13344 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
13345 return UNSPEC_VCMPGTUH
;
13346 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
13347 return UNSPEC_VCMPGTUW
;
13352 return INSN_NOT_AVAILABLE
;
13355 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
13356 DMODE is expected destination mode. This is a recursive function. */
13359 rs6000_emit_vector_compare (enum rtx_code rcode
,
13361 enum machine_mode dmode
)
13365 enum machine_mode dest_mode
;
13366 enum machine_mode op_mode
= GET_MODE (op1
);
13368 gcc_assert (TARGET_ALTIVEC
);
13369 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
13371 /* Floating point vector compare instructions uses destination V4SImode.
13372 Move destination to appropriate mode later. */
13373 if (dmode
== V4SFmode
)
13374 dest_mode
= V4SImode
;
13378 mask
= gen_reg_rtx (dest_mode
);
13379 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
13381 if (vec_cmp_insn
== INSN_NOT_AVAILABLE
)
13383 bool swap_operands
= false;
13384 bool try_again
= false;
13389 swap_operands
= true;
13394 swap_operands
= true;
13402 /* Invert condition and try again.
13403 e.g., A != B becomes ~(A==B). */
13405 enum rtx_code rev_code
;
13406 enum insn_code nor_code
;
13409 rev_code
= reverse_condition_maybe_unordered (rcode
);
13410 eq_rtx
= rs6000_emit_vector_compare (rev_code
, op0
, op1
,
13413 nor_code
= optab_handler (one_cmpl_optab
, (int)dest_mode
)->insn_code
;
13414 gcc_assert (nor_code
!= CODE_FOR_nothing
);
13415 emit_insn (GEN_FCN (nor_code
) (mask
, eq_rtx
));
13417 if (dmode
!= dest_mode
)
13419 rtx temp
= gen_reg_rtx (dest_mode
);
13420 convert_move (temp
, mask
, 0);
13430 /* Try GT/GTU/LT/LTU OR EQ */
13433 enum insn_code ior_code
;
13434 enum rtx_code new_code
;
13455 gcc_unreachable ();
13458 c_rtx
= rs6000_emit_vector_compare (new_code
,
13459 op0
, op1
, dest_mode
);
13460 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
,
13463 ior_code
= optab_handler (ior_optab
, (int)dest_mode
)->insn_code
;
13464 gcc_assert (ior_code
!= CODE_FOR_nothing
);
13465 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
13466 if (dmode
!= dest_mode
)
13468 rtx temp
= gen_reg_rtx (dest_mode
);
13469 convert_move (temp
, mask
, 0);
13476 gcc_unreachable ();
13481 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
13482 /* You only get two chances. */
13483 gcc_assert (vec_cmp_insn
!= INSN_NOT_AVAILABLE
);
13495 emit_insn (gen_rtx_SET (VOIDmode
, mask
,
13496 gen_rtx_UNSPEC (dest_mode
,
13497 gen_rtvec (2, op0
, op1
),
13499 if (dmode
!= dest_mode
)
13501 rtx temp
= gen_reg_rtx (dest_mode
);
13502 convert_move (temp
, mask
, 0);
13508 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
13509 valid insn doesn exist for given mode. */
13512 get_vsel_insn (enum machine_mode mode
)
13517 return UNSPEC_VSEL4SI
;
13520 return UNSPEC_VSEL4SF
;
13523 return UNSPEC_VSEL8HI
;
13526 return UNSPEC_VSEL16QI
;
13529 return INSN_NOT_AVAILABLE
;
13532 return INSN_NOT_AVAILABLE
;
13535 /* Emit vector select insn where DEST is destination using
13536 operands OP1, OP2 and MASK. */
13539 rs6000_emit_vector_select (rtx dest
, rtx op1
, rtx op2
, rtx mask
)
13542 enum machine_mode dest_mode
= GET_MODE (dest
);
13543 int vsel_insn_index
= get_vsel_insn (GET_MODE (dest
));
13545 temp
= gen_reg_rtx (dest_mode
);
13547 /* For each vector element, select op1 when mask is 1 otherwise
13549 t
= gen_rtx_SET (VOIDmode
, temp
,
13550 gen_rtx_UNSPEC (dest_mode
,
13551 gen_rtvec (3, op2
, op1
, mask
),
13554 emit_move_insn (dest
, temp
);
13558 /* Emit vector conditional expression.
13559 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
13560 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
13563 rs6000_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
13564 rtx cond
, rtx cc_op0
, rtx cc_op1
)
13566 enum machine_mode dest_mode
= GET_MODE (dest
);
13567 enum rtx_code rcode
= GET_CODE (cond
);
13570 if (!TARGET_ALTIVEC
)
13573 /* Get the vector mask for the given relational operations. */
13574 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
13576 rs6000_emit_vector_select (dest
, op1
, op2
, mask
);
13581 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
13582 operands of the last comparison is nonzero/true, FALSE_COND if it
13583 is zero/false. Return 0 if the hardware has no such operation. */
13586 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
13588 enum rtx_code code
= GET_CODE (op
);
13589 rtx op0
= XEXP (op
, 0);
13590 rtx op1
= XEXP (op
, 1);
13591 REAL_VALUE_TYPE c1
;
13592 enum machine_mode compare_mode
= GET_MODE (op0
);
13593 enum machine_mode result_mode
= GET_MODE (dest
);
13595 bool is_against_zero
;
13597 /* These modes should always match. */
13598 if (GET_MODE (op1
) != compare_mode
13599 /* In the isel case however, we can use a compare immediate, so
13600 op1 may be a small constant. */
13601 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
13603 if (GET_MODE (true_cond
) != result_mode
)
13605 if (GET_MODE (false_cond
) != result_mode
)
13608 /* First, work out if the hardware can do this at all, or
13609 if it's too slow.... */
13610 if (!FLOAT_MODE_P (compare_mode
))
13613 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
13616 else if (TARGET_HARD_FLOAT
&& !TARGET_FPRS
13617 && SCALAR_FLOAT_MODE_P (compare_mode
))
13620 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
13622 /* A floating-point subtract might overflow, underflow, or produce
13623 an inexact result, thus changing the floating-point flags, so it
13624 can't be generated if we care about that. It's safe if one side
13625 of the construct is zero, since then no subtract will be
13627 if (SCALAR_FLOAT_MODE_P (compare_mode
)
13628 && flag_trapping_math
&& ! is_against_zero
)
13631 /* Eliminate half of the comparisons by switching operands, this
13632 makes the remaining code simpler. */
13633 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
13634 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
13636 code
= reverse_condition_maybe_unordered (code
);
13638 true_cond
= false_cond
;
13642 /* UNEQ and LTGT take four instructions for a comparison with zero,
13643 it'll probably be faster to use a branch here too. */
13644 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
13647 if (GET_CODE (op1
) == CONST_DOUBLE
)
13648 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
13650 /* We're going to try to implement comparisons by performing
13651 a subtract, then comparing against zero. Unfortunately,
13652 Inf - Inf is NaN which is not zero, and so if we don't
13653 know that the operand is finite and the comparison
13654 would treat EQ different to UNORDERED, we can't do it. */
13655 if (HONOR_INFINITIES (compare_mode
)
13656 && code
!= GT
&& code
!= UNGE
13657 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
13658 /* Constructs of the form (a OP b ? a : b) are safe. */
13659 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
13660 || (! rtx_equal_p (op0
, true_cond
)
13661 && ! rtx_equal_p (op1
, true_cond
))))
13664 /* At this point we know we can use fsel. */
13666 /* Reduce the comparison to a comparison against zero. */
13667 if (! is_against_zero
)
13669 temp
= gen_reg_rtx (compare_mode
);
13670 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13671 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
13673 op1
= CONST0_RTX (compare_mode
);
13676 /* If we don't care about NaNs we can reduce some of the comparisons
13677 down to faster ones. */
13678 if (! HONOR_NANS (compare_mode
))
13684 true_cond
= false_cond
;
13697 /* Now, reduce everything down to a GE. */
13704 temp
= gen_reg_rtx (compare_mode
);
13705 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
13710 temp
= gen_reg_rtx (compare_mode
);
13711 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
13716 temp
= gen_reg_rtx (compare_mode
);
13717 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13718 gen_rtx_NEG (compare_mode
,
13719 gen_rtx_ABS (compare_mode
, op0
))));
13724 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
13725 temp
= gen_reg_rtx (result_mode
);
13726 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13727 gen_rtx_IF_THEN_ELSE (result_mode
,
13728 gen_rtx_GE (VOIDmode
,
13730 true_cond
, false_cond
)));
13731 false_cond
= true_cond
;
13734 temp
= gen_reg_rtx (compare_mode
);
13735 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
13740 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
13741 temp
= gen_reg_rtx (result_mode
);
13742 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13743 gen_rtx_IF_THEN_ELSE (result_mode
,
13744 gen_rtx_GE (VOIDmode
,
13746 true_cond
, false_cond
)));
13747 true_cond
= false_cond
;
13750 temp
= gen_reg_rtx (compare_mode
);
13751 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
13756 gcc_unreachable ();
13759 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
13760 gen_rtx_IF_THEN_ELSE (result_mode
,
13761 gen_rtx_GE (VOIDmode
,
13763 true_cond
, false_cond
)));
13767 /* Same as above, but for ints (isel). */
13770 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
13772 rtx condition_rtx
, cr
;
13774 /* All isel implementations thus far are 32-bits. */
13775 if (GET_MODE (XEXP (op
, 0)) != SImode
)
13778 /* We still have to do the compare, because isel doesn't do a
13779 compare, it just looks at the CRx bits set by a previous compare
13781 condition_rtx
= rs6000_generate_compare (op
, SImode
);
13782 cr
= XEXP (condition_rtx
, 0);
13784 if (GET_MODE (cr
) == CCmode
)
13785 emit_insn (gen_isel_signed (dest
, condition_rtx
,
13786 true_cond
, false_cond
, cr
));
13788 emit_insn (gen_isel_unsigned (dest
, condition_rtx
,
13789 true_cond
, false_cond
, cr
));
13795 output_isel (rtx
*operands
)
13797 enum rtx_code code
;
13799 code
= GET_CODE (operands
[1]);
13800 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
13802 PUT_CODE (operands
[1], reverse_condition (code
));
13803 return "isel %0,%3,%2,%j1";
13806 return "isel %0,%2,%3,%j1";
13810 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
13812 enum machine_mode mode
= GET_MODE (op0
);
13816 if (code
== SMAX
|| code
== SMIN
)
13821 if (code
== SMAX
|| code
== UMAX
)
13822 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
13823 op0
, op1
, mode
, 0);
13825 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
13826 op1
, op0
, mode
, 0);
13827 gcc_assert (target
);
13828 if (target
!= dest
)
13829 emit_move_insn (dest
, target
);
13832 /* Emit instructions to perform a load-reserved/store-conditional operation.
13833 The operation performed is an atomic
13834 (set M (CODE:MODE M OP))
13835 If not NULL, BEFORE is atomically set to M before the operation, and
13836 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
13837 If SYNC_P then a memory barrier is emitted before the operation.
13838 Either OP or M may be wrapped in a NOT operation. */
13841 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
13842 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
13845 enum machine_mode used_mode
;
13846 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
13849 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
13850 rtx shift
= NULL_RTX
;
13853 emit_insn (gen_lwsync ());
13857 /* If this is smaller than SImode, we'll have to use SImode with
13859 if (mode
== QImode
|| mode
== HImode
)
13863 if (MEM_ALIGN (used_m
) >= 32)
13866 if (BYTES_BIG_ENDIAN
)
13867 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
13869 shift
= GEN_INT (ishift
);
13870 used_m
= change_address (used_m
, SImode
, 0);
13874 rtx addrSI
, aligned_addr
;
13875 int shift_mask
= mode
== QImode
? 0x18 : 0x10;
13877 addrSI
= gen_lowpart_common (SImode
,
13878 force_reg (Pmode
, XEXP (used_m
, 0)));
13879 addrSI
= force_reg (SImode
, addrSI
);
13880 shift
= gen_reg_rtx (SImode
);
13882 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
13883 GEN_INT (shift_mask
)));
13884 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
13886 aligned_addr
= expand_binop (Pmode
, and_optab
,
13888 GEN_INT (-4), NULL_RTX
,
13889 1, OPTAB_LIB_WIDEN
);
13890 used_m
= change_address (used_m
, SImode
, aligned_addr
);
13891 set_mem_align (used_m
, 32);
13893 /* It's safe to keep the old alias set of USED_M, because
13894 the operation is atomic and only affects the original
13898 if (GET_CODE (op
) == NOT
)
13900 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
13901 oldop
= gen_rtx_NOT (SImode
, oldop
);
13904 oldop
= lowpart_subreg (SImode
, op
, mode
);
13910 newop
= expand_binop (SImode
, and_optab
,
13911 oldop
, GEN_INT (imask
), NULL_RTX
,
13912 1, OPTAB_LIB_WIDEN
);
13913 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
13916 case NOT
: /* NAND */
13917 newop
= expand_binop (SImode
, ior_optab
,
13918 oldop
, GEN_INT (~imask
), NULL_RTX
,
13919 1, OPTAB_LIB_WIDEN
);
13920 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
13924 newop
= expand_binop (SImode
, ior_optab
,
13925 oldop
, GEN_INT (~imask
), NULL_RTX
,
13926 1, OPTAB_LIB_WIDEN
);
13927 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
13935 newop
= expand_binop (SImode
, and_optab
,
13936 oldop
, GEN_INT (imask
), NULL_RTX
,
13937 1, OPTAB_LIB_WIDEN
);
13938 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
13940 mask
= gen_reg_rtx (SImode
);
13941 emit_move_insn (mask
, GEN_INT (imask
));
13942 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
13945 newop
= gen_rtx_PLUS (SImode
, m
, newop
);
13947 newop
= gen_rtx_MINUS (SImode
, m
, newop
);
13948 newop
= gen_rtx_AND (SImode
, newop
, mask
);
13949 newop
= gen_rtx_IOR (SImode
, newop
,
13950 gen_rtx_AND (SImode
,
13951 gen_rtx_NOT (SImode
, mask
),
13957 gcc_unreachable ();
13961 used_mode
= SImode
;
13962 before
= gen_reg_rtx (used_mode
);
13963 after
= gen_reg_rtx (used_mode
);
13968 before
= before_param
;
13969 after
= after_param
;
13971 if (before
== NULL_RTX
)
13972 before
= gen_reg_rtx (used_mode
);
13973 if (after
== NULL_RTX
)
13974 after
= gen_reg_rtx (used_mode
);
13977 if ((code
== PLUS
|| code
== MINUS
)
13978 && used_mode
!= mode
)
13979 the_op
= op
; /* Computed above. */
13980 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
13981 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
13982 else if (code
== NOT
)
13983 the_op
= gen_rtx_fmt_ee (IOR
, used_mode
,
13984 gen_rtx_NOT (used_mode
, m
),
13985 gen_rtx_NOT (used_mode
, op
));
13987 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
13989 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
13990 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
13991 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
13992 gen_rtx_UNSPEC (used_mode
,
13993 gen_rtvec (1, the_op
),
13995 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
13997 if ((code
== PLUS
|| code
== MINUS
) && used_mode
!= mode
)
13998 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
13999 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
14001 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
14002 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
14004 /* Shift and mask the return values properly. */
14005 if (used_mode
!= mode
&& before_param
)
14007 emit_insn (gen_lshrsi3 (before
, before
, shift
));
14008 convert_move (before_param
, before
, 1);
14011 if (used_mode
!= mode
&& after_param
)
14013 emit_insn (gen_lshrsi3 (after
, after
, shift
));
14014 convert_move (after_param
, after
, 1);
14017 /* The previous sequence will end with a branch that's dependent on
14018 the conditional store, so placing an isync will ensure that no
14019 other instructions (especially, no load or store instructions)
14020 can start before the atomic operation completes. */
14022 emit_insn (gen_isync ());
14025 /* A subroutine of the atomic operation splitters. Jump to LABEL if
14026 COND is true. Mark the jump as unlikely to be taken. */
14029 emit_unlikely_jump (rtx cond
, rtx label
)
14031 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
14034 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
14035 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
14036 add_reg_note (x
, REG_BR_PROB
, very_unlikely
);
14039 /* A subroutine of the atomic operation splitters. Emit a load-locked
14040 instruction in MODE. */
14043 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
14045 rtx (*fn
) (rtx
, rtx
) = NULL
;
14046 if (mode
== SImode
)
14047 fn
= gen_load_locked_si
;
14048 else if (mode
== DImode
)
14049 fn
= gen_load_locked_di
;
14050 emit_insn (fn (reg
, mem
));
14053 /* A subroutine of the atomic operation splitters. Emit a store-conditional
14054 instruction in MODE. */
14057 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
14059 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
14060 if (mode
== SImode
)
14061 fn
= gen_store_conditional_si
;
14062 else if (mode
== DImode
)
14063 fn
= gen_store_conditional_di
;
14065 /* Emit sync before stwcx. to address PPC405 Erratum. */
14066 if (PPC405_ERRATUM77
)
14067 emit_insn (gen_memory_barrier ());
14069 emit_insn (fn (res
, mem
, val
));
14072 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
14073 to perform. MEM is the memory on which to operate. VAL is the second
14074 operand of the binary operator. BEFORE and AFTER are optional locations to
14075 return the value of MEM either before of after the operation. SCRATCH is
14076 a scratch register. */
14079 rs6000_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
14080 rtx before
, rtx after
, rtx scratch
)
14082 enum machine_mode mode
= GET_MODE (mem
);
14083 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
14085 emit_insn (gen_lwsync ());
14087 label
= gen_label_rtx ();
14088 emit_label (label
);
14089 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
14091 if (before
== NULL_RTX
)
14093 emit_load_locked (mode
, before
, mem
);
14096 x
= gen_rtx_IOR (mode
,
14097 gen_rtx_NOT (mode
, before
),
14098 gen_rtx_NOT (mode
, val
));
14099 else if (code
== AND
)
14100 x
= gen_rtx_UNSPEC (mode
, gen_rtvec (2, before
, val
), UNSPEC_AND
);
14102 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
14104 if (after
!= NULL_RTX
)
14105 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
14106 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
14108 emit_store_conditional (mode
, cond
, mem
, scratch
);
14110 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14111 emit_unlikely_jump (x
, label
);
14113 emit_insn (gen_isync ());
14116 /* Expand an atomic compare and swap operation. MEM is the memory on which
14117 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
14118 value to be stored. SCRATCH is a scratch GPR. */
14121 rs6000_split_compare_and_swap (rtx retval
, rtx mem
, rtx oldval
, rtx newval
,
14124 enum machine_mode mode
= GET_MODE (mem
);
14125 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
14127 emit_insn (gen_lwsync ());
14129 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
14130 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
14131 emit_label (XEXP (label1
, 0));
14133 emit_load_locked (mode
, retval
, mem
);
14135 x
= gen_rtx_COMPARE (CCmode
, retval
, oldval
);
14136 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
14138 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14139 emit_unlikely_jump (x
, label2
);
14141 emit_move_insn (scratch
, newval
);
14142 emit_store_conditional (mode
, cond
, mem
, scratch
);
14144 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14145 emit_unlikely_jump (x
, label1
);
14147 emit_insn (gen_isync ());
14148 emit_label (XEXP (label2
, 0));
14151 /* Expand an atomic test and set operation. MEM is the memory on which
14152 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
14155 rs6000_split_lock_test_and_set (rtx retval
, rtx mem
, rtx val
, rtx scratch
)
14157 enum machine_mode mode
= GET_MODE (mem
);
14158 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
14160 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
14161 emit_label (XEXP (label
, 0));
14163 emit_load_locked (mode
, retval
, mem
);
14164 emit_move_insn (scratch
, val
);
14165 emit_store_conditional (mode
, cond
, mem
, scratch
);
14167 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14168 emit_unlikely_jump (x
, label
);
14170 emit_insn (gen_isync ());
14174 rs6000_expand_compare_and_swapqhi (rtx dst
, rtx mem
, rtx oldval
, rtx newval
)
14176 enum machine_mode mode
= GET_MODE (mem
);
14177 rtx addrSI
, align
, wdst
, shift
, mask
;
14178 HOST_WIDE_INT shift_mask
= mode
== QImode
? 0x18 : 0x10;
14179 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
14181 /* Shift amount for subword relative to aligned word. */
14182 addrSI
= force_reg (GET_MODE (XEXP (mem
, 0)), XEXP (mem
, 0));
14183 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
, addrSI
));
14184 shift
= gen_reg_rtx (SImode
);
14185 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
14186 GEN_INT (shift_mask
)));
14187 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
14189 /* Shift and mask old value into position within word. */
14190 oldval
= convert_modes (SImode
, mode
, oldval
, 1);
14191 oldval
= expand_binop (SImode
, and_optab
,
14192 oldval
, GEN_INT (imask
), NULL_RTX
,
14193 1, OPTAB_LIB_WIDEN
);
14194 emit_insn (gen_ashlsi3 (oldval
, oldval
, shift
));
14196 /* Shift and mask new value into position within word. */
14197 newval
= convert_modes (SImode
, mode
, newval
, 1);
14198 newval
= expand_binop (SImode
, and_optab
,
14199 newval
, GEN_INT (imask
), NULL_RTX
,
14200 1, OPTAB_LIB_WIDEN
);
14201 emit_insn (gen_ashlsi3 (newval
, newval
, shift
));
14203 /* Mask for insertion. */
14204 mask
= gen_reg_rtx (SImode
);
14205 emit_move_insn (mask
, GEN_INT (imask
));
14206 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
14208 /* Address of aligned word containing subword. */
14209 align
= expand_binop (Pmode
, and_optab
, XEXP (mem
, 0), GEN_INT (-4),
14210 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
14211 mem
= change_address (mem
, SImode
, align
);
14212 set_mem_align (mem
, 32);
14213 MEM_VOLATILE_P (mem
) = 1;
14215 wdst
= gen_reg_rtx (SImode
);
14216 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst
, mask
,
14217 oldval
, newval
, mem
));
14219 /* Shift the result back. */
14220 emit_insn (gen_lshrsi3 (wdst
, wdst
, shift
));
14222 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
14226 rs6000_split_compare_and_swapqhi (rtx dest
, rtx mask
,
14227 rtx oldval
, rtx newval
, rtx mem
,
14230 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
14232 emit_insn (gen_lwsync ());
14233 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
14234 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
14235 emit_label (XEXP (label1
, 0));
14237 emit_load_locked (SImode
, scratch
, mem
);
14239 /* Mask subword within loaded value for comparison with oldval.
14240 Use UNSPEC_AND to avoid clobber.*/
14241 emit_insn (gen_rtx_SET (SImode
, dest
,
14242 gen_rtx_UNSPEC (SImode
,
14243 gen_rtvec (2, scratch
, mask
),
14246 x
= gen_rtx_COMPARE (CCmode
, dest
, oldval
);
14247 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
14249 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14250 emit_unlikely_jump (x
, label2
);
14252 /* Clear subword within loaded value for insertion of new value. */
14253 emit_insn (gen_rtx_SET (SImode
, scratch
,
14254 gen_rtx_AND (SImode
,
14255 gen_rtx_NOT (SImode
, mask
), scratch
)));
14256 emit_insn (gen_iorsi3 (scratch
, scratch
, newval
));
14257 emit_store_conditional (SImode
, cond
, mem
, scratch
);
14259 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14260 emit_unlikely_jump (x
, label1
);
14262 emit_insn (gen_isync ());
14263 emit_label (XEXP (label2
, 0));
14267 /* Emit instructions to move SRC to DST. Called by splitters for
14268 multi-register moves. It will emit at most one instruction for
14269 each register that is accessed; that is, it won't emit li/lis pairs
14270 (or equivalent for 64-bit code). One of SRC or DST must be a hard
14274 rs6000_split_multireg_move (rtx dst
, rtx src
)
14276 /* The register number of the first register being moved. */
14278 /* The mode that is to be moved. */
14279 enum machine_mode mode
;
14280 /* The mode that the move is being done in, and its size. */
14281 enum machine_mode reg_mode
;
14283 /* The number of registers that will be moved. */
14286 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
14287 mode
= GET_MODE (dst
);
14288 nregs
= hard_regno_nregs
[reg
][mode
];
14289 if (FP_REGNO_P (reg
))
14290 reg_mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
:
14291 ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? DFmode
: SFmode
);
14292 else if (ALTIVEC_REGNO_P (reg
))
14293 reg_mode
= V16QImode
;
14294 else if (TARGET_E500_DOUBLE
&& mode
== TFmode
)
14297 reg_mode
= word_mode
;
14298 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
14300 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
14302 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
14304 /* Move register range backwards, if we might have destructive
14307 for (i
= nregs
- 1; i
>= 0; i
--)
14308 emit_insn (gen_rtx_SET (VOIDmode
,
14309 simplify_gen_subreg (reg_mode
, dst
, mode
,
14310 i
* reg_mode_size
),
14311 simplify_gen_subreg (reg_mode
, src
, mode
,
14312 i
* reg_mode_size
)));
14318 bool used_update
= false;
14320 if (MEM_P (src
) && INT_REGNO_P (reg
))
14324 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
14325 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
14328 breg
= XEXP (XEXP (src
, 0), 0);
14329 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
14330 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
14331 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
14332 emit_insn (TARGET_32BIT
14333 ? gen_addsi3 (breg
, breg
, delta_rtx
)
14334 : gen_adddi3 (breg
, breg
, delta_rtx
));
14335 src
= replace_equiv_address (src
, breg
);
14337 else if (! rs6000_offsettable_memref_p (src
))
14340 basereg
= gen_rtx_REG (Pmode
, reg
);
14341 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
14342 src
= replace_equiv_address (src
, basereg
);
14345 breg
= XEXP (src
, 0);
14346 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
14347 breg
= XEXP (breg
, 0);
14349 /* If the base register we are using to address memory is
14350 also a destination reg, then change that register last. */
14352 && REGNO (breg
) >= REGNO (dst
)
14353 && REGNO (breg
) < REGNO (dst
) + nregs
)
14354 j
= REGNO (breg
) - REGNO (dst
);
14357 if (GET_CODE (dst
) == MEM
&& INT_REGNO_P (reg
))
14361 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
14362 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
14365 breg
= XEXP (XEXP (dst
, 0), 0);
14366 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
14367 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
14368 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
14370 /* We have to update the breg before doing the store.
14371 Use store with update, if available. */
14375 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
14376 emit_insn (TARGET_32BIT
14377 ? (TARGET_POWERPC64
14378 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
14379 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
14380 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
14381 used_update
= true;
14384 emit_insn (TARGET_32BIT
14385 ? gen_addsi3 (breg
, breg
, delta_rtx
)
14386 : gen_adddi3 (breg
, breg
, delta_rtx
));
14387 dst
= replace_equiv_address (dst
, breg
);
14390 gcc_assert (rs6000_offsettable_memref_p (dst
));
14393 for (i
= 0; i
< nregs
; i
++)
14395 /* Calculate index to next subword. */
14400 /* If compiler already emitted move of first word by
14401 store with update, no need to do anything. */
14402 if (j
== 0 && used_update
)
14405 emit_insn (gen_rtx_SET (VOIDmode
,
14406 simplify_gen_subreg (reg_mode
, dst
, mode
,
14407 j
* reg_mode_size
),
14408 simplify_gen_subreg (reg_mode
, src
, mode
,
14409 j
* reg_mode_size
)));
14415 /* This page contains routines that are used to determine what the
14416 function prologue and epilogue code will do and write them out. */
14418 /* Return the first fixed-point register that is required to be
14419 saved. 32 if none. */
14422 first_reg_to_save (void)
14426 /* Find lowest numbered live register. */
14427 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
14428 if (df_regs_ever_live_p (first_reg
)
14429 && (! call_used_regs
[first_reg
]
14430 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
14431 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
14432 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
14433 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
14438 && crtl
->uses_pic_offset_table
14439 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
14440 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
14446 /* Similar, for FP regs. */
14449 first_fp_reg_to_save (void)
14453 /* Find lowest numbered live register. */
14454 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
14455 if (df_regs_ever_live_p (first_reg
))
14461 /* Similar, for AltiVec regs. */
14464 first_altivec_reg_to_save (void)
14468 /* Stack frame remains as is unless we are in AltiVec ABI. */
14469 if (! TARGET_ALTIVEC_ABI
)
14470 return LAST_ALTIVEC_REGNO
+ 1;
14472 /* On Darwin, the unwind routines are compiled without
14473 TARGET_ALTIVEC, and use save_world to save/restore the
14474 altivec registers when necessary. */
14475 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
14476 && ! TARGET_ALTIVEC
)
14477 return FIRST_ALTIVEC_REGNO
+ 20;
14479 /* Find lowest numbered live register. */
14480 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14481 if (df_regs_ever_live_p (i
))
14487 /* Return a 32-bit mask of the AltiVec registers we need to set in
14488 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
14489 the 32-bit word is 0. */
14491 static unsigned int
14492 compute_vrsave_mask (void)
14494 unsigned int i
, mask
= 0;
14496 /* On Darwin, the unwind routines are compiled without
14497 TARGET_ALTIVEC, and use save_world to save/restore the
14498 call-saved altivec registers when necessary. */
14499 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
14500 && ! TARGET_ALTIVEC
)
14503 /* First, find out if we use _any_ altivec registers. */
14504 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14505 if (df_regs_ever_live_p (i
))
14506 mask
|= ALTIVEC_REG_BIT (i
);
14511 /* Next, remove the argument registers from the set. These must
14512 be in the VRSAVE mask set by the caller, so we don't need to add
14513 them in again. More importantly, the mask we compute here is
14514 used to generate CLOBBERs in the set_vrsave insn, and we do not
14515 wish the argument registers to die. */
14516 for (i
= crtl
->args
.info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
14517 mask
&= ~ALTIVEC_REG_BIT (i
);
14519 /* Similarly, remove the return value from the set. */
14522 diddle_return_value (is_altivec_return_reg
, &yes
);
14524 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
14530 /* For a very restricted set of circumstances, we can cut down the
14531 size of prologues/epilogues by calling our own save/restore-the-world
14535 compute_save_world_info (rs6000_stack_t
*info_ptr
)
14537 info_ptr
->world_save_p
= 1;
14538 info_ptr
->world_save_p
14539 = (WORLD_SAVE_P (info_ptr
)
14540 && DEFAULT_ABI
== ABI_DARWIN
14541 && ! (cfun
->calls_setjmp
&& flag_exceptions
)
14542 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
14543 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
14544 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
14545 && info_ptr
->cr_save_p
);
14547 /* This will not work in conjunction with sibcalls. Make sure there
14548 are none. (This check is expensive, but seldom executed.) */
14549 if (WORLD_SAVE_P (info_ptr
))
14552 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
14553 if ( GET_CODE (insn
) == CALL_INSN
14554 && SIBLING_CALL_P (insn
))
14556 info_ptr
->world_save_p
= 0;
14561 if (WORLD_SAVE_P (info_ptr
))
14563 /* Even if we're not touching VRsave, make sure there's room on the
14564 stack for it, if it looks like we're calling SAVE_WORLD, which
14565 will attempt to save it. */
14566 info_ptr
->vrsave_size
= 4;
14568 /* If we are going to save the world, we need to save the link register too. */
14569 info_ptr
->lr_save_p
= 1;
14571 /* "Save" the VRsave register too if we're saving the world. */
14572 if (info_ptr
->vrsave_mask
== 0)
14573 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
14575 /* Because the Darwin register save/restore routines only handle
14576 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
14578 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
14579 && (info_ptr
->first_altivec_reg_save
14580 >= FIRST_SAVED_ALTIVEC_REGNO
));
14587 is_altivec_return_reg (rtx reg
, void *xyes
)
14589 bool *yes
= (bool *) xyes
;
14590 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
14595 /* Calculate the stack information for the current function. This is
14596 complicated by having two separate calling sequences, the AIX calling
14597 sequence and the V.4 calling sequence.
14599 AIX (and Darwin/Mac OS X) stack frames look like:
14601 SP----> +---------------------------------------+
14602 | back chain to caller | 0 0
14603 +---------------------------------------+
14604 | saved CR | 4 8 (8-11)
14605 +---------------------------------------+
14607 +---------------------------------------+
14608 | reserved for compilers | 12 24
14609 +---------------------------------------+
14610 | reserved for binders | 16 32
14611 +---------------------------------------+
14612 | saved TOC pointer | 20 40
14613 +---------------------------------------+
14614 | Parameter save area (P) | 24 48
14615 +---------------------------------------+
14616 | Alloca space (A) | 24+P etc.
14617 +---------------------------------------+
14618 | Local variable space (L) | 24+P+A
14619 +---------------------------------------+
14620 | Float/int conversion temporary (X) | 24+P+A+L
14621 +---------------------------------------+
14622 | Save area for AltiVec registers (W) | 24+P+A+L+X
14623 +---------------------------------------+
14624 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
14625 +---------------------------------------+
14626 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
14627 +---------------------------------------+
14628 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
14629 +---------------------------------------+
14630 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
14631 +---------------------------------------+
14632 old SP->| back chain to caller's caller |
14633 +---------------------------------------+
14635 The required alignment for AIX configurations is two words (i.e., 8
14639 V.4 stack frames look like:
14641 SP----> +---------------------------------------+
14642 | back chain to caller | 0
14643 +---------------------------------------+
14644 | caller's saved LR | 4
14645 +---------------------------------------+
14646 | Parameter save area (P) | 8
14647 +---------------------------------------+
14648 | Alloca space (A) | 8+P
14649 +---------------------------------------+
14650 | Varargs save area (V) | 8+P+A
14651 +---------------------------------------+
14652 | Local variable space (L) | 8+P+A+V
14653 +---------------------------------------+
14654 | Float/int conversion temporary (X) | 8+P+A+V+L
14655 +---------------------------------------+
14656 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
14657 +---------------------------------------+
14658 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
14659 +---------------------------------------+
14660 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
14661 +---------------------------------------+
14662 | SPE: area for 64-bit GP registers |
14663 +---------------------------------------+
14664 | SPE alignment padding |
14665 +---------------------------------------+
14666 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
14667 +---------------------------------------+
14668 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
14669 +---------------------------------------+
14670 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
14671 +---------------------------------------+
14672 old SP->| back chain to caller's caller |
14673 +---------------------------------------+
14675 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
14676 given. (But note below and in sysv4.h that we require only 8 and
14677 may round up the size of our stack frame anyways. The historical
14678 reason is early versions of powerpc-linux which didn't properly
14679 align the stack at program startup. A happy side-effect is that
14680 -mno-eabi libraries can be used with -meabi programs.)
14682 The EABI configuration defaults to the V.4 layout. However,
14683 the stack alignment requirements may differ. If -mno-eabi is not
14684 given, the required stack alignment is 8 bytes; if -mno-eabi is
14685 given, the required alignment is 16 bytes. (But see V.4 comment
14688 #ifndef ABI_STACK_BOUNDARY
14689 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
14692 static rs6000_stack_t
*
14693 rs6000_stack_info (void)
14695 static rs6000_stack_t info
;
14696 rs6000_stack_t
*info_ptr
= &info
;
14697 int reg_size
= TARGET_32BIT
? 4 : 8;
14701 HOST_WIDE_INT non_fixed_size
;
14703 memset (&info
, 0, sizeof (info
));
14707 /* Cache value so we don't rescan instruction chain over and over. */
14708 if (cfun
->machine
->insn_chain_scanned_p
== 0)
14709 cfun
->machine
->insn_chain_scanned_p
14710 = spe_func_has_64bit_regs_p () + 1;
14711 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
14714 /* Select which calling sequence. */
14715 info_ptr
->abi
= DEFAULT_ABI
;
14717 /* Calculate which registers need to be saved & save area size. */
14718 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
14719 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
14720 even if it currently looks like we won't. Reload may need it to
14721 get at a constant; if so, it will have already created a constant
14722 pool entry for it. */
14723 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
14724 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
14725 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
14726 && crtl
->uses_const_pool
14727 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
14728 first_gp
= RS6000_PIC_OFFSET_TABLE_REGNUM
;
14730 first_gp
= info_ptr
->first_gp_reg_save
;
14732 info_ptr
->gp_size
= reg_size
* (32 - first_gp
);
14734 /* For the SPE, we have an additional upper 32-bits on each GPR.
14735 Ideally we should save the entire 64-bits only when the upper
14736 half is used in SIMD instructions. Since we only record
14737 registers live (not the size they are used in), this proves
14738 difficult because we'd have to traverse the instruction chain at
14739 the right time, taking reload into account. This is a real pain,
14740 so we opt to save the GPRs in 64-bits always if but one register
14741 gets used in 64-bits. Otherwise, all the registers in the frame
14742 get saved in 32-bits.
14744 So... since when we save all GPRs (except the SP) in 64-bits, the
14745 traditional GP save area will be empty. */
14746 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
14747 info_ptr
->gp_size
= 0;
14749 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
14750 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
14752 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
14753 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
14754 - info_ptr
->first_altivec_reg_save
);
14756 /* Does this function call anything? */
14757 info_ptr
->calls_p
= (! current_function_is_leaf
14758 || cfun
->machine
->ra_needs_full_frame
);
14760 /* Determine if we need to save the link register. */
14761 if ((DEFAULT_ABI
== ABI_AIX
14763 && !TARGET_PROFILE_KERNEL
)
14764 #ifdef TARGET_RELOCATABLE
14765 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
14767 || (info_ptr
->first_fp_reg_save
!= 64
14768 && !FP_SAVE_INLINE (info_ptr
->first_fp_reg_save
))
14769 || (DEFAULT_ABI
== ABI_V4
&& cfun
->calls_alloca
)
14770 || info_ptr
->calls_p
14771 || rs6000_ra_ever_killed ())
14773 info_ptr
->lr_save_p
= 1;
14774 df_set_regs_ever_live (LR_REGNO
, true);
14777 /* Determine if we need to save the condition code registers. */
14778 if (df_regs_ever_live_p (CR2_REGNO
)
14779 || df_regs_ever_live_p (CR3_REGNO
)
14780 || df_regs_ever_live_p (CR4_REGNO
))
14782 info_ptr
->cr_save_p
= 1;
14783 if (DEFAULT_ABI
== ABI_V4
)
14784 info_ptr
->cr_size
= reg_size
;
14787 /* If the current function calls __builtin_eh_return, then we need
14788 to allocate stack space for registers that will hold data for
14789 the exception handler. */
14790 if (crtl
->calls_eh_return
)
14793 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
14796 /* SPE saves EH registers in 64-bits. */
14797 ehrd_size
= i
* (TARGET_SPE_ABI
14798 && info_ptr
->spe_64bit_regs_used
!= 0
14799 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
14804 /* Determine various sizes. */
14805 info_ptr
->reg_size
= reg_size
;
14806 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
14807 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
14808 info_ptr
->parm_size
= RS6000_ALIGN (crtl
->outgoing_args_size
,
14809 TARGET_ALTIVEC
? 16 : 8);
14810 if (FRAME_GROWS_DOWNWARD
)
14811 info_ptr
->vars_size
14812 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
14813 + info_ptr
->parm_size
,
14814 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
14815 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
14816 + info_ptr
->parm_size
);
14818 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
14819 info_ptr
->spe_gp_size
= 8 * (32 - first_gp
);
14821 info_ptr
->spe_gp_size
= 0;
14823 if (TARGET_ALTIVEC_ABI
)
14824 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
14826 info_ptr
->vrsave_mask
= 0;
14828 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
14829 info_ptr
->vrsave_size
= 4;
14831 info_ptr
->vrsave_size
= 0;
14833 compute_save_world_info (info_ptr
);
14835 /* Calculate the offsets. */
14836 switch (DEFAULT_ABI
)
14840 gcc_unreachable ();
14844 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
14845 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
14847 if (TARGET_ALTIVEC_ABI
)
14849 info_ptr
->vrsave_save_offset
14850 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
14852 /* Align stack so vector save area is on a quadword boundary.
14853 The padding goes above the vectors. */
14854 if (info_ptr
->altivec_size
!= 0)
14855 info_ptr
->altivec_padding_size
14856 = info_ptr
->vrsave_save_offset
& 0xF;
14858 info_ptr
->altivec_padding_size
= 0;
14860 info_ptr
->altivec_save_offset
14861 = info_ptr
->vrsave_save_offset
14862 - info_ptr
->altivec_padding_size
14863 - info_ptr
->altivec_size
;
14864 gcc_assert (info_ptr
->altivec_size
== 0
14865 || info_ptr
->altivec_save_offset
% 16 == 0);
14867 /* Adjust for AltiVec case. */
14868 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
14871 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
14872 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
14873 info_ptr
->lr_save_offset
= 2*reg_size
;
14877 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
14878 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
14879 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
14881 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
14883 /* Align stack so SPE GPR save area is aligned on a
14884 double-word boundary. */
14885 if (info_ptr
->spe_gp_size
!= 0 && info_ptr
->cr_save_offset
!= 0)
14886 info_ptr
->spe_padding_size
14887 = 8 - (-info_ptr
->cr_save_offset
% 8);
14889 info_ptr
->spe_padding_size
= 0;
14891 info_ptr
->spe_gp_save_offset
14892 = info_ptr
->cr_save_offset
14893 - info_ptr
->spe_padding_size
14894 - info_ptr
->spe_gp_size
;
14896 /* Adjust for SPE case. */
14897 info_ptr
->ehrd_offset
= info_ptr
->spe_gp_save_offset
;
14899 else if (TARGET_ALTIVEC_ABI
)
14901 info_ptr
->vrsave_save_offset
14902 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
14904 /* Align stack so vector save area is on a quadword boundary. */
14905 if (info_ptr
->altivec_size
!= 0)
14906 info_ptr
->altivec_padding_size
14907 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
14909 info_ptr
->altivec_padding_size
= 0;
14911 info_ptr
->altivec_save_offset
14912 = info_ptr
->vrsave_save_offset
14913 - info_ptr
->altivec_padding_size
14914 - info_ptr
->altivec_size
;
14916 /* Adjust for AltiVec case. */
14917 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
;
14920 info_ptr
->ehrd_offset
= info_ptr
->cr_save_offset
;
14921 info_ptr
->ehrd_offset
-= ehrd_size
;
14922 info_ptr
->lr_save_offset
= reg_size
;
14926 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
14927 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
14928 + info_ptr
->gp_size
14929 + info_ptr
->altivec_size
14930 + info_ptr
->altivec_padding_size
14931 + info_ptr
->spe_gp_size
14932 + info_ptr
->spe_padding_size
14934 + info_ptr
->cr_size
14935 + info_ptr
->vrsave_size
,
14938 non_fixed_size
= (info_ptr
->vars_size
14939 + info_ptr
->parm_size
14940 + info_ptr
->save_size
);
14942 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
14943 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
14945 /* Determine if we need to allocate any stack frame:
14947 For AIX we need to push the stack if a frame pointer is needed
14948 (because the stack might be dynamically adjusted), if we are
14949 debugging, if we make calls, or if the sum of fp_save, gp_save,
14950 and local variables are more than the space needed to save all
14951 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
14952 + 18*8 = 288 (GPR13 reserved).
14954 For V.4 we don't have the stack cushion that AIX uses, but assume
14955 that the debugger can handle stackless frames. */
14957 if (info_ptr
->calls_p
)
14958 info_ptr
->push_p
= 1;
14960 else if (DEFAULT_ABI
== ABI_V4
)
14961 info_ptr
->push_p
= non_fixed_size
!= 0;
14963 else if (frame_pointer_needed
)
14964 info_ptr
->push_p
= 1;
14966 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
14967 info_ptr
->push_p
= 1;
14970 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
14972 /* Zero offsets if we're not saving those registers. */
14973 if (info_ptr
->fp_size
== 0)
14974 info_ptr
->fp_save_offset
= 0;
14976 if (info_ptr
->gp_size
== 0)
14977 info_ptr
->gp_save_offset
= 0;
14979 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
14980 info_ptr
->altivec_save_offset
= 0;
14982 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
14983 info_ptr
->vrsave_save_offset
= 0;
14985 if (! TARGET_SPE_ABI
14986 || info_ptr
->spe_64bit_regs_used
== 0
14987 || info_ptr
->spe_gp_size
== 0)
14988 info_ptr
->spe_gp_save_offset
= 0;
14990 if (! info_ptr
->lr_save_p
)
14991 info_ptr
->lr_save_offset
= 0;
14993 if (! info_ptr
->cr_save_p
)
14994 info_ptr
->cr_save_offset
= 0;
14999 /* Return true if the current function uses any GPRs in 64-bit SIMD
15003 spe_func_has_64bit_regs_p (void)
15007 /* Functions that save and restore all the call-saved registers will
15008 need to save/restore the registers in 64-bits. */
15009 if (crtl
->calls_eh_return
15010 || cfun
->calls_setjmp
15011 || crtl
->has_nonlocal_goto
)
15014 insns
= get_insns ();
15016 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
15022 /* FIXME: This should be implemented with attributes...
15024 (set_attr "spe64" "true")....then,
15025 if (get_spe64(insn)) return true;
15027 It's the only reliable way to do the stuff below. */
15029 i
= PATTERN (insn
);
15030 if (GET_CODE (i
) == SET
)
15032 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
15034 if (SPE_VECTOR_MODE (mode
))
15036 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
))
15046 debug_stack_info (rs6000_stack_t
*info
)
15048 const char *abi_string
;
15051 info
= rs6000_stack_info ();
15053 fprintf (stderr
, "\nStack information for function %s:\n",
15054 ((current_function_decl
&& DECL_NAME (current_function_decl
))
15055 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
15060 default: abi_string
= "Unknown"; break;
15061 case ABI_NONE
: abi_string
= "NONE"; break;
15062 case ABI_AIX
: abi_string
= "AIX"; break;
15063 case ABI_DARWIN
: abi_string
= "Darwin"; break;
15064 case ABI_V4
: abi_string
= "V.4"; break;
15067 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
15069 if (TARGET_ALTIVEC_ABI
)
15070 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
15072 if (TARGET_SPE_ABI
)
15073 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
15075 if (info
->first_gp_reg_save
!= 32)
15076 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
15078 if (info
->first_fp_reg_save
!= 64)
15079 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
15081 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
15082 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
15083 info
->first_altivec_reg_save
);
15085 if (info
->lr_save_p
)
15086 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
15088 if (info
->cr_save_p
)
15089 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
15091 if (info
->vrsave_mask
)
15092 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
15095 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
15098 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
15100 if (info
->gp_save_offset
)
15101 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
15103 if (info
->fp_save_offset
)
15104 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
15106 if (info
->altivec_save_offset
)
15107 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
15108 info
->altivec_save_offset
);
15110 if (info
->spe_gp_save_offset
)
15111 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
15112 info
->spe_gp_save_offset
);
15114 if (info
->vrsave_save_offset
)
15115 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
15116 info
->vrsave_save_offset
);
15118 if (info
->lr_save_offset
)
15119 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
15121 if (info
->cr_save_offset
)
15122 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
15124 if (info
->varargs_save_offset
)
15125 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
15127 if (info
->total_size
)
15128 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
15131 if (info
->vars_size
)
15132 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
15135 if (info
->parm_size
)
15136 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
15138 if (info
->fixed_size
)
15139 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
15142 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
15144 if (info
->spe_gp_size
)
15145 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
15148 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
15150 if (info
->altivec_size
)
15151 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
15153 if (info
->vrsave_size
)
15154 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
15156 if (info
->altivec_padding_size
)
15157 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
15158 info
->altivec_padding_size
);
15160 if (info
->spe_padding_size
)
15161 fprintf (stderr
, "\tspe_padding_size = %5d\n",
15162 info
->spe_padding_size
);
15165 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
15167 if (info
->save_size
)
15168 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
15170 if (info
->reg_size
!= 4)
15171 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
15173 fprintf (stderr
, "\n");
15177 rs6000_return_addr (int count
, rtx frame
)
15179 /* Currently we don't optimize very well between prolog and body
15180 code and for PIC code the code can be actually quite bad, so
15181 don't try to be too clever here. */
15182 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
15184 cfun
->machine
->ra_needs_full_frame
= 1;
15191 plus_constant (copy_to_reg
15192 (gen_rtx_MEM (Pmode
,
15193 memory_address (Pmode
, frame
))),
15194 RETURN_ADDRESS_OFFSET
)));
15197 cfun
->machine
->ra_need_lr
= 1;
15198 return get_hard_reg_initial_val (Pmode
, LR_REGNO
);
15201 /* Say whether a function is a candidate for sibcall handling or not.
15202 We do not allow indirect calls to be optimized into sibling calls.
15203 Also, we can't do it if there are any vector parameters; there's
15204 nowhere to put the VRsave code so it works; note that functions with
15205 vector parameters are required to have a prototype, so the argument
15206 type info must be available here. (The tail recursion case can work
15207 with vector parameters, but there's no way to distinguish here.) */
15209 rs6000_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
15214 if (TARGET_ALTIVEC_VRSAVE
)
15216 for (type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
15217 type
; type
= TREE_CHAIN (type
))
15219 if (TREE_CODE (TREE_VALUE (type
)) == VECTOR_TYPE
)
15223 if (DEFAULT_ABI
== ABI_DARWIN
15224 || ((*targetm
.binds_local_p
) (decl
)
15225 && (DEFAULT_ABI
!= ABI_AIX
|| !DECL_EXTERNAL (decl
))))
15227 tree attr_list
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
15229 if (!lookup_attribute ("longcall", attr_list
)
15230 || lookup_attribute ("shortcall", attr_list
))
15237 /* NULL if INSN insn is valid within a low-overhead loop.
15238 Otherwise return why doloop cannot be applied.
15239 PowerPC uses the COUNT register for branch on table instructions. */
15241 static const char *
15242 rs6000_invalid_within_doloop (const_rtx insn
)
15245 return "Function call in the loop.";
15248 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
15249 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
15250 return "Computed branch in the loop.";
15256 rs6000_ra_ever_killed (void)
15262 if (cfun
->is_thunk
)
15265 /* regs_ever_live has LR marked as used if any sibcalls are present,
15266 but this should not force saving and restoring in the
15267 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
15268 clobbers LR, so that is inappropriate. */
15270 /* Also, the prologue can generate a store into LR that
15271 doesn't really count, like this:
15274 bcl to set PIC register
15278 When we're called from the epilogue, we need to avoid counting
15279 this as a store. */
15281 push_topmost_sequence ();
15282 top
= get_insns ();
15283 pop_topmost_sequence ();
15284 reg
= gen_rtx_REG (Pmode
, LR_REGNO
);
15286 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
15292 if (!SIBLING_CALL_P (insn
))
15295 else if (find_regno_note (insn
, REG_INC
, LR_REGNO
))
15297 else if (set_of (reg
, insn
) != NULL_RTX
15298 && !prologue_epilogue_contains (insn
))
15305 /* Emit instructions needed to load the TOC register.
15306 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
15307 a constant pool; or for SVR4 -fpic. */
15310 rs6000_emit_load_toc_table (int fromprolog
)
15313 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
15315 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
15318 rtx lab
, tmp1
, tmp2
, got
;
15320 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
15321 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15323 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
15325 got
= rs6000_got_sym ();
15326 tmp1
= tmp2
= dest
;
15329 tmp1
= gen_reg_rtx (Pmode
);
15330 tmp2
= gen_reg_rtx (Pmode
);
15332 emit_insn (gen_load_toc_v4_PIC_1 (lab
));
15333 emit_move_insn (tmp1
,
15334 gen_rtx_REG (Pmode
, LR_REGNO
));
15335 emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
15336 emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
15338 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
15340 emit_insn (gen_load_toc_v4_pic_si ());
15341 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
15343 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
15346 rtx temp0
= (fromprolog
15347 ? gen_rtx_REG (Pmode
, 0)
15348 : gen_reg_rtx (Pmode
));
15354 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
15355 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15357 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
15358 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15360 emit_insn (gen_load_toc_v4_PIC_1 (symF
));
15361 emit_move_insn (dest
,
15362 gen_rtx_REG (Pmode
, LR_REGNO
));
15363 emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
, symL
, symF
));
15369 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
15370 emit_insn (gen_load_toc_v4_PIC_1b (tocsym
));
15371 emit_move_insn (dest
,
15372 gen_rtx_REG (Pmode
, LR_REGNO
));
15373 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
15375 emit_insn (gen_addsi3 (dest
, temp0
, dest
));
15377 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
15379 /* This is for AIX code running in non-PIC ELF32. */
15382 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
15383 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15385 emit_insn (gen_elf_high (dest
, realsym
));
15386 emit_insn (gen_elf_low (dest
, dest
, realsym
));
15390 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
15393 emit_insn (gen_load_toc_aix_si (dest
));
15395 emit_insn (gen_load_toc_aix_di (dest
));
15399 /* Emit instructions to restore the link register after determining where
15400 its value has been stored. */
15403 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
15405 rs6000_stack_t
*info
= rs6000_stack_info ();
15408 operands
[0] = source
;
15409 operands
[1] = scratch
;
15411 if (info
->lr_save_p
)
15413 rtx frame_rtx
= stack_pointer_rtx
;
15414 HOST_WIDE_INT sp_offset
= 0;
15417 if (frame_pointer_needed
15418 || cfun
->calls_alloca
15419 || info
->total_size
> 32767)
15421 tmp
= gen_frame_mem (Pmode
, frame_rtx
);
15422 emit_move_insn (operands
[1], tmp
);
15423 frame_rtx
= operands
[1];
15425 else if (info
->push_p
)
15426 sp_offset
= info
->total_size
;
15428 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
15429 tmp
= gen_frame_mem (Pmode
, tmp
);
15430 emit_move_insn (tmp
, operands
[0]);
15433 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
), operands
[0]);
15436 static GTY(()) alias_set_type set
= -1;
15439 get_TOC_alias_set (void)
15442 set
= new_alias_set ();
15446 /* This returns nonzero if the current function uses the TOC. This is
15447 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
15448 is generated by the ABI_V4 load_toc_* patterns. */
15455 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
15458 rtx pat
= PATTERN (insn
);
15461 if (GET_CODE (pat
) == PARALLEL
)
15462 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
15464 rtx sub
= XVECEXP (pat
, 0, i
);
15465 if (GET_CODE (sub
) == USE
)
15467 sub
= XEXP (sub
, 0);
15468 if (GET_CODE (sub
) == UNSPEC
15469 && XINT (sub
, 1) == UNSPEC_TOC
)
15479 create_TOC_reference (rtx symbol
)
15481 if (!can_create_pseudo_p ())
15482 df_set_regs_ever_live (TOC_REGISTER
, true);
15483 return gen_rtx_PLUS (Pmode
,
15484 gen_rtx_REG (Pmode
, TOC_REGISTER
),
15485 gen_rtx_CONST (Pmode
,
15486 gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, symbol
), UNSPEC_TOCREL
)));
15489 /* If _Unwind_* has been called from within the same module,
15490 toc register is not guaranteed to be saved to 40(1) on function
15491 entry. Save it there in that case. */
15494 rs6000_aix_emit_builtin_unwind_init (void)
15497 rtx stack_top
= gen_reg_rtx (Pmode
);
15498 rtx opcode_addr
= gen_reg_rtx (Pmode
);
15499 rtx opcode
= gen_reg_rtx (SImode
);
15500 rtx tocompare
= gen_reg_rtx (SImode
);
15501 rtx no_toc_save_needed
= gen_label_rtx ();
15503 mem
= gen_frame_mem (Pmode
, hard_frame_pointer_rtx
);
15504 emit_move_insn (stack_top
, mem
);
15506 mem
= gen_frame_mem (Pmode
,
15507 gen_rtx_PLUS (Pmode
, stack_top
,
15508 GEN_INT (2 * GET_MODE_SIZE (Pmode
))));
15509 emit_move_insn (opcode_addr
, mem
);
15510 emit_move_insn (opcode
, gen_rtx_MEM (SImode
, opcode_addr
));
15511 emit_move_insn (tocompare
, gen_int_mode (TARGET_32BIT
? 0x80410014
15512 : 0xE8410028, SImode
));
15514 do_compare_rtx_and_jump (opcode
, tocompare
, EQ
, 1,
15515 SImode
, NULL_RTX
, NULL_RTX
,
15516 no_toc_save_needed
);
15518 mem
= gen_frame_mem (Pmode
,
15519 gen_rtx_PLUS (Pmode
, stack_top
,
15520 GEN_INT (5 * GET_MODE_SIZE (Pmode
))));
15521 emit_move_insn (mem
, gen_rtx_REG (Pmode
, 2));
15522 emit_label (no_toc_save_needed
);
15525 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
15526 and the change to the stack pointer. */
15529 rs6000_emit_stack_tie (void)
15531 rtx mem
= gen_frame_mem (BLKmode
,
15532 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
15534 emit_insn (gen_stack_tie (mem
));
15537 /* Emit the correct code for allocating stack space, as insns.
15538 If COPY_R12, make sure a copy of the old frame is left in r12.
15539 If COPY_R11, make sure a copy of the old frame is left in r11,
15540 in preference to r12 if COPY_R12.
15541 The generated code may use hard register 0 as a temporary. */
15544 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, int copy_r12
, int copy_r11
)
15547 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
15548 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
15549 rtx todec
= gen_int_mode (-size
, Pmode
);
15552 if (INTVAL (todec
) != -size
)
15554 warning (0, "stack frame too large");
15555 emit_insn (gen_trap ());
15559 if (crtl
->limit_stack
)
15561 if (REG_P (stack_limit_rtx
)
15562 && REGNO (stack_limit_rtx
) > 1
15563 && REGNO (stack_limit_rtx
) <= 31)
15565 emit_insn (TARGET_32BIT
15566 ? gen_addsi3 (tmp_reg
,
15569 : gen_adddi3 (tmp_reg
,
15573 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
15576 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
15578 && DEFAULT_ABI
== ABI_V4
)
15580 rtx toload
= gen_rtx_CONST (VOIDmode
,
15581 gen_rtx_PLUS (Pmode
,
15585 emit_insn (gen_elf_high (tmp_reg
, toload
));
15586 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
15587 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
15591 warning (0, "stack limit expression is not supported");
15594 if (copy_r12
|| copy_r11
)
15595 emit_move_insn (copy_r11
15596 ? gen_rtx_REG (Pmode
, 11)
15597 : gen_rtx_REG (Pmode
, 12),
15602 /* Need a note here so that try_split doesn't get confused. */
15603 if (get_last_insn () == NULL_RTX
)
15604 emit_note (NOTE_INSN_DELETED
);
15605 insn
= emit_move_insn (tmp_reg
, todec
);
15606 try_split (PATTERN (insn
), insn
, 0);
15610 insn
= emit_insn (TARGET_32BIT
15611 ? gen_movsi_update_stack (stack_reg
, stack_reg
,
15613 : gen_movdi_di_update_stack (stack_reg
, stack_reg
,
15614 todec
, stack_reg
));
15615 /* Since we didn't use gen_frame_mem to generate the MEM, grab
15616 it now and set the alias set/attributes. The above gen_*_update
15617 calls will generate a PARALLEL with the MEM set being the first
15619 par
= PATTERN (insn
);
15620 gcc_assert (GET_CODE (par
) == PARALLEL
);
15621 set
= XVECEXP (par
, 0, 0);
15622 gcc_assert (GET_CODE (set
) == SET
);
15623 mem
= SET_DEST (set
);
15624 gcc_assert (MEM_P (mem
));
15625 MEM_NOTRAP_P (mem
) = 1;
15626 set_mem_alias_set (mem
, get_frame_alias_set ());
15628 RTX_FRAME_RELATED_P (insn
) = 1;
15629 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
15630 gen_rtx_SET (VOIDmode
, stack_reg
,
15631 gen_rtx_PLUS (Pmode
, stack_reg
,
15632 GEN_INT (-size
))));
15635 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
15636 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
15637 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
15638 deduce these equivalences by itself so it wasn't necessary to hold
15639 its hand so much. */
15642 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
15643 rtx reg2
, rtx rreg
)
15647 /* copy_rtx will not make unique copies of registers, so we need to
15648 ensure we don't have unwanted sharing here. */
15650 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
15653 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
15655 real
= copy_rtx (PATTERN (insn
));
15657 if (reg2
!= NULL_RTX
)
15658 real
= replace_rtx (real
, reg2
, rreg
);
15660 real
= replace_rtx (real
, reg
,
15661 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
15662 STACK_POINTER_REGNUM
),
15665 /* We expect that 'real' is either a SET or a PARALLEL containing
15666 SETs (and possibly other stuff). In a PARALLEL, all the SETs
15667 are important so they all have to be marked RTX_FRAME_RELATED_P. */
15669 if (GET_CODE (real
) == SET
)
15673 temp
= simplify_rtx (SET_SRC (set
));
15675 SET_SRC (set
) = temp
;
15676 temp
= simplify_rtx (SET_DEST (set
));
15678 SET_DEST (set
) = temp
;
15679 if (GET_CODE (SET_DEST (set
)) == MEM
)
15681 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
15683 XEXP (SET_DEST (set
), 0) = temp
;
15690 gcc_assert (GET_CODE (real
) == PARALLEL
);
15691 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
15692 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
15694 rtx set
= XVECEXP (real
, 0, i
);
15696 temp
= simplify_rtx (SET_SRC (set
));
15698 SET_SRC (set
) = temp
;
15699 temp
= simplify_rtx (SET_DEST (set
));
15701 SET_DEST (set
) = temp
;
15702 if (GET_CODE (SET_DEST (set
)) == MEM
)
15704 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
15706 XEXP (SET_DEST (set
), 0) = temp
;
15708 RTX_FRAME_RELATED_P (set
) = 1;
15712 RTX_FRAME_RELATED_P (insn
) = 1;
15713 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, real
);
15716 /* Returns an insn that has a vrsave set operation with the
15717 appropriate CLOBBERs. */
15720 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
15723 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
15724 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
15727 = gen_rtx_SET (VOIDmode
,
15729 gen_rtx_UNSPEC_VOLATILE (SImode
,
15730 gen_rtvec (2, reg
, vrsave
),
15731 UNSPECV_SET_VRSAVE
));
15735 /* We need to clobber the registers in the mask so the scheduler
15736 does not move sets to VRSAVE before sets of AltiVec registers.
15738 However, if the function receives nonlocal gotos, reload will set
15739 all call saved registers live. We will end up with:
15741 (set (reg 999) (mem))
15742 (parallel [ (set (reg vrsave) (unspec blah))
15743 (clobber (reg 999))])
15745 The clobber will cause the store into reg 999 to be dead, and
15746 flow will attempt to delete an epilogue insn. In this case, we
15747 need an unspec use/set of the register. */
15749 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
15750 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
15752 if (!epiloguep
|| call_used_regs
[i
])
15753 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
15754 gen_rtx_REG (V4SImode
, i
));
15757 rtx reg
= gen_rtx_REG (V4SImode
, i
);
15760 = gen_rtx_SET (VOIDmode
,
15762 gen_rtx_UNSPEC (V4SImode
,
15763 gen_rtvec (1, reg
), 27));
15767 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
15769 for (i
= 0; i
< nclobs
; ++i
)
15770 XVECEXP (insn
, 0, i
) = clobs
[i
];
15775 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
15776 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
15779 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
15780 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
15782 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
15783 rtx replacea
, replaceb
;
15785 int_rtx
= GEN_INT (offset
);
15787 /* Some cases that need register indexed addressing. */
15788 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
15789 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
15791 && SPE_VECTOR_MODE (mode
)
15792 && !SPE_CONST_OFFSET_OK (offset
)))
15794 /* Whomever calls us must make sure r11 is available in the
15795 flow path of instructions in the prologue. */
15796 offset_rtx
= gen_rtx_REG (Pmode
, 11);
15797 emit_move_insn (offset_rtx
, int_rtx
);
15799 replacea
= offset_rtx
;
15800 replaceb
= int_rtx
;
15804 offset_rtx
= int_rtx
;
15805 replacea
= NULL_RTX
;
15806 replaceb
= NULL_RTX
;
15809 reg
= gen_rtx_REG (mode
, regno
);
15810 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
15811 mem
= gen_frame_mem (mode
, addr
);
15813 insn
= emit_move_insn (mem
, reg
);
15815 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
15818 /* Emit an offset memory reference suitable for a frame store, while
15819 converting to a valid addressing mode. */
15822 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
15824 rtx int_rtx
, offset_rtx
;
15826 int_rtx
= GEN_INT (offset
);
15828 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
15829 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
15831 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
15832 emit_move_insn (offset_rtx
, int_rtx
);
15835 offset_rtx
= int_rtx
;
15837 return gen_frame_mem (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
15840 /* Look for user-defined global regs. We should not save and restore these,
15841 and cannot use stmw/lmw if there are any in its range. */
15844 no_global_regs_above (int first
, bool gpr
)
15847 for (i
= first
; i
< gpr
? 32 : 64 ; i
++)
15848 if (global_regs
[i
])
15853 #ifndef TARGET_FIX_AND_CONTINUE
15854 #define TARGET_FIX_AND_CONTINUE 0
15857 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
15858 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
15859 #define LAST_SAVRES_REGISTER 31
15860 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
15862 static GTY(()) rtx savres_routine_syms
[N_SAVRES_REGISTERS
][8];
15864 /* Return the symbol for an out-of-line register save/restore routine.
15865 We are saving/restoring GPRs if GPR is true. */
15868 rs6000_savres_routine_sym (rs6000_stack_t
*info
, bool savep
, bool gpr
, bool exitp
)
15870 int regno
= gpr
? info
->first_gp_reg_save
: (info
->first_fp_reg_save
- 32);
15872 int select
= ((savep
? 1 : 0) << 2
15874 /* On the SPE, we never have any FPRs, but we do have
15875 32/64-bit versions of the routines. */
15876 ? (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
? 1 : 0)
15880 /* Don't generate bogus routine names. */
15881 gcc_assert (FIRST_SAVRES_REGISTER
<= regno
&& regno
<= LAST_SAVRES_REGISTER
);
15883 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
];
15888 const char *action
;
15889 const char *regkind
;
15890 const char *exit_suffix
;
15892 action
= savep
? "save" : "rest";
15894 /* SPE has slightly different names for its routines depending on
15895 whether we are saving 32-bit or 64-bit registers. */
15896 if (TARGET_SPE_ABI
)
15898 /* No floating point saves on the SPE. */
15901 regkind
= info
->spe_64bit_regs_used
? "64gpr" : "32gpr";
15904 regkind
= gpr
? "gpr" : "fpr";
15906 exit_suffix
= exitp
? "_x" : "";
15908 sprintf (name
, "_%s%s_%d%s", action
, regkind
, regno
, exit_suffix
);
15910 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
]
15911 = gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (name
));
15917 /* Emit a sequence of insns, including a stack tie if needed, for
15918 resetting the stack pointer. If SAVRES is true, then don't reset the
15919 stack pointer, but move the base of the frame into r11 for use by
15920 out-of-line register restore routines. */
15923 rs6000_emit_stack_reset (rs6000_stack_t
*info
,
15924 rtx sp_reg_rtx
, rtx frame_reg_rtx
,
15925 int sp_offset
, bool savres
)
15927 /* This blockage is needed so that sched doesn't decide to move
15928 the sp change before the register restores. */
15929 if (frame_reg_rtx
!= sp_reg_rtx
15931 && info
->spe_64bit_regs_used
!= 0
15932 && info
->first_gp_reg_save
!= 32))
15933 rs6000_emit_stack_tie ();
15935 if (frame_reg_rtx
!= sp_reg_rtx
)
15937 if (sp_offset
!= 0)
15938 return emit_insn (gen_addsi3 (sp_reg_rtx
, frame_reg_rtx
,
15939 GEN_INT (sp_offset
)));
15941 return emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
15943 else if (sp_offset
!= 0)
15945 /* If we are restoring registers out-of-line, we will be using the
15946 "exit" variants of the restore routines, which will reset the
15947 stack for us. But we do need to point r11 into the right place
15948 for those routines. */
15949 rtx dest_reg
= (savres
15950 ? gen_rtx_REG (Pmode
, 11)
15953 rtx insn
= emit_insn (gen_add3_insn (dest_reg
, sp_reg_rtx
,
15954 GEN_INT (sp_offset
)));
15961 /* Construct a parallel rtx describing the effect of a call to an
15962 out-of-line register save/restore routine. */
15965 rs6000_make_savres_rtx (rs6000_stack_t
*info
,
15966 rtx frame_reg_rtx
, int save_area_offset
,
15967 enum machine_mode reg_mode
,
15968 bool savep
, bool gpr
, bool exitp
)
15971 int offset
, start_reg
, end_reg
, n_regs
;
15972 int reg_size
= GET_MODE_SIZE (reg_mode
);
15978 ? info
->first_gp_reg_save
15979 : info
->first_fp_reg_save
);
15980 end_reg
= gpr
? 32 : 64;
15981 n_regs
= end_reg
- start_reg
;
15982 p
= rtvec_alloc ((exitp
? 4 : 3) + n_regs
);
15984 /* If we're saving registers, then we should never say we're exiting. */
15985 gcc_assert ((savep
&& !exitp
) || !savep
);
15988 RTVEC_ELT (p
, offset
++) = gen_rtx_RETURN (VOIDmode
);
15990 RTVEC_ELT (p
, offset
++)
15991 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 65));
15993 sym
= rs6000_savres_routine_sym (info
, savep
, gpr
, exitp
);
15994 RTVEC_ELT (p
, offset
++) = gen_rtx_USE (VOIDmode
, sym
);
15995 RTVEC_ELT (p
, offset
++) = gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 11));
15997 for (i
= 0; i
< end_reg
- start_reg
; i
++)
15999 rtx addr
, reg
, mem
;
16000 reg
= gen_rtx_REG (reg_mode
, start_reg
+ i
);
16001 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16002 GEN_INT (save_area_offset
+ reg_size
*i
));
16003 mem
= gen_frame_mem (reg_mode
, addr
);
16005 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
,
16007 savep
? reg
: mem
);
16010 return gen_rtx_PARALLEL (VOIDmode
, p
);
16013 /* Determine whether the gp REG is really used. */
16016 rs6000_reg_live_or_pic_offset_p (int reg
)
16018 return ((df_regs_ever_live_p (reg
)
16019 && (!call_used_regs
[reg
]
16020 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
16021 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
16022 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
16023 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
16024 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))));
16028 SAVRES_MULTIPLE
= 0x1,
16029 SAVRES_INLINE_FPRS
= 0x2,
16030 SAVRES_INLINE_GPRS
= 0x4
16033 /* Determine the strategy for savings/restoring registers. */
16036 rs6000_savres_strategy (rs6000_stack_t
*info
, bool savep
,
16037 int using_static_chain_p
, int sibcall
)
16039 bool using_multiple_p
;
16041 bool savres_fprs_inline
;
16042 bool savres_gprs_inline
;
16043 bool noclobber_global_gprs
16044 = no_global_regs_above (info
->first_gp_reg_save
, /*gpr=*/true);
16046 using_multiple_p
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
16047 && (!TARGET_SPE_ABI
16048 || info
->spe_64bit_regs_used
== 0)
16049 && info
->first_gp_reg_save
< 31
16050 && noclobber_global_gprs
);
16051 /* Don't bother to try to save things out-of-line if r11 is occupied
16052 by the static chain. It would require too much fiddling and the
16053 static chain is rarely used anyway. */
16054 common
= (using_static_chain_p
16056 || crtl
->calls_eh_return
16057 || !info
->lr_save_p
16058 || cfun
->machine
->ra_need_lr
16059 || info
->total_size
> 32767);
16060 savres_fprs_inline
= (common
16061 || info
->first_fp_reg_save
== 64
16062 || !no_global_regs_above (info
->first_fp_reg_save
,
16064 || FP_SAVE_INLINE (info
->first_fp_reg_save
));
16065 savres_gprs_inline
= (common
16066 /* Saving CR interferes with the exit routines
16067 used on the SPE, so just punt here. */
16070 && info
->spe_64bit_regs_used
!= 0
16071 && info
->cr_save_p
!= 0)
16072 || info
->first_gp_reg_save
== 32
16073 || !noclobber_global_gprs
16074 || GP_SAVE_INLINE (info
->first_gp_reg_save
));
16077 /* If we are going to use store multiple, then don't even bother
16078 with the out-of-line routines, since the store-multiple instruction
16079 will always be smaller. */
16080 savres_gprs_inline
= savres_gprs_inline
|| using_multiple_p
;
16083 /* The situation is more complicated with load multiple. We'd
16084 prefer to use the out-of-line routines for restores, since the
16085 "exit" out-of-line routines can handle the restore of LR and
16086 the frame teardown. But we can only use the out-of-line
16087 routines if we know that we've used store multiple or
16088 out-of-line routines in the prologue, i.e. if we've saved all
16089 the registers from first_gp_reg_save. Otherwise, we risk
16090 loading garbage from the stack. Furthermore, we can only use
16091 the "exit" out-of-line gpr restore if we haven't saved any
16093 bool saved_all
= !savres_gprs_inline
|| using_multiple_p
;
16095 if (saved_all
&& info
->first_fp_reg_save
!= 64)
16096 /* We can't use the exit routine; use load multiple if it's
16098 savres_gprs_inline
= savres_gprs_inline
|| using_multiple_p
;
16101 return (using_multiple_p
16102 | (savres_fprs_inline
<< 1)
16103 | (savres_gprs_inline
<< 2));
16106 /* Emit function prologue as insns. */
16109 rs6000_emit_prologue (void)
16111 rs6000_stack_t
*info
= rs6000_stack_info ();
16112 enum machine_mode reg_mode
= Pmode
;
16113 int reg_size
= TARGET_32BIT
? 4 : 8;
16114 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
16115 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
16116 rtx frame_reg_rtx
= sp_reg_rtx
;
16117 rtx cr_save_rtx
= NULL_RTX
;
16120 int saving_FPRs_inline
;
16121 int saving_GPRs_inline
;
16122 int using_store_multiple
;
16123 int using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
16124 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
16125 && !call_used_regs
[STATIC_CHAIN_REGNUM
]);
16126 HOST_WIDE_INT sp_offset
= 0;
16128 if (TARGET_FIX_AND_CONTINUE
)
16130 /* gdb on darwin arranges to forward a function from the old
16131 address by modifying the first 5 instructions of the function
16132 to branch to the overriding function. This is necessary to
16133 permit function pointers that point to the old function to
16134 actually forward to the new function. */
16135 emit_insn (gen_nop ());
16136 emit_insn (gen_nop ());
16137 emit_insn (gen_nop ());
16138 emit_insn (gen_nop ());
16139 emit_insn (gen_nop ());
16142 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
16144 reg_mode
= V2SImode
;
16148 strategy
= rs6000_savres_strategy (info
, /*savep=*/true,
16149 /*static_chain_p=*/using_static_chain_p
,
16151 using_store_multiple
= strategy
& SAVRES_MULTIPLE
;
16152 saving_FPRs_inline
= strategy
& SAVRES_INLINE_FPRS
;
16153 saving_GPRs_inline
= strategy
& SAVRES_INLINE_GPRS
;
16155 /* For V.4, update stack before we do any saving and set back pointer. */
16156 if (! WORLD_SAVE_P (info
)
16158 && (DEFAULT_ABI
== ABI_V4
16159 || crtl
->calls_eh_return
))
16161 bool need_r11
= (TARGET_SPE
16162 ? (!saving_GPRs_inline
16163 && info
->spe_64bit_regs_used
== 0)
16164 : (!saving_FPRs_inline
|| !saving_GPRs_inline
));
16165 if (info
->total_size
< 32767)
16166 sp_offset
= info
->total_size
;
16168 frame_reg_rtx
= (need_r11
16169 ? gen_rtx_REG (Pmode
, 11)
16171 rs6000_emit_allocate_stack (info
->total_size
,
16172 (frame_reg_rtx
!= sp_reg_rtx
16173 && (info
->cr_save_p
16175 || info
->first_fp_reg_save
< 64
16176 || info
->first_gp_reg_save
< 32
16179 if (frame_reg_rtx
!= sp_reg_rtx
)
16180 rs6000_emit_stack_tie ();
16183 /* Handle world saves specially here. */
16184 if (WORLD_SAVE_P (info
))
16191 /* save_world expects lr in r0. */
16192 reg0
= gen_rtx_REG (Pmode
, 0);
16193 if (info
->lr_save_p
)
16195 insn
= emit_move_insn (reg0
,
16196 gen_rtx_REG (Pmode
, LR_REGNO
));
16197 RTX_FRAME_RELATED_P (insn
) = 1;
16200 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
16201 assumptions about the offsets of various bits of the stack
16203 gcc_assert (info
->gp_save_offset
== -220
16204 && info
->fp_save_offset
== -144
16205 && info
->lr_save_offset
== 8
16206 && info
->cr_save_offset
== 4
16209 && (!crtl
->calls_eh_return
16210 || info
->ehrd_offset
== -432)
16211 && info
->vrsave_save_offset
== -224
16212 && info
->altivec_save_offset
== -416);
16214 treg
= gen_rtx_REG (SImode
, 11);
16215 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
16217 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
16218 in R11. It also clobbers R12, so beware! */
16220 /* Preserve CR2 for save_world prologues */
16222 sz
+= 32 - info
->first_gp_reg_save
;
16223 sz
+= 64 - info
->first_fp_reg_save
;
16224 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
16225 p
= rtvec_alloc (sz
);
16227 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
16228 gen_rtx_REG (SImode
,
16230 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
16231 gen_rtx_SYMBOL_REF (Pmode
,
16233 /* We do floats first so that the instruction pattern matches
16235 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
16237 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
16238 ? DFmode
: SFmode
),
16239 info
->first_fp_reg_save
+ i
);
16240 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16241 GEN_INT (info
->fp_save_offset
16242 + sp_offset
+ 8 * i
));
16243 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
16244 ? DFmode
: SFmode
), addr
);
16246 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
16248 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
16250 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
16251 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16252 GEN_INT (info
->altivec_save_offset
16253 + sp_offset
+ 16 * i
));
16254 rtx mem
= gen_frame_mem (V4SImode
, addr
);
16256 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
16258 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16260 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16261 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16262 GEN_INT (info
->gp_save_offset
16263 + sp_offset
+ reg_size
* i
));
16264 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16266 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
16270 /* CR register traditionally saved as CR2. */
16271 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
16272 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16273 GEN_INT (info
->cr_save_offset
16275 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16277 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
16279 /* Explain about use of R0. */
16280 if (info
->lr_save_p
)
16282 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16283 GEN_INT (info
->lr_save_offset
16285 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16287 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg0
);
16289 /* Explain what happens to the stack pointer. */
16291 rtx newval
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
, treg
);
16292 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, sp_reg_rtx
, newval
);
16295 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16296 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16297 treg
, GEN_INT (-info
->total_size
));
16298 sp_offset
= info
->total_size
;
16301 /* If we use the link register, get it into r0. */
16302 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
16304 rtx addr
, reg
, mem
;
16306 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
16307 gen_rtx_REG (Pmode
, LR_REGNO
));
16308 RTX_FRAME_RELATED_P (insn
) = 1;
16310 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16311 GEN_INT (info
->lr_save_offset
+ sp_offset
));
16312 reg
= gen_rtx_REG (Pmode
, 0);
16313 mem
= gen_rtx_MEM (Pmode
, addr
);
16314 /* This should not be of rs6000_sr_alias_set, because of
16315 __builtin_return_address. */
16317 insn
= emit_move_insn (mem
, reg
);
16318 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16319 NULL_RTX
, NULL_RTX
);
16322 /* If we need to save CR, put it into r12. */
16323 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
16327 cr_save_rtx
= gen_rtx_REG (SImode
, 12);
16328 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
16329 RTX_FRAME_RELATED_P (insn
) = 1;
16330 /* Now, there's no way that dwarf2out_frame_debug_expr is going
16331 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
16332 But that's OK. All we have to do is specify that _one_ condition
16333 code register is saved in this stack slot. The thrower's epilogue
16334 will then restore all the call-saved registers.
16335 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
16336 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
16337 gen_rtx_REG (SImode
, CR2_REGNO
));
16338 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
16341 /* Do any required saving of fpr's. If only one or two to save, do
16342 it ourselves. Otherwise, call function. */
16343 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
16346 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
16347 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
16348 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
16349 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
,
16350 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
16352 info
->first_fp_reg_save
+ i
,
16353 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
16356 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
16360 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
16361 info
->fp_save_offset
+ sp_offset
,
16363 /*savep=*/true, /*gpr=*/false,
16365 insn
= emit_insn (par
);
16366 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16367 NULL_RTX
, NULL_RTX
);
16370 /* Save GPRs. This is done as a PARALLEL if we are using
16371 the store-multiple instructions. */
16372 if (!WORLD_SAVE_P (info
)
16374 && info
->spe_64bit_regs_used
!= 0
16375 && info
->first_gp_reg_save
!= 32)
16378 rtx spe_save_area_ptr
;
16380 /* Determine whether we can address all of the registers that need
16381 to be saved with an offset from the stack pointer that fits in
16382 the small const field for SPE memory instructions. */
16383 int spe_regs_addressable_via_sp
16384 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
16385 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
16386 && saving_GPRs_inline
);
16389 if (spe_regs_addressable_via_sp
)
16391 spe_save_area_ptr
= frame_reg_rtx
;
16392 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
16396 /* Make r11 point to the start of the SPE save area. We need
16397 to be careful here if r11 is holding the static chain. If
16398 it is, then temporarily save it in r0. We would use r0 as
16399 our base register here, but using r0 as a base register in
16400 loads and stores means something different from what we
16402 int ool_adjust
= (saving_GPRs_inline
16404 : (info
->first_gp_reg_save
16405 - (FIRST_SAVRES_REGISTER
+1))*8);
16406 HOST_WIDE_INT offset
= (info
->spe_gp_save_offset
16407 + sp_offset
- ool_adjust
);
16409 if (using_static_chain_p
)
16411 rtx r0
= gen_rtx_REG (Pmode
, 0);
16412 gcc_assert (info
->first_gp_reg_save
> 11);
16414 emit_move_insn (r0
, gen_rtx_REG (Pmode
, 11));
16417 spe_save_area_ptr
= gen_rtx_REG (Pmode
, 11);
16418 insn
= emit_insn (gen_addsi3 (spe_save_area_ptr
,
16420 GEN_INT (offset
)));
16421 /* We need to make sure the move to r11 gets noted for
16422 properly outputting unwind information. */
16423 if (!saving_GPRs_inline
)
16424 rs6000_frame_related (insn
, frame_reg_rtx
, offset
,
16425 NULL_RTX
, NULL_RTX
);
16429 if (saving_GPRs_inline
)
16431 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16432 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
16434 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16435 rtx offset
, addr
, mem
;
16437 /* We're doing all this to ensure that the offset fits into
16438 the immediate offset of 'evstdd'. */
16439 gcc_assert (SPE_CONST_OFFSET_OK (reg_size
* i
+ spe_offset
));
16441 offset
= GEN_INT (reg_size
* i
+ spe_offset
);
16442 addr
= gen_rtx_PLUS (Pmode
, spe_save_area_ptr
, offset
);
16443 mem
= gen_rtx_MEM (V2SImode
, addr
);
16445 insn
= emit_move_insn (mem
, reg
);
16447 rs6000_frame_related (insn
, spe_save_area_ptr
,
16448 info
->spe_gp_save_offset
16449 + sp_offset
+ reg_size
* i
,
16450 offset
, const0_rtx
);
16457 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
16459 /*savep=*/true, /*gpr=*/true,
16461 insn
= emit_insn (par
);
16462 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16463 NULL_RTX
, NULL_RTX
);
16467 /* Move the static chain pointer back. */
16468 if (using_static_chain_p
&& !spe_regs_addressable_via_sp
)
16469 emit_move_insn (gen_rtx_REG (Pmode
, 11), gen_rtx_REG (Pmode
, 0));
16471 else if (!WORLD_SAVE_P (info
) && !saving_GPRs_inline
)
16475 /* Need to adjust r11 if we saved any FPRs. */
16476 if (info
->first_fp_reg_save
!= 64)
16478 rtx r11
= gen_rtx_REG (reg_mode
, 11);
16479 rtx offset
= GEN_INT (info
->total_size
16480 + (-8 * (64-info
->first_fp_reg_save
)));
16481 rtx ptr_reg
= (sp_reg_rtx
== frame_reg_rtx
16482 ? sp_reg_rtx
: r11
);
16484 emit_insn (TARGET_32BIT
16485 ? gen_addsi3 (r11
, ptr_reg
, offset
)
16486 : gen_adddi3 (r11
, ptr_reg
, offset
));
16489 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
16490 info
->gp_save_offset
+ sp_offset
,
16492 /*savep=*/true, /*gpr=*/true,
16494 insn
= emit_insn (par
);
16495 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16496 NULL_RTX
, NULL_RTX
);
16498 else if (!WORLD_SAVE_P (info
) && using_store_multiple
)
16502 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
16503 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16505 rtx addr
, reg
, mem
;
16506 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16507 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16508 GEN_INT (info
->gp_save_offset
16511 mem
= gen_frame_mem (reg_mode
, addr
);
16513 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
16515 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16516 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16517 NULL_RTX
, NULL_RTX
);
16519 else if (!WORLD_SAVE_P (info
))
16522 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16523 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
16525 rtx addr
, reg
, mem
;
16526 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16528 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16529 GEN_INT (info
->gp_save_offset
16532 mem
= gen_frame_mem (reg_mode
, addr
);
16534 insn
= emit_move_insn (mem
, reg
);
16535 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16536 NULL_RTX
, NULL_RTX
);
16540 /* ??? There's no need to emit actual instructions here, but it's the
16541 easiest way to get the frame unwind information emitted. */
16542 if (crtl
->calls_eh_return
)
16544 unsigned int i
, regno
;
16546 /* In AIX ABI we need to pretend we save r2 here. */
16549 rtx addr
, reg
, mem
;
16551 reg
= gen_rtx_REG (reg_mode
, 2);
16552 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16553 GEN_INT (sp_offset
+ 5 * reg_size
));
16554 mem
= gen_frame_mem (reg_mode
, addr
);
16556 insn
= emit_move_insn (mem
, reg
);
16557 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16558 NULL_RTX
, NULL_RTX
);
16559 PATTERN (insn
) = gen_blockage ();
16564 regno
= EH_RETURN_DATA_REGNO (i
);
16565 if (regno
== INVALID_REGNUM
)
16568 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
16569 info
->ehrd_offset
+ sp_offset
16570 + reg_size
* (int) i
,
16575 /* Save CR if we use any that must be preserved. */
16576 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
16578 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16579 GEN_INT (info
->cr_save_offset
+ sp_offset
));
16580 rtx mem
= gen_frame_mem (SImode
, addr
);
16581 /* See the large comment above about why CR2_REGNO is used. */
16582 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
16584 /* If r12 was used to hold the original sp, copy cr into r0 now
16586 if (REGNO (frame_reg_rtx
) == 12)
16590 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
16591 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
16592 RTX_FRAME_RELATED_P (insn
) = 1;
16593 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
16594 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
16596 insn
= emit_move_insn (mem
, cr_save_rtx
);
16598 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16599 NULL_RTX
, NULL_RTX
);
16602 /* Update stack and set back pointer unless this is V.4,
16603 for which it was done previously. */
16604 if (!WORLD_SAVE_P (info
) && info
->push_p
16605 && !(DEFAULT_ABI
== ABI_V4
|| crtl
->calls_eh_return
))
16607 if (info
->total_size
< 32767)
16608 sp_offset
= info
->total_size
;
16610 frame_reg_rtx
= frame_ptr_rtx
;
16611 rs6000_emit_allocate_stack (info
->total_size
,
16612 (frame_reg_rtx
!= sp_reg_rtx
16613 && ((info
->altivec_size
!= 0)
16614 || (info
->vrsave_mask
!= 0)
16617 if (frame_reg_rtx
!= sp_reg_rtx
)
16618 rs6000_emit_stack_tie ();
16621 /* Set frame pointer, if needed. */
16622 if (frame_pointer_needed
)
16624 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
16626 RTX_FRAME_RELATED_P (insn
) = 1;
16629 /* Save AltiVec registers if needed. Save here because the red zone does
16630 not include AltiVec registers. */
16631 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
16635 /* There should be a non inline version of this, for when we
16636 are saving lots of vector registers. */
16637 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
16638 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
16640 rtx areg
, savereg
, mem
;
16643 offset
= info
->altivec_save_offset
+ sp_offset
16644 + 16 * (i
- info
->first_altivec_reg_save
);
16646 savereg
= gen_rtx_REG (V4SImode
, i
);
16648 areg
= gen_rtx_REG (Pmode
, 0);
16649 emit_move_insn (areg
, GEN_INT (offset
));
16651 /* AltiVec addressing mode is [reg+reg]. */
16652 mem
= gen_frame_mem (V4SImode
,
16653 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
16655 insn
= emit_move_insn (mem
, savereg
);
16657 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16658 areg
, GEN_INT (offset
));
16662 /* VRSAVE is a bit vector representing which AltiVec registers
16663 are used. The OS uses this to determine which vector
16664 registers to save on a context switch. We need to save
16665 VRSAVE on the stack frame, add whatever AltiVec registers we
16666 used in this function, and do the corresponding magic in the
16669 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
16670 && info
->vrsave_mask
!= 0)
16672 rtx reg
, mem
, vrsave
;
16675 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
16676 as frame_reg_rtx and r11 as the static chain pointer for
16677 nested functions. */
16678 reg
= gen_rtx_REG (SImode
, 0);
16679 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
16681 emit_insn (gen_get_vrsave_internal (reg
));
16683 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
16685 if (!WORLD_SAVE_P (info
))
16688 offset
= info
->vrsave_save_offset
+ sp_offset
;
16689 mem
= gen_frame_mem (SImode
,
16690 gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16691 GEN_INT (offset
)));
16692 insn
= emit_move_insn (mem
, reg
);
16695 /* Include the registers in the mask. */
16696 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
16698 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
16701 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
16702 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
16703 || (DEFAULT_ABI
== ABI_V4
16704 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
16705 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
)))
16707 /* If emit_load_toc_table will use the link register, we need to save
16708 it. We use R12 for this purpose because emit_load_toc_table
16709 can use register 0. This allows us to use a plain 'blr' to return
16710 from the procedure more often. */
16711 int save_LR_around_toc_setup
= (TARGET_ELF
16712 && DEFAULT_ABI
!= ABI_AIX
16714 && ! info
->lr_save_p
16715 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
16716 if (save_LR_around_toc_setup
)
16718 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
16720 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
16721 RTX_FRAME_RELATED_P (insn
) = 1;
16723 rs6000_emit_load_toc_table (TRUE
);
16725 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
16726 RTX_FRAME_RELATED_P (insn
) = 1;
16729 rs6000_emit_load_toc_table (TRUE
);
16733 if (DEFAULT_ABI
== ABI_DARWIN
16734 && flag_pic
&& crtl
->uses_pic_offset_table
)
16736 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
16737 rtx src
= gen_rtx_SYMBOL_REF (Pmode
, MACHOPIC_FUNCTION_BASE_NAME
);
16739 /* Save and restore LR locally around this call (in R0). */
16740 if (!info
->lr_save_p
)
16741 emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
);
16743 emit_insn (gen_load_macho_picbase (src
));
16745 emit_move_insn (gen_rtx_REG (Pmode
,
16746 RS6000_PIC_OFFSET_TABLE_REGNUM
),
16749 if (!info
->lr_save_p
)
16750 emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0));
16755 /* Write function prologue. */
16758 rs6000_output_function_prologue (FILE *file
,
16759 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
16761 rs6000_stack_t
*info
= rs6000_stack_info ();
16763 if (TARGET_DEBUG_STACK
)
16764 debug_stack_info (info
);
16766 /* Write .extern for any function we will call to save and restore
16768 if (info
->first_fp_reg_save
< 64
16769 && !FP_SAVE_INLINE (info
->first_fp_reg_save
))
16770 fprintf (file
, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
16771 SAVE_FP_PREFIX
, info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
,
16772 RESTORE_FP_PREFIX
, info
->first_fp_reg_save
- 32, RESTORE_FP_SUFFIX
);
16774 /* Write .extern for AIX common mode routines, if needed. */
16775 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
16777 fputs ("\t.extern __mulh\n", file
);
16778 fputs ("\t.extern __mull\n", file
);
16779 fputs ("\t.extern __divss\n", file
);
16780 fputs ("\t.extern __divus\n", file
);
16781 fputs ("\t.extern __quoss\n", file
);
16782 fputs ("\t.extern __quous\n", file
);
16783 common_mode_defined
= 1;
16786 if (! HAVE_prologue
)
16790 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
16791 the "toplevel" insn chain. */
16792 emit_note (NOTE_INSN_DELETED
);
16793 rs6000_emit_prologue ();
16794 emit_note (NOTE_INSN_DELETED
);
16796 /* Expand INSN_ADDRESSES so final() doesn't crash. */
16800 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
16802 INSN_ADDRESSES_NEW (insn
, addr
);
16807 if (TARGET_DEBUG_STACK
)
16808 debug_rtx_list (get_insns (), 100);
16809 final (get_insns (), file
, FALSE
);
16813 rs6000_pic_labelno
++;
16816 /* Non-zero if vmx regs are restored before the frame pop, zero if
16817 we restore after the pop when possible. */
16818 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
16820 /* Reload CR from REG. */
16823 rs6000_restore_saved_cr (rtx reg
, int using_mfcr_multiple
)
16828 if (using_mfcr_multiple
)
16830 for (i
= 0; i
< 8; i
++)
16831 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
16833 gcc_assert (count
);
16836 if (using_mfcr_multiple
&& count
> 1)
16841 p
= rtvec_alloc (count
);
16844 for (i
= 0; i
< 8; i
++)
16845 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
16847 rtvec r
= rtvec_alloc (2);
16848 RTVEC_ELT (r
, 0) = reg
;
16849 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
16850 RTVEC_ELT (p
, ndx
) =
16851 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
16852 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
16855 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16856 gcc_assert (ndx
== count
);
16859 for (i
= 0; i
< 8; i
++)
16860 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
16862 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
16868 /* Return true if OFFSET from stack pointer can be clobbered by signals.
16869 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
16870 below stack pointer not cloberred by signals. */
16873 offset_below_red_zone_p (HOST_WIDE_INT offset
)
16875 return offset
< (DEFAULT_ABI
== ABI_V4
16877 : TARGET_32BIT
? -220 : -288);
16880 /* Emit function epilogue as insns. */
16883 rs6000_emit_epilogue (int sibcall
)
16885 rs6000_stack_t
*info
;
16886 int restoring_GPRs_inline
;
16887 int restoring_FPRs_inline
;
16888 int using_load_multiple
;
16889 int using_mtcr_multiple
;
16890 int use_backchain_to_restore_sp
;
16894 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
16895 rtx frame_reg_rtx
= sp_reg_rtx
;
16896 rtx cfa_restores
= NULL_RTX
;
16898 enum machine_mode reg_mode
= Pmode
;
16899 int reg_size
= TARGET_32BIT
? 4 : 8;
16902 info
= rs6000_stack_info ();
16904 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
16906 reg_mode
= V2SImode
;
16910 strategy
= rs6000_savres_strategy (info
, /*savep=*/false,
16911 /*static_chain_p=*/0, sibcall
);
16912 using_load_multiple
= strategy
& SAVRES_MULTIPLE
;
16913 restoring_FPRs_inline
= strategy
& SAVRES_INLINE_FPRS
;
16914 restoring_GPRs_inline
= strategy
& SAVRES_INLINE_GPRS
;
16915 using_mtcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
16916 || rs6000_cpu
== PROCESSOR_PPC603
16917 || rs6000_cpu
== PROCESSOR_PPC750
16919 /* Restore via the backchain when we have a large frame, since this
16920 is more efficient than an addis, addi pair. The second condition
16921 here will not trigger at the moment; We don't actually need a
16922 frame pointer for alloca, but the generic parts of the compiler
16923 give us one anyway. */
16924 use_backchain_to_restore_sp
= (info
->total_size
> 32767
16925 || info
->total_size
16926 + (info
->lr_save_p
? info
->lr_save_offset
: 0)
16928 || (cfun
->calls_alloca
16929 && !frame_pointer_needed
));
16930 restore_lr
= (info
->lr_save_p
16931 && restoring_GPRs_inline
16932 && restoring_FPRs_inline
);
16934 if (WORLD_SAVE_P (info
))
16938 const char *alloc_rname
;
16941 /* eh_rest_world_r10 will return to the location saved in the LR
16942 stack slot (which is not likely to be our caller.)
16943 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
16944 rest_world is similar, except any R10 parameter is ignored.
16945 The exception-handling stuff that was here in 2.95 is no
16946 longer necessary. */
16950 + 32 - info
->first_gp_reg_save
16951 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
16952 + 63 + 1 - info
->first_fp_reg_save
);
16954 strcpy (rname
, ((crtl
->calls_eh_return
) ?
16955 "*eh_rest_world_r10" : "*rest_world"));
16956 alloc_rname
= ggc_strdup (rname
);
16959 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
16960 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
16961 gen_rtx_REG (Pmode
,
16964 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
16965 /* The instruction pattern requires a clobber here;
16966 it is shared with the restVEC helper. */
16968 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
16971 /* CR register traditionally saved as CR2. */
16972 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
16973 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16974 GEN_INT (info
->cr_save_offset
));
16975 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16977 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16980 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16982 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16983 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16984 GEN_INT (info
->gp_save_offset
16986 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16988 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16990 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
16992 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
16993 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16994 GEN_INT (info
->altivec_save_offset
16996 rtx mem
= gen_frame_mem (V4SImode
, addr
);
16998 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
17000 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
17002 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
17003 ? DFmode
: SFmode
),
17004 info
->first_fp_reg_save
+ i
);
17005 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17006 GEN_INT (info
->fp_save_offset
17008 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
17009 ? DFmode
: SFmode
), addr
);
17011 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
17014 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
17016 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
17018 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
17020 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
17022 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
17023 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
17028 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
17030 sp_offset
= info
->total_size
;
17032 /* Restore AltiVec registers if we must do so before adjusting the
17034 if (TARGET_ALTIVEC_ABI
17035 && info
->altivec_size
!= 0
17036 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
17037 || (DEFAULT_ABI
!= ABI_V4
17038 && offset_below_red_zone_p (info
->altivec_save_offset
))))
17042 if (use_backchain_to_restore_sp
)
17044 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
17045 emit_move_insn (frame_reg_rtx
,
17046 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
17049 else if (frame_pointer_needed
)
17050 frame_reg_rtx
= hard_frame_pointer_rtx
;
17052 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
17053 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
17055 rtx addr
, areg
, mem
, reg
;
17057 areg
= gen_rtx_REG (Pmode
, 0);
17059 (areg
, GEN_INT (info
->altivec_save_offset
17061 + 16 * (i
- info
->first_altivec_reg_save
)));
17063 /* AltiVec addressing mode is [reg+reg]. */
17064 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
17065 mem
= gen_frame_mem (V4SImode
, addr
);
17067 reg
= gen_rtx_REG (V4SImode
, i
);
17068 emit_move_insn (reg
, mem
);
17069 if (offset_below_red_zone_p (info
->altivec_save_offset
17070 + (i
- info
->first_altivec_reg_save
)
17072 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
17077 /* Restore VRSAVE if we must do so before adjusting the stack. */
17079 && TARGET_ALTIVEC_VRSAVE
17080 && info
->vrsave_mask
!= 0
17081 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
17082 || (DEFAULT_ABI
!= ABI_V4
17083 && offset_below_red_zone_p (info
->vrsave_save_offset
))))
17085 rtx addr
, mem
, reg
;
17087 if (frame_reg_rtx
== sp_reg_rtx
)
17089 if (use_backchain_to_restore_sp
)
17091 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
17092 emit_move_insn (frame_reg_rtx
,
17093 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
17096 else if (frame_pointer_needed
)
17097 frame_reg_rtx
= hard_frame_pointer_rtx
;
17100 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17101 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
17102 mem
= gen_frame_mem (SImode
, addr
);
17103 reg
= gen_rtx_REG (SImode
, 12);
17104 emit_move_insn (reg
, mem
);
17106 emit_insn (generate_set_vrsave (reg
, info
, 1));
17110 /* If we have a large stack frame, restore the old stack pointer
17111 using the backchain. */
17112 if (use_backchain_to_restore_sp
)
17114 if (frame_reg_rtx
== sp_reg_rtx
)
17116 /* Under V.4, don't reset the stack pointer until after we're done
17117 loading the saved registers. */
17118 if (DEFAULT_ABI
== ABI_V4
)
17119 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
17121 insn
= emit_move_insn (frame_reg_rtx
,
17122 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
17125 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
17126 && DEFAULT_ABI
== ABI_V4
)
17127 /* frame_reg_rtx has been set up by the altivec restore. */
17131 insn
= emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
17132 frame_reg_rtx
= sp_reg_rtx
;
17135 /* If we have a frame pointer, we can restore the old stack pointer
17137 else if (frame_pointer_needed
)
17139 frame_reg_rtx
= sp_reg_rtx
;
17140 if (DEFAULT_ABI
== ABI_V4
)
17141 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
17143 insn
= emit_insn (gen_add3_insn (frame_reg_rtx
, hard_frame_pointer_rtx
,
17144 GEN_INT (info
->total_size
)));
17147 else if (info
->push_p
17148 && DEFAULT_ABI
!= ABI_V4
17149 && !crtl
->calls_eh_return
)
17151 insn
= emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
,
17152 GEN_INT (info
->total_size
)));
17155 if (insn
&& frame_reg_rtx
== sp_reg_rtx
)
17159 REG_NOTES (insn
) = cfa_restores
;
17160 cfa_restores
= NULL_RTX
;
17162 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
17163 RTX_FRAME_RELATED_P (insn
) = 1;
17166 /* Restore AltiVec registers if we have not done so already. */
17167 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
17168 && TARGET_ALTIVEC_ABI
17169 && info
->altivec_size
!= 0
17170 && (DEFAULT_ABI
== ABI_V4
17171 || !offset_below_red_zone_p (info
->altivec_save_offset
)))
17175 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
17176 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
17178 rtx addr
, areg
, mem
, reg
;
17180 areg
= gen_rtx_REG (Pmode
, 0);
17182 (areg
, GEN_INT (info
->altivec_save_offset
17184 + 16 * (i
- info
->first_altivec_reg_save
)));
17186 /* AltiVec addressing mode is [reg+reg]. */
17187 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
17188 mem
= gen_frame_mem (V4SImode
, addr
);
17190 reg
= gen_rtx_REG (V4SImode
, i
);
17191 emit_move_insn (reg
, mem
);
17192 if (DEFAULT_ABI
== ABI_V4
)
17193 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
17198 /* Restore VRSAVE if we have not done so already. */
17199 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
17201 && TARGET_ALTIVEC_VRSAVE
17202 && info
->vrsave_mask
!= 0
17203 && (DEFAULT_ABI
== ABI_V4
17204 || !offset_below_red_zone_p (info
->vrsave_save_offset
)))
17206 rtx addr
, mem
, reg
;
17208 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17209 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
17210 mem
= gen_frame_mem (SImode
, addr
);
17211 reg
= gen_rtx_REG (SImode
, 12);
17212 emit_move_insn (reg
, mem
);
17214 emit_insn (generate_set_vrsave (reg
, info
, 1));
17217 /* Get the old lr if we saved it. If we are restoring registers
17218 out-of-line, then the out-of-line routines can do this for us. */
17221 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
17222 info
->lr_save_offset
+ sp_offset
);
17224 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
17227 /* Get the old cr if we saved it. */
17228 if (info
->cr_save_p
)
17230 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17231 GEN_INT (info
->cr_save_offset
+ sp_offset
));
17232 rtx mem
= gen_frame_mem (SImode
, addr
);
17234 emit_move_insn (gen_rtx_REG (SImode
, 12), mem
);
17237 /* Set LR here to try to overlap restores below. LR is always saved
17238 above incoming stack, so it never needs REG_CFA_RESTORE. */
17240 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
17241 gen_rtx_REG (Pmode
, 0));
17243 /* Load exception handler data registers, if needed. */
17244 if (crtl
->calls_eh_return
)
17246 unsigned int i
, regno
;
17250 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17251 GEN_INT (sp_offset
+ 5 * reg_size
));
17252 rtx mem
= gen_frame_mem (reg_mode
, addr
);
17254 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
17261 regno
= EH_RETURN_DATA_REGNO (i
);
17262 if (regno
== INVALID_REGNUM
)
17265 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
17266 info
->ehrd_offset
+ sp_offset
17267 + reg_size
* (int) i
);
17269 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
17273 /* Restore GPRs. This is done as a PARALLEL if we are using
17274 the load-multiple instructions. */
17276 && info
->spe_64bit_regs_used
!= 0
17277 && info
->first_gp_reg_save
!= 32)
17279 /* Determine whether we can address all of the registers that need
17280 to be saved with an offset from the stack pointer that fits in
17281 the small const field for SPE memory instructions. */
17282 int spe_regs_addressable_via_sp
17283 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
17284 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
17285 && restoring_GPRs_inline
);
17288 if (spe_regs_addressable_via_sp
)
17289 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
17292 rtx old_frame_reg_rtx
= frame_reg_rtx
;
17293 /* Make r11 point to the start of the SPE save area. We worried about
17294 not clobbering it when we were saving registers in the prologue.
17295 There's no need to worry here because the static chain is passed
17296 anew to every function. */
17297 int ool_adjust
= (restoring_GPRs_inline
17299 : (info
->first_gp_reg_save
17300 - (FIRST_SAVRES_REGISTER
+1))*8);
17302 if (frame_reg_rtx
== sp_reg_rtx
)
17303 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
17304 emit_insn (gen_addsi3 (frame_reg_rtx
, old_frame_reg_rtx
,
17305 GEN_INT (info
->spe_gp_save_offset
17308 /* Keep the invariant that frame_reg_rtx + sp_offset points
17309 at the top of the stack frame. */
17310 sp_offset
= -info
->spe_gp_save_offset
;
17315 if (restoring_GPRs_inline
)
17317 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
17318 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
17320 rtx offset
, addr
, mem
, reg
;
17322 /* We're doing all this to ensure that the immediate offset
17323 fits into the immediate field of 'evldd'. */
17324 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset
+ reg_size
* i
));
17326 offset
= GEN_INT (spe_offset
+ reg_size
* i
);
17327 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, offset
);
17328 mem
= gen_rtx_MEM (V2SImode
, addr
);
17329 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
17331 insn
= emit_move_insn (reg
, mem
);
17332 if (DEFAULT_ABI
== ABI_V4
)
17334 if (frame_pointer_needed
17335 && info
->first_gp_reg_save
+ i
17336 == HARD_FRAME_POINTER_REGNUM
)
17338 add_reg_note (insn
, REG_CFA_DEF_CFA
,
17339 plus_constant (frame_reg_rtx
,
17341 RTX_FRAME_RELATED_P (insn
) = 1;
17344 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
17353 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
17355 /*savep=*/false, /*gpr=*/true,
17357 emit_jump_insn (par
);
17358 /* We don't want anybody else emitting things after we jumped
17363 else if (!restoring_GPRs_inline
)
17365 /* We are jumping to an out-of-line function. */
17366 bool can_use_exit
= info
->first_fp_reg_save
== 64;
17369 /* Emit stack reset code if we need it. */
17371 rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
17372 sp_offset
, can_use_exit
);
17374 emit_insn (gen_addsi3 (gen_rtx_REG (Pmode
, 11),
17376 GEN_INT (sp_offset
- info
->fp_size
)));
17378 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
17379 info
->gp_save_offset
, reg_mode
,
17380 /*savep=*/false, /*gpr=*/true,
17381 /*exitp=*/can_use_exit
);
17385 if (info
->cr_save_p
)
17387 rs6000_restore_saved_cr (gen_rtx_REG (SImode
, 12),
17388 using_mtcr_multiple
);
17389 if (DEFAULT_ABI
== ABI_V4
)
17391 = alloc_reg_note (REG_CFA_RESTORE
,
17392 gen_rtx_REG (SImode
, CR2_REGNO
),
17396 emit_jump_insn (par
);
17398 /* We don't want anybody else emitting things after we jumped
17403 insn
= emit_insn (par
);
17404 if (DEFAULT_ABI
== ABI_V4
)
17406 if (frame_pointer_needed
)
17408 add_reg_note (insn
, REG_CFA_DEF_CFA
,
17409 plus_constant (frame_reg_rtx
, sp_offset
));
17410 RTX_FRAME_RELATED_P (insn
) = 1;
17413 for (i
= info
->first_gp_reg_save
; i
< 32; i
++)
17415 = alloc_reg_note (REG_CFA_RESTORE
,
17416 gen_rtx_REG (reg_mode
, i
), cfa_restores
);
17419 else if (using_load_multiple
)
17422 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
17423 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
17425 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17426 GEN_INT (info
->gp_save_offset
17429 rtx mem
= gen_frame_mem (reg_mode
, addr
);
17430 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
17432 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, reg
, mem
);
17433 if (DEFAULT_ABI
== ABI_V4
)
17434 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
17437 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
17438 if (DEFAULT_ABI
== ABI_V4
&& frame_pointer_needed
)
17440 add_reg_note (insn
, REG_CFA_DEF_CFA
,
17441 plus_constant (frame_reg_rtx
, sp_offset
));
17442 RTX_FRAME_RELATED_P (insn
) = 1;
17447 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
17448 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
17450 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17451 GEN_INT (info
->gp_save_offset
17454 rtx mem
= gen_frame_mem (reg_mode
, addr
);
17455 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
17457 insn
= emit_move_insn (reg
, mem
);
17458 if (DEFAULT_ABI
== ABI_V4
)
17460 if (frame_pointer_needed
17461 && info
->first_gp_reg_save
+ i
17462 == HARD_FRAME_POINTER_REGNUM
)
17464 add_reg_note (insn
, REG_CFA_DEF_CFA
,
17465 plus_constant (frame_reg_rtx
, sp_offset
));
17466 RTX_FRAME_RELATED_P (insn
) = 1;
17469 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
17475 /* Restore fpr's if we need to do it without calling a function. */
17476 if (restoring_FPRs_inline
)
17477 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
17478 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
17479 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
17481 rtx addr
, mem
, reg
;
17482 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17483 GEN_INT (info
->fp_save_offset
17486 mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
17487 ? DFmode
: SFmode
), addr
);
17488 reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
17489 ? DFmode
: SFmode
),
17490 info
->first_fp_reg_save
+ i
);
17492 emit_move_insn (reg
, mem
);
17493 if (DEFAULT_ABI
== ABI_V4
)
17494 cfa_restores
= alloc_reg_note (REG_CFA_RESTORE
, reg
,
17498 /* If we saved cr, restore it here. Just those that were used. */
17499 if (info
->cr_save_p
)
17501 rs6000_restore_saved_cr (gen_rtx_REG (SImode
, 12), using_mtcr_multiple
);
17502 if (DEFAULT_ABI
== ABI_V4
)
17504 = alloc_reg_note (REG_CFA_RESTORE
, gen_rtx_REG (SImode
, CR2_REGNO
),
17508 /* If this is V.4, unwind the stack pointer after all of the loads
17510 insn
= rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
17511 sp_offset
, !restoring_FPRs_inline
);
17516 REG_NOTES (insn
) = cfa_restores
;
17517 cfa_restores
= NULL_RTX
;
17519 add_reg_note (insn
, REG_CFA_DEF_CFA
, sp_reg_rtx
);
17520 RTX_FRAME_RELATED_P (insn
) = 1;
17523 if (crtl
->calls_eh_return
)
17525 rtx sa
= EH_RETURN_STACKADJ_RTX
;
17526 emit_insn (gen_add3_insn (sp_reg_rtx
, sp_reg_rtx
, sa
));
17532 if (! restoring_FPRs_inline
)
17533 p
= rtvec_alloc (4 + 64 - info
->first_fp_reg_save
);
17535 p
= rtvec_alloc (2);
17537 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
17538 RTVEC_ELT (p
, 1) = (restoring_FPRs_inline
17539 ? gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 65))
17540 : gen_rtx_CLOBBER (VOIDmode
,
17541 gen_rtx_REG (Pmode
, 65)));
17543 /* If we have to restore more than two FP registers, branch to the
17544 restore function. It will return to our caller. */
17545 if (! restoring_FPRs_inline
)
17550 sym
= rs6000_savres_routine_sym (info
,
17554 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
, sym
);
17555 RTVEC_ELT (p
, 3) = gen_rtx_USE (VOIDmode
,
17556 gen_rtx_REG (Pmode
, 11));
17557 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
17560 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
17561 GEN_INT (info
->fp_save_offset
+ 8*i
));
17562 mem
= gen_frame_mem (DFmode
, addr
);
17564 RTVEC_ELT (p
, i
+4) =
17565 gen_rtx_SET (VOIDmode
,
17566 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
17571 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
17575 /* Write function epilogue. */
17578 rs6000_output_function_epilogue (FILE *file
,
17579 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
17581 if (! HAVE_epilogue
)
17583 rtx insn
= get_last_insn ();
17584 /* If the last insn was a BARRIER, we don't have to write anything except
17585 the trace table. */
17586 if (GET_CODE (insn
) == NOTE
)
17587 insn
= prev_nonnote_insn (insn
);
17588 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
17590 /* This is slightly ugly, but at least we don't have two
17591 copies of the epilogue-emitting code. */
17594 /* A NOTE_INSN_DELETED is supposed to be at the start
17595 and end of the "toplevel" insn chain. */
17596 emit_note (NOTE_INSN_DELETED
);
17597 rs6000_emit_epilogue (FALSE
);
17598 emit_note (NOTE_INSN_DELETED
);
17600 /* Expand INSN_ADDRESSES so final() doesn't crash. */
17604 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
17606 INSN_ADDRESSES_NEW (insn
, addr
);
17611 if (TARGET_DEBUG_STACK
)
17612 debug_rtx_list (get_insns (), 100);
17613 final (get_insns (), file
, FALSE
);
17619 macho_branch_islands ();
17620 /* Mach-O doesn't support labels at the end of objects, so if
17621 it looks like we might want one, insert a NOP. */
17623 rtx insn
= get_last_insn ();
17626 && NOTE_KIND (insn
) != NOTE_INSN_DELETED_LABEL
)
17627 insn
= PREV_INSN (insn
);
17631 && NOTE_KIND (insn
) == NOTE_INSN_DELETED_LABEL
)))
17632 fputs ("\tnop\n", file
);
17636 /* Output a traceback table here. See /usr/include/sys/debug.h for info
17639 We don't output a traceback table if -finhibit-size-directive was
17640 used. The documentation for -finhibit-size-directive reads
17641 ``don't output a @code{.size} assembler directive, or anything
17642 else that would cause trouble if the function is split in the
17643 middle, and the two halves are placed at locations far apart in
17644 memory.'' The traceback table has this property, since it
17645 includes the offset from the start of the function to the
17646 traceback table itself.
17648 System V.4 Powerpc's (and the embedded ABI derived from it) use a
17649 different traceback table. */
17650 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
17651 && rs6000_traceback
!= traceback_none
&& !cfun
->is_thunk
)
17653 const char *fname
= NULL
;
17654 const char *language_string
= lang_hooks
.name
;
17655 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
17657 int optional_tbtab
;
17658 rs6000_stack_t
*info
= rs6000_stack_info ();
17660 if (rs6000_traceback
== traceback_full
)
17661 optional_tbtab
= 1;
17662 else if (rs6000_traceback
== traceback_part
)
17663 optional_tbtab
= 0;
17665 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
17667 if (optional_tbtab
)
17669 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
17670 while (*fname
== '.') /* V.4 encodes . in the name */
17673 /* Need label immediately before tbtab, so we can compute
17674 its offset from the function start. */
17675 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
17676 ASM_OUTPUT_LABEL (file
, fname
);
17679 /* The .tbtab pseudo-op can only be used for the first eight
17680 expressions, since it can't handle the possibly variable
17681 length fields that follow. However, if you omit the optional
17682 fields, the assembler outputs zeros for all optional fields
17683 anyways, giving each variable length field is minimum length
17684 (as defined in sys/debug.h). Thus we can not use the .tbtab
17685 pseudo-op at all. */
17687 /* An all-zero word flags the start of the tbtab, for debuggers
17688 that have to find it by searching forward from the entry
17689 point or from the current pc. */
17690 fputs ("\t.long 0\n", file
);
17692 /* Tbtab format type. Use format type 0. */
17693 fputs ("\t.byte 0,", file
);
17695 /* Language type. Unfortunately, there does not seem to be any
17696 official way to discover the language being compiled, so we
17697 use language_string.
17698 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
17699 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
17700 a number, so for now use 9. */
17701 if (! strcmp (language_string
, "GNU C"))
17703 else if (! strcmp (language_string
, "GNU F77")
17704 || ! strcmp (language_string
, "GNU Fortran"))
17706 else if (! strcmp (language_string
, "GNU Pascal"))
17708 else if (! strcmp (language_string
, "GNU Ada"))
17710 else if (! strcmp (language_string
, "GNU C++")
17711 || ! strcmp (language_string
, "GNU Objective-C++"))
17713 else if (! strcmp (language_string
, "GNU Java"))
17715 else if (! strcmp (language_string
, "GNU Objective-C"))
17718 gcc_unreachable ();
17719 fprintf (file
, "%d,", i
);
17721 /* 8 single bit fields: global linkage (not set for C extern linkage,
17722 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
17723 from start of procedure stored in tbtab, internal function, function
17724 has controlled storage, function has no toc, function uses fp,
17725 function logs/aborts fp operations. */
17726 /* Assume that fp operations are used if any fp reg must be saved. */
17727 fprintf (file
, "%d,",
17728 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
17730 /* 6 bitfields: function is interrupt handler, name present in
17731 proc table, function calls alloca, on condition directives
17732 (controls stack walks, 3 bits), saves condition reg, saves
17734 /* The `function calls alloca' bit seems to be set whenever reg 31 is
17735 set up as a frame pointer, even when there is no alloca call. */
17736 fprintf (file
, "%d,",
17737 ((optional_tbtab
<< 6)
17738 | ((optional_tbtab
& frame_pointer_needed
) << 5)
17739 | (info
->cr_save_p
<< 1)
17740 | (info
->lr_save_p
)));
17742 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
17744 fprintf (file
, "%d,",
17745 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
17747 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
17748 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
17750 if (optional_tbtab
)
17752 /* Compute the parameter info from the function decl argument
17755 int next_parm_info_bit
= 31;
17757 for (decl
= DECL_ARGUMENTS (current_function_decl
);
17758 decl
; decl
= TREE_CHAIN (decl
))
17760 rtx parameter
= DECL_INCOMING_RTL (decl
);
17761 enum machine_mode mode
= GET_MODE (parameter
);
17763 if (GET_CODE (parameter
) == REG
)
17765 if (SCALAR_FLOAT_MODE_P (mode
))
17786 gcc_unreachable ();
17789 /* If only one bit will fit, don't or in this entry. */
17790 if (next_parm_info_bit
> 0)
17791 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
17792 next_parm_info_bit
-= 2;
17796 fixed_parms
+= ((GET_MODE_SIZE (mode
)
17797 + (UNITS_PER_WORD
- 1))
17799 next_parm_info_bit
-= 1;
17805 /* Number of fixed point parameters. */
17806 /* This is actually the number of words of fixed point parameters; thus
17807 an 8 byte struct counts as 2; and thus the maximum value is 8. */
17808 fprintf (file
, "%d,", fixed_parms
);
17810 /* 2 bitfields: number of floating point parameters (7 bits), parameters
17812 /* This is actually the number of fp registers that hold parameters;
17813 and thus the maximum value is 13. */
17814 /* Set parameters on stack bit if parameters are not in their original
17815 registers, regardless of whether they are on the stack? Xlc
17816 seems to set the bit when not optimizing. */
17817 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
17819 if (! optional_tbtab
)
17822 /* Optional fields follow. Some are variable length. */
17824 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
17825 11 double float. */
17826 /* There is an entry for each parameter in a register, in the order that
17827 they occur in the parameter list. Any intervening arguments on the
17828 stack are ignored. If the list overflows a long (max possible length
17829 34 bits) then completely leave off all elements that don't fit. */
17830 /* Only emit this long if there was at least one parameter. */
17831 if (fixed_parms
|| float_parms
)
17832 fprintf (file
, "\t.long %d\n", parm_info
);
17834 /* Offset from start of code to tb table. */
17835 fputs ("\t.long ", file
);
17836 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
17838 RS6000_OUTPUT_BASENAME (file
, fname
);
17840 assemble_name (file
, fname
);
17842 rs6000_output_function_entry (file
, fname
);
17845 /* Interrupt handler mask. */
17846 /* Omit this long, since we never set the interrupt handler bit
17849 /* Number of CTL (controlled storage) anchors. */
17850 /* Omit this long, since the has_ctl bit is never set above. */
17852 /* Displacement into stack of each CTL anchor. */
17853 /* Omit this list of longs, because there are no CTL anchors. */
17855 /* Length of function name. */
17858 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
17860 /* Function name. */
17861 assemble_string (fname
, strlen (fname
));
17863 /* Register for alloca automatic storage; this is always reg 31.
17864 Only emit this if the alloca bit was set above. */
17865 if (frame_pointer_needed
)
17866 fputs ("\t.byte 31\n", file
);
17868 fputs ("\t.align 2\n", file
);
17872 /* A C compound statement that outputs the assembler code for a thunk
17873 function, used to implement C++ virtual function calls with
17874 multiple inheritance. The thunk acts as a wrapper around a virtual
17875 function, adjusting the implicit object parameter before handing
17876 control off to the real function.
17878 First, emit code to add the integer DELTA to the location that
17879 contains the incoming first argument. Assume that this argument
17880 contains a pointer, and is the one used to pass the `this' pointer
17881 in C++. This is the incoming argument *before* the function
17882 prologue, e.g. `%o0' on a sparc. The addition must preserve the
17883 values of all other incoming arguments.
17885 After the addition, emit code to jump to FUNCTION, which is a
17886 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
17887 not touch the return address. Hence returning from FUNCTION will
17888 return to whoever called the current `thunk'.
17890 The effect must be as if FUNCTION had been called directly with the
17891 adjusted first argument. This macro is responsible for emitting
17892 all of the code for a thunk function; output_function_prologue()
17893 and output_function_epilogue() are not invoked.
17895 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
17896 been extracted from it.) It might possibly be useful on some
17897 targets, but probably not.
17899 If you do not define this macro, the target-independent code in the
17900 C++ frontend will generate a less efficient heavyweight thunk that
17901 calls FUNCTION instead of jumping to it. The generic approach does
17902 not support varargs. */
17905 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
17906 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
17909 rtx this_rtx
, insn
, funexp
;
17911 reload_completed
= 1;
17912 epilogue_completed
= 1;
17914 /* Mark the end of the (empty) prologue. */
17915 emit_note (NOTE_INSN_PROLOGUE_END
);
17917 /* Find the "this" pointer. If the function returns a structure,
17918 the structure return pointer is in r3. */
17919 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
17920 this_rtx
= gen_rtx_REG (Pmode
, 4);
17922 this_rtx
= gen_rtx_REG (Pmode
, 3);
17924 /* Apply the constant offset, if required. */
17927 rtx delta_rtx
= GEN_INT (delta
);
17928 emit_insn (TARGET_32BIT
17929 ? gen_addsi3 (this_rtx
, this_rtx
, delta_rtx
)
17930 : gen_adddi3 (this_rtx
, this_rtx
, delta_rtx
));
17933 /* Apply the offset from the vtable, if required. */
17936 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
17937 rtx tmp
= gen_rtx_REG (Pmode
, 12);
17939 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this_rtx
));
17940 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
17942 emit_insn (TARGET_32BIT
17943 ? gen_addsi3 (tmp
, tmp
, vcall_offset_rtx
)
17944 : gen_adddi3 (tmp
, tmp
, vcall_offset_rtx
));
17945 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
17949 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
17951 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
17953 emit_insn (TARGET_32BIT
17954 ? gen_addsi3 (this_rtx
, this_rtx
, tmp
)
17955 : gen_adddi3 (this_rtx
, this_rtx
, tmp
));
17958 /* Generate a tail call to the target function. */
17959 if (!TREE_USED (function
))
17961 assemble_external (function
);
17962 TREE_USED (function
) = 1;
17964 funexp
= XEXP (DECL_RTL (function
), 0);
17965 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
17968 if (MACHOPIC_INDIRECT
)
17969 funexp
= machopic_indirect_call_target (funexp
);
17972 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
17973 generate sibcall RTL explicitly. */
17974 insn
= emit_call_insn (
17975 gen_rtx_PARALLEL (VOIDmode
,
17977 gen_rtx_CALL (VOIDmode
,
17978 funexp
, const0_rtx
),
17979 gen_rtx_USE (VOIDmode
, const0_rtx
),
17980 gen_rtx_USE (VOIDmode
,
17981 gen_rtx_REG (SImode
,
17983 gen_rtx_RETURN (VOIDmode
))));
17984 SIBLING_CALL_P (insn
) = 1;
17987 /* Run just enough of rest_of_compilation to get the insns emitted.
17988 There's not really enough bulk here to make other passes such as
17989 instruction scheduling worth while. Note that use_thunk calls
17990 assemble_start_function and assemble_end_function. */
17991 insn
= get_insns ();
17992 insn_locators_alloc ();
17993 shorten_branches (insn
);
17994 final_start_function (insn
, file
, 1);
17995 final (insn
, file
, 1);
17996 final_end_function ();
17997 free_after_compilation (cfun
);
17999 reload_completed
= 0;
18000 epilogue_completed
= 0;
18003 /* A quick summary of the various types of 'constant-pool tables'
18006 Target Flags Name One table per
18007 AIX (none) AIX TOC object file
18008 AIX -mfull-toc AIX TOC object file
18009 AIX -mminimal-toc AIX minimal TOC translation unit
18010 SVR4/EABI (none) SVR4 SDATA object file
18011 SVR4/EABI -fpic SVR4 pic object file
18012 SVR4/EABI -fPIC SVR4 PIC translation unit
18013 SVR4/EABI -mrelocatable EABI TOC function
18014 SVR4/EABI -maix AIX TOC object file
18015 SVR4/EABI -maix -mminimal-toc
18016 AIX minimal TOC translation unit
18018 Name Reg. Set by entries contains:
18019 made by addrs? fp? sum?
18021 AIX TOC 2 crt0 as Y option option
18022 AIX minimal TOC 30 prolog gcc Y Y option
18023 SVR4 SDATA 13 crt0 gcc N Y N
18024 SVR4 pic 30 prolog ld Y not yet N
18025 SVR4 PIC 30 prolog gcc Y option option
18026 EABI TOC 30 prolog gcc Y option option
18030 /* Hash functions for the hash table. */
18033 rs6000_hash_constant (rtx k
)
18035 enum rtx_code code
= GET_CODE (k
);
18036 enum machine_mode mode
= GET_MODE (k
);
18037 unsigned result
= (code
<< 3) ^ mode
;
18038 const char *format
;
18041 format
= GET_RTX_FORMAT (code
);
18042 flen
= strlen (format
);
18048 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
18051 if (mode
!= VOIDmode
)
18052 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
18064 for (; fidx
< flen
; fidx
++)
18065 switch (format
[fidx
])
18070 const char *str
= XSTR (k
, fidx
);
18071 len
= strlen (str
);
18072 result
= result
* 613 + len
;
18073 for (i
= 0; i
< len
; i
++)
18074 result
= result
* 613 + (unsigned) str
[i
];
18079 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
18083 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
18086 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
18087 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
18091 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
18092 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
18099 gcc_unreachable ();
18106 toc_hash_function (const void *hash_entry
)
18108 const struct toc_hash_struct
*thc
=
18109 (const struct toc_hash_struct
*) hash_entry
;
18110 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
18113 /* Compare H1 and H2 for equivalence. */
18116 toc_hash_eq (const void *h1
, const void *h2
)
18118 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
18119 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
18121 if (((const struct toc_hash_struct
*) h1
)->key_mode
18122 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
18125 return rtx_equal_p (r1
, r2
);
18128 /* These are the names given by the C++ front-end to vtables, and
18129 vtable-like objects. Ideally, this logic should not be here;
18130 instead, there should be some programmatic way of inquiring as
18131 to whether or not an object is a vtable. */
18133 #define VTABLE_NAME_P(NAME) \
18134 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
18135 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
18136 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
18137 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
18138 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
18140 #ifdef NO_DOLLAR_IN_LABEL
18141 /* Return a GGC-allocated character string translating dollar signs in
18142 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
18145 rs6000_xcoff_strip_dollar (const char *name
)
18150 p
= strchr (name
, '$');
18152 if (p
== 0 || p
== name
)
18155 len
= strlen (name
);
18156 strip
= (char *) alloca (len
+ 1);
18157 strcpy (strip
, name
);
18158 p
= strchr (strip
, '$');
18162 p
= strchr (p
+ 1, '$');
18165 return ggc_alloc_string (strip
, len
);
18170 rs6000_output_symbol_ref (FILE *file
, rtx x
)
18172 /* Currently C++ toc references to vtables can be emitted before it
18173 is decided whether the vtable is public or private. If this is
18174 the case, then the linker will eventually complain that there is
18175 a reference to an unknown section. Thus, for vtables only,
18176 we emit the TOC reference to reference the symbol and not the
18178 const char *name
= XSTR (x
, 0);
18180 if (VTABLE_NAME_P (name
))
18182 RS6000_OUTPUT_BASENAME (file
, name
);
18185 assemble_name (file
, name
);
18188 /* Output a TOC entry. We derive the entry name from what is being
18192 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
18195 const char *name
= buf
;
18197 HOST_WIDE_INT offset
= 0;
18199 gcc_assert (!TARGET_NO_TOC
);
18201 /* When the linker won't eliminate them, don't output duplicate
18202 TOC entries (this happens on AIX if there is any kind of TOC,
18203 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
18205 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
18207 struct toc_hash_struct
*h
;
18210 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
18211 time because GGC is not initialized at that point. */
18212 if (toc_hash_table
== NULL
)
18213 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
18214 toc_hash_eq
, NULL
);
18216 h
= GGC_NEW (struct toc_hash_struct
);
18218 h
->key_mode
= mode
;
18219 h
->labelno
= labelno
;
18221 found
= htab_find_slot (toc_hash_table
, h
, INSERT
);
18222 if (*found
== NULL
)
18224 else /* This is indeed a duplicate.
18225 Set this label equal to that label. */
18227 fputs ("\t.set ", file
);
18228 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
18229 fprintf (file
, "%d,", labelno
);
18230 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
18231 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
18237 /* If we're going to put a double constant in the TOC, make sure it's
18238 aligned properly when strict alignment is on. */
18239 if (GET_CODE (x
) == CONST_DOUBLE
18240 && STRICT_ALIGNMENT
18241 && GET_MODE_BITSIZE (mode
) >= 64
18242 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
18243 ASM_OUTPUT_ALIGN (file
, 3);
18246 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
18248 /* Handle FP constants specially. Note that if we have a minimal
18249 TOC, things we put here aren't actually in the TOC, so we can allow
18251 if (GET_CODE (x
) == CONST_DOUBLE
&&
18252 (GET_MODE (x
) == TFmode
|| GET_MODE (x
) == TDmode
))
18254 REAL_VALUE_TYPE rv
;
18257 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
18258 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
18259 REAL_VALUE_TO_TARGET_DECIMAL128 (rv
, k
);
18261 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
18265 if (TARGET_MINIMAL_TOC
)
18266 fputs (DOUBLE_INT_ASM_OP
, file
);
18268 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
18269 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
18270 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
18271 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
18272 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
18273 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
18278 if (TARGET_MINIMAL_TOC
)
18279 fputs ("\t.long ", file
);
18281 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
18282 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
18283 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
18284 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
18285 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
18286 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
18290 else if (GET_CODE (x
) == CONST_DOUBLE
&&
18291 (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DDmode
))
18293 REAL_VALUE_TYPE rv
;
18296 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
18298 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
18299 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, k
);
18301 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
18305 if (TARGET_MINIMAL_TOC
)
18306 fputs (DOUBLE_INT_ASM_OP
, file
);
18308 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
18309 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
18310 fprintf (file
, "0x%lx%08lx\n",
18311 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
18316 if (TARGET_MINIMAL_TOC
)
18317 fputs ("\t.long ", file
);
18319 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
18320 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
18321 fprintf (file
, "0x%lx,0x%lx\n",
18322 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
18326 else if (GET_CODE (x
) == CONST_DOUBLE
&&
18327 (GET_MODE (x
) == SFmode
|| GET_MODE (x
) == SDmode
))
18329 REAL_VALUE_TYPE rv
;
18332 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
18333 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
18334 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
18336 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
18340 if (TARGET_MINIMAL_TOC
)
18341 fputs (DOUBLE_INT_ASM_OP
, file
);
18343 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
18344 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
18349 if (TARGET_MINIMAL_TOC
)
18350 fputs ("\t.long ", file
);
18352 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
18353 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
18357 else if (GET_MODE (x
) == VOIDmode
18358 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
18360 unsigned HOST_WIDE_INT low
;
18361 HOST_WIDE_INT high
;
18363 if (GET_CODE (x
) == CONST_DOUBLE
)
18365 low
= CONST_DOUBLE_LOW (x
);
18366 high
= CONST_DOUBLE_HIGH (x
);
18369 #if HOST_BITS_PER_WIDE_INT == 32
18372 high
= (low
& 0x80000000) ? ~0 : 0;
18376 low
= INTVAL (x
) & 0xffffffff;
18377 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
18381 /* TOC entries are always Pmode-sized, but since this
18382 is a bigendian machine then if we're putting smaller
18383 integer constants in the TOC we have to pad them.
18384 (This is still a win over putting the constants in
18385 a separate constant pool, because then we'd have
18386 to have both a TOC entry _and_ the actual constant.)
18388 For a 32-bit target, CONST_INT values are loaded and shifted
18389 entirely within `low' and can be stored in one TOC entry. */
18391 /* It would be easy to make this work, but it doesn't now. */
18392 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
18394 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
18396 #if HOST_BITS_PER_WIDE_INT == 32
18397 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
18398 POINTER_SIZE
, &low
, &high
, 0);
18401 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
18402 high
= (HOST_WIDE_INT
) low
>> 32;
18409 if (TARGET_MINIMAL_TOC
)
18410 fputs (DOUBLE_INT_ASM_OP
, file
);
18412 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
18413 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
18414 fprintf (file
, "0x%lx%08lx\n",
18415 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
18420 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
18422 if (TARGET_MINIMAL_TOC
)
18423 fputs ("\t.long ", file
);
18425 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
18426 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
18427 fprintf (file
, "0x%lx,0x%lx\n",
18428 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
18432 if (TARGET_MINIMAL_TOC
)
18433 fputs ("\t.long ", file
);
18435 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
18436 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
18442 if (GET_CODE (x
) == CONST
)
18444 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
);
18446 base
= XEXP (XEXP (x
, 0), 0);
18447 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
18450 switch (GET_CODE (base
))
18453 name
= XSTR (base
, 0);
18457 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
18458 CODE_LABEL_NUMBER (XEXP (base
, 0)));
18462 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
18466 gcc_unreachable ();
18469 if (TARGET_MINIMAL_TOC
)
18470 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
18473 fputs ("\t.tc ", file
);
18474 RS6000_OUTPUT_BASENAME (file
, name
);
18477 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
18479 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
18481 fputs ("[TC],", file
);
18484 /* Currently C++ toc references to vtables can be emitted before it
18485 is decided whether the vtable is public or private. If this is
18486 the case, then the linker will eventually complain that there is
18487 a TOC reference to an unknown section. Thus, for vtables only,
18488 we emit the TOC reference to reference the symbol and not the
18490 if (VTABLE_NAME_P (name
))
18492 RS6000_OUTPUT_BASENAME (file
, name
);
18494 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
18495 else if (offset
> 0)
18496 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
18499 output_addr_const (file
, x
);
18503 /* Output an assembler pseudo-op to write an ASCII string of N characters
18504 starting at P to FILE.
18506 On the RS/6000, we have to do this using the .byte operation and
18507 write out special characters outside the quoted string.
18508 Also, the assembler is broken; very long strings are truncated,
18509 so we must artificially break them up early. */
18512 output_ascii (FILE *file
, const char *p
, int n
)
18515 int i
, count_string
;
18516 const char *for_string
= "\t.byte \"";
18517 const char *for_decimal
= "\t.byte ";
18518 const char *to_close
= NULL
;
18521 for (i
= 0; i
< n
; i
++)
18524 if (c
>= ' ' && c
< 0177)
18527 fputs (for_string
, file
);
18530 /* Write two quotes to get one. */
18538 for_decimal
= "\"\n\t.byte ";
18542 if (count_string
>= 512)
18544 fputs (to_close
, file
);
18546 for_string
= "\t.byte \"";
18547 for_decimal
= "\t.byte ";
18555 fputs (for_decimal
, file
);
18556 fprintf (file
, "%d", c
);
18558 for_string
= "\n\t.byte \"";
18559 for_decimal
= ", ";
18565 /* Now close the string if we have written one. Then end the line. */
18567 fputs (to_close
, file
);
18570 /* Generate a unique section name for FILENAME for a section type
18571 represented by SECTION_DESC. Output goes into BUF.
18573 SECTION_DESC can be any string, as long as it is different for each
18574 possible section type.
18576 We name the section in the same manner as xlc. The name begins with an
18577 underscore followed by the filename (after stripping any leading directory
18578 names) with the last period replaced by the string SECTION_DESC. If
18579 FILENAME does not contain a period, SECTION_DESC is appended to the end of
18583 rs6000_gen_section_name (char **buf
, const char *filename
,
18584 const char *section_desc
)
18586 const char *q
, *after_last_slash
, *last_period
= 0;
18590 after_last_slash
= filename
;
18591 for (q
= filename
; *q
; q
++)
18594 after_last_slash
= q
+ 1;
18595 else if (*q
== '.')
18599 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
18600 *buf
= (char *) xmalloc (len
);
18605 for (q
= after_last_slash
; *q
; q
++)
18607 if (q
== last_period
)
18609 strcpy (p
, section_desc
);
18610 p
+= strlen (section_desc
);
18614 else if (ISALNUM (*q
))
18618 if (last_period
== 0)
18619 strcpy (p
, section_desc
);
18624 /* Emit profile function. */
18627 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
18629 /* Non-standard profiling for kernels, which just saves LR then calls
18630 _mcount without worrying about arg saves. The idea is to change
18631 the function prologue as little as possible as it isn't easy to
18632 account for arg save/restore code added just for _mcount. */
18633 if (TARGET_PROFILE_KERNEL
)
18636 if (DEFAULT_ABI
== ABI_AIX
)
18638 #ifndef NO_PROFILE_COUNTERS
18639 # define NO_PROFILE_COUNTERS 0
18641 if (NO_PROFILE_COUNTERS
)
18642 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
18643 LCT_NORMAL
, VOIDmode
, 0);
18647 const char *label_name
;
18650 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
18651 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
18652 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
18654 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
18655 LCT_NORMAL
, VOIDmode
, 1, fun
, Pmode
);
18658 else if (DEFAULT_ABI
== ABI_DARWIN
)
18660 const char *mcount_name
= RS6000_MCOUNT
;
18661 int caller_addr_regno
= LR_REGNO
;
18663 /* Be conservative and always set this, at least for now. */
18664 crtl
->uses_pic_offset_table
= 1;
18667 /* For PIC code, set up a stub and collect the caller's address
18668 from r0, which is where the prologue puts it. */
18669 if (MACHOPIC_INDIRECT
18670 && crtl
->uses_pic_offset_table
)
18671 caller_addr_regno
= 0;
18673 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
18674 LCT_NORMAL
, VOIDmode
, 1,
18675 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
18679 /* Write function profiler code. */
18682 output_function_profiler (FILE *file
, int labelno
)
18686 switch (DEFAULT_ABI
)
18689 gcc_unreachable ();
18694 warning (0, "no profiling of 64-bit code for this ABI");
18697 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
18698 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
18699 if (NO_PROFILE_COUNTERS
)
18701 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
18702 reg_names
[0], reg_names
[1]);
18704 else if (TARGET_SECURE_PLT
&& flag_pic
)
18706 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
18707 reg_names
[0], reg_names
[1]);
18708 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
18709 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
18710 reg_names
[12], reg_names
[12]);
18711 assemble_name (file
, buf
);
18712 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
18713 assemble_name (file
, buf
);
18714 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
18716 else if (flag_pic
== 1)
18718 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
18719 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
18720 reg_names
[0], reg_names
[1]);
18721 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
18722 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
18723 assemble_name (file
, buf
);
18724 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
18726 else if (flag_pic
> 1)
18728 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
18729 reg_names
[0], reg_names
[1]);
18730 /* Now, we need to get the address of the label. */
18731 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
18732 assemble_name (file
, buf
);
18733 fputs ("-.\n1:", file
);
18734 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
18735 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
18736 reg_names
[0], reg_names
[11]);
18737 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
18738 reg_names
[0], reg_names
[0], reg_names
[11]);
18742 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
18743 assemble_name (file
, buf
);
18744 fputs ("@ha\n", file
);
18745 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
18746 reg_names
[0], reg_names
[1]);
18747 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
18748 assemble_name (file
, buf
);
18749 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
18752 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
18753 fprintf (file
, "\tbl %s%s\n",
18754 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
18759 if (!TARGET_PROFILE_KERNEL
)
18761 /* Don't do anything, done in output_profile_hook (). */
18765 gcc_assert (!TARGET_32BIT
);
18767 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
18768 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
18770 if (cfun
->static_chain_decl
!= NULL
)
18772 asm_fprintf (file
, "\tstd %s,24(%s)\n",
18773 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
18774 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
18775 asm_fprintf (file
, "\tld %s,24(%s)\n",
18776 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
18779 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
18787 /* The following variable value is the last issued insn. */
18789 static rtx last_scheduled_insn
;
18791 /* The following variable helps to balance issuing of load and
18792 store instructions */
18794 static int load_store_pendulum
;
18796 /* Power4 load update and store update instructions are cracked into a
18797 load or store and an integer insn which are executed in the same cycle.
18798 Branches have their own dispatch slot which does not count against the
18799 GCC issue rate, but it changes the program flow so there are no other
18800 instructions to issue in this cycle. */
18803 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED
,
18804 int verbose ATTRIBUTE_UNUSED
,
18805 rtx insn
, int more
)
18807 last_scheduled_insn
= insn
;
18808 if (GET_CODE (PATTERN (insn
)) == USE
18809 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18811 cached_can_issue_more
= more
;
18812 return cached_can_issue_more
;
18815 if (insn_terminates_group_p (insn
, current_group
))
18817 cached_can_issue_more
= 0;
18818 return cached_can_issue_more
;
18821 /* If no reservation, but reach here */
18822 if (recog_memoized (insn
) < 0)
18825 if (rs6000_sched_groups
)
18827 if (is_microcoded_insn (insn
))
18828 cached_can_issue_more
= 0;
18829 else if (is_cracked_insn (insn
))
18830 cached_can_issue_more
= more
> 2 ? more
- 2 : 0;
18832 cached_can_issue_more
= more
- 1;
18834 return cached_can_issue_more
;
18837 if (rs6000_cpu_attr
== CPU_CELL
&& is_nonpipeline_insn (insn
))
18840 cached_can_issue_more
= more
- 1;
18841 return cached_can_issue_more
;
18844 /* Adjust the cost of a scheduling dependency. Return the new cost of
18845 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
18848 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
18850 enum attr_type attr_type
;
18852 if (! recog_memoized (insn
))
18855 switch (REG_NOTE_KIND (link
))
18859 /* Data dependency; DEP_INSN writes a register that INSN reads
18860 some cycles later. */
18862 /* Separate a load from a narrower, dependent store. */
18863 if (rs6000_sched_groups
18864 && GET_CODE (PATTERN (insn
)) == SET
18865 && GET_CODE (PATTERN (dep_insn
)) == SET
18866 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
18867 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
18868 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
18869 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
18872 attr_type
= get_attr_type (insn
);
18877 /* Tell the first scheduling pass about the latency between
18878 a mtctr and bctr (and mtlr and br/blr). The first
18879 scheduling pass will not know about this latency since
18880 the mtctr instruction, which has the latency associated
18881 to it, will be generated by reload. */
18882 return TARGET_POWER
? 5 : 4;
18884 /* Leave some extra cycles between a compare and its
18885 dependent branch, to inhibit expensive mispredicts. */
18886 if ((rs6000_cpu_attr
== CPU_PPC603
18887 || rs6000_cpu_attr
== CPU_PPC604
18888 || rs6000_cpu_attr
== CPU_PPC604E
18889 || rs6000_cpu_attr
== CPU_PPC620
18890 || rs6000_cpu_attr
== CPU_PPC630
18891 || rs6000_cpu_attr
== CPU_PPC750
18892 || rs6000_cpu_attr
== CPU_PPC7400
18893 || rs6000_cpu_attr
== CPU_PPC7450
18894 || rs6000_cpu_attr
== CPU_POWER4
18895 || rs6000_cpu_attr
== CPU_POWER5
18896 || rs6000_cpu_attr
== CPU_CELL
)
18897 && recog_memoized (dep_insn
)
18898 && (INSN_CODE (dep_insn
) >= 0))
18900 switch (get_attr_type (dep_insn
))
18904 case TYPE_DELAYED_COMPARE
:
18905 case TYPE_IMUL_COMPARE
:
18906 case TYPE_LMUL_COMPARE
:
18907 case TYPE_FPCOMPARE
:
18908 case TYPE_CR_LOGICAL
:
18909 case TYPE_DELAYED_CR
:
18918 case TYPE_STORE_UX
:
18920 case TYPE_FPSTORE_U
:
18921 case TYPE_FPSTORE_UX
:
18922 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18923 && recog_memoized (dep_insn
)
18924 && (INSN_CODE (dep_insn
) >= 0))
18927 if (GET_CODE (PATTERN (insn
)) != SET
)
18928 /* If this happens, we have to extend this to schedule
18929 optimally. Return default for now. */
18932 /* Adjust the cost for the case where the value written
18933 by a fixed point operation is used as the address
18934 gen value on a store. */
18935 switch (get_attr_type (dep_insn
))
18942 if (! store_data_bypass_p (dep_insn
, insn
))
18946 case TYPE_LOAD_EXT
:
18947 case TYPE_LOAD_EXT_U
:
18948 case TYPE_LOAD_EXT_UX
:
18949 case TYPE_VAR_SHIFT_ROTATE
:
18950 case TYPE_VAR_DELAYED_COMPARE
:
18952 if (! store_data_bypass_p (dep_insn
, insn
))
18958 case TYPE_FAST_COMPARE
:
18961 case TYPE_INSERT_WORD
:
18962 case TYPE_INSERT_DWORD
:
18963 case TYPE_FPLOAD_U
:
18964 case TYPE_FPLOAD_UX
:
18966 case TYPE_STORE_UX
:
18967 case TYPE_FPSTORE_U
:
18968 case TYPE_FPSTORE_UX
:
18970 if (! store_data_bypass_p (dep_insn
, insn
))
18978 case TYPE_IMUL_COMPARE
:
18979 case TYPE_LMUL_COMPARE
:
18981 if (! store_data_bypass_p (dep_insn
, insn
))
18987 if (! store_data_bypass_p (dep_insn
, insn
))
18993 if (! store_data_bypass_p (dep_insn
, insn
))
19006 case TYPE_LOAD_EXT
:
19007 case TYPE_LOAD_EXT_U
:
19008 case TYPE_LOAD_EXT_UX
:
19009 if ((rs6000_cpu
== PROCESSOR_POWER6
)
19010 && recog_memoized (dep_insn
)
19011 && (INSN_CODE (dep_insn
) >= 0))
19014 /* Adjust the cost for the case where the value written
19015 by a fixed point instruction is used within the address
19016 gen portion of a subsequent load(u)(x) */
19017 switch (get_attr_type (dep_insn
))
19024 if (set_to_load_agen (dep_insn
, insn
))
19028 case TYPE_LOAD_EXT
:
19029 case TYPE_LOAD_EXT_U
:
19030 case TYPE_LOAD_EXT_UX
:
19031 case TYPE_VAR_SHIFT_ROTATE
:
19032 case TYPE_VAR_DELAYED_COMPARE
:
19034 if (set_to_load_agen (dep_insn
, insn
))
19040 case TYPE_FAST_COMPARE
:
19043 case TYPE_INSERT_WORD
:
19044 case TYPE_INSERT_DWORD
:
19045 case TYPE_FPLOAD_U
:
19046 case TYPE_FPLOAD_UX
:
19048 case TYPE_STORE_UX
:
19049 case TYPE_FPSTORE_U
:
19050 case TYPE_FPSTORE_UX
:
19052 if (set_to_load_agen (dep_insn
, insn
))
19060 case TYPE_IMUL_COMPARE
:
19061 case TYPE_LMUL_COMPARE
:
19063 if (set_to_load_agen (dep_insn
, insn
))
19069 if (set_to_load_agen (dep_insn
, insn
))
19075 if (set_to_load_agen (dep_insn
, insn
))
19086 if ((rs6000_cpu
== PROCESSOR_POWER6
)
19087 && recog_memoized (dep_insn
)
19088 && (INSN_CODE (dep_insn
) >= 0)
19089 && (get_attr_type (dep_insn
) == TYPE_MFFGPR
))
19096 /* Fall out to return default cost. */
19100 case REG_DEP_OUTPUT
:
19101 /* Output dependency; DEP_INSN writes a register that INSN writes some
19103 if ((rs6000_cpu
== PROCESSOR_POWER6
)
19104 && recog_memoized (dep_insn
)
19105 && (INSN_CODE (dep_insn
) >= 0))
19107 attr_type
= get_attr_type (insn
);
19112 if (get_attr_type (dep_insn
) == TYPE_FP
)
19116 if (get_attr_type (dep_insn
) == TYPE_MFFGPR
)
19124 /* Anti dependency; DEP_INSN reads a register that INSN writes some
19129 gcc_unreachable ();
19135 /* The function returns a true if INSN is microcoded.
19136 Return false otherwise. */
19139 is_microcoded_insn (rtx insn
)
19141 if (!insn
|| !INSN_P (insn
)
19142 || GET_CODE (PATTERN (insn
)) == USE
19143 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19146 if (rs6000_cpu_attr
== CPU_CELL
)
19147 return get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
;
19149 if (rs6000_sched_groups
)
19151 enum attr_type type
= get_attr_type (insn
);
19152 if (type
== TYPE_LOAD_EXT_U
19153 || type
== TYPE_LOAD_EXT_UX
19154 || type
== TYPE_LOAD_UX
19155 || type
== TYPE_STORE_UX
19156 || type
== TYPE_MFCR
)
19163 /* The function returns true if INSN is cracked into 2 instructions
19164 by the processor (and therefore occupies 2 issue slots). */
19167 is_cracked_insn (rtx insn
)
19169 if (!insn
|| !INSN_P (insn
)
19170 || GET_CODE (PATTERN (insn
)) == USE
19171 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19174 if (rs6000_sched_groups
)
19176 enum attr_type type
= get_attr_type (insn
);
19177 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
19178 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
19179 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
19180 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
19181 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
19182 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
19183 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
19184 || type
== TYPE_INSERT_WORD
)
19191 /* The function returns true if INSN can be issued only from
19192 the branch slot. */
19195 is_branch_slot_insn (rtx insn
)
19197 if (!insn
|| !INSN_P (insn
)
19198 || GET_CODE (PATTERN (insn
)) == USE
19199 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19202 if (rs6000_sched_groups
)
19204 enum attr_type type
= get_attr_type (insn
);
19205 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
19213 /* The function returns true if out_inst sets a value that is
19214 used in the address generation computation of in_insn */
19216 set_to_load_agen (rtx out_insn
, rtx in_insn
)
19218 rtx out_set
, in_set
;
19220 /* For performance reasons, only handle the simple case where
19221 both loads are a single_set. */
19222 out_set
= single_set (out_insn
);
19225 in_set
= single_set (in_insn
);
19227 return reg_mentioned_p (SET_DEST (out_set
), SET_SRC (in_set
));
19233 /* The function returns true if the target storage location of
19234 out_insn is adjacent to the target storage location of in_insn */
19235 /* Return 1 if memory locations are adjacent. */
19238 adjacent_mem_locations (rtx insn1
, rtx insn2
)
19241 rtx a
= get_store_dest (PATTERN (insn1
));
19242 rtx b
= get_store_dest (PATTERN (insn2
));
19244 if ((GET_CODE (XEXP (a
, 0)) == REG
19245 || (GET_CODE (XEXP (a
, 0)) == PLUS
19246 && GET_CODE (XEXP (XEXP (a
, 0), 1)) == CONST_INT
))
19247 && (GET_CODE (XEXP (b
, 0)) == REG
19248 || (GET_CODE (XEXP (b
, 0)) == PLUS
19249 && GET_CODE (XEXP (XEXP (b
, 0), 1)) == CONST_INT
)))
19251 HOST_WIDE_INT val0
= 0, val1
= 0, val_diff
;
19254 if (GET_CODE (XEXP (a
, 0)) == PLUS
)
19256 reg0
= XEXP (XEXP (a
, 0), 0);
19257 val0
= INTVAL (XEXP (XEXP (a
, 0), 1));
19260 reg0
= XEXP (a
, 0);
19262 if (GET_CODE (XEXP (b
, 0)) == PLUS
)
19264 reg1
= XEXP (XEXP (b
, 0), 0);
19265 val1
= INTVAL (XEXP (XEXP (b
, 0), 1));
19268 reg1
= XEXP (b
, 0);
19270 val_diff
= val1
- val0
;
19272 return ((REGNO (reg0
) == REGNO (reg1
))
19273 && ((MEM_SIZE (a
) && val_diff
== INTVAL (MEM_SIZE (a
)))
19274 || (MEM_SIZE (b
) && val_diff
== -INTVAL (MEM_SIZE (b
)))));
19280 /* A C statement (sans semicolon) to update the integer scheduling
19281 priority INSN_PRIORITY (INSN). Increase the priority to execute the
19282 INSN earlier, reduce the priority to execute INSN later. Do not
19283 define this macro if you do not need to adjust the scheduling
19284 priorities of insns. */
19287 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
19289 /* On machines (like the 750) which have asymmetric integer units,
19290 where one integer unit can do multiply and divides and the other
19291 can't, reduce the priority of multiply/divide so it is scheduled
19292 before other integer operations. */
19295 if (! INSN_P (insn
))
19298 if (GET_CODE (PATTERN (insn
)) == USE
)
19301 switch (rs6000_cpu_attr
) {
19303 switch (get_attr_type (insn
))
19310 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
19311 priority
, priority
);
19312 if (priority
>= 0 && priority
< 0x01000000)
19319 if (insn_must_be_first_in_group (insn
)
19320 && reload_completed
19321 && current_sched_info
->sched_max_insns_priority
19322 && rs6000_sched_restricted_insns_priority
)
19325 /* Prioritize insns that can be dispatched only in the first
19327 if (rs6000_sched_restricted_insns_priority
== 1)
19328 /* Attach highest priority to insn. This means that in
19329 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
19330 precede 'priority' (critical path) considerations. */
19331 return current_sched_info
->sched_max_insns_priority
;
19332 else if (rs6000_sched_restricted_insns_priority
== 2)
19333 /* Increase priority of insn by a minimal amount. This means that in
19334 haifa-sched.c:ready_sort(), only 'priority' (critical path)
19335 considerations precede dispatch-slot restriction considerations. */
19336 return (priority
+ 1);
19339 if (rs6000_cpu
== PROCESSOR_POWER6
19340 && ((load_store_pendulum
== -2 && is_load_insn (insn
))
19341 || (load_store_pendulum
== 2 && is_store_insn (insn
))))
19342 /* Attach highest priority to insn if the scheduler has just issued two
19343 stores and this instruction is a load, or two loads and this instruction
19344 is a store. Power6 wants loads and stores scheduled alternately
19346 return current_sched_info
->sched_max_insns_priority
;
19351 /* Return true if the instruction is nonpipelined on the Cell. */
19353 is_nonpipeline_insn (rtx insn
)
19355 enum attr_type type
;
19356 if (!insn
|| !INSN_P (insn
)
19357 || GET_CODE (PATTERN (insn
)) == USE
19358 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19361 type
= get_attr_type (insn
);
19362 if (type
== TYPE_IMUL
19363 || type
== TYPE_IMUL2
19364 || type
== TYPE_IMUL3
19365 || type
== TYPE_LMUL
19366 || type
== TYPE_IDIV
19367 || type
== TYPE_LDIV
19368 || type
== TYPE_SDIV
19369 || type
== TYPE_DDIV
19370 || type
== TYPE_SSQRT
19371 || type
== TYPE_DSQRT
19372 || type
== TYPE_MFCR
19373 || type
== TYPE_MFCRF
19374 || type
== TYPE_MFJMPR
)
19382 /* Return how many instructions the machine can issue per cycle. */
19385 rs6000_issue_rate (void)
19387 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
19388 if (!reload_completed
)
19391 switch (rs6000_cpu_attr
) {
19392 case CPU_RIOS1
: /* ? */
19394 case CPU_PPC601
: /* ? */
19403 case CPU_PPCE300C2
:
19404 case CPU_PPCE300C3
:
19405 case CPU_PPCE500MC
:
19422 /* Return how many instructions to look ahead for better insn
19426 rs6000_use_sched_lookahead (void)
19428 if (rs6000_cpu_attr
== CPU_PPC8540
)
19430 if (rs6000_cpu_attr
== CPU_CELL
)
19431 return (reload_completed
? 8 : 0);
19435 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
19437 rs6000_use_sched_lookahead_guard (rtx insn
)
19439 if (rs6000_cpu_attr
!= CPU_CELL
)
19442 if (insn
== NULL_RTX
|| !INSN_P (insn
))
19445 if (!reload_completed
19446 || is_nonpipeline_insn (insn
)
19447 || is_microcoded_insn (insn
))
19453 /* Determine is PAT refers to memory. */
19456 is_mem_ref (rtx pat
)
19462 /* stack_tie does not produce any real memory traffic. */
19463 if (GET_CODE (pat
) == UNSPEC
19464 && XINT (pat
, 1) == UNSPEC_TIE
)
19467 if (GET_CODE (pat
) == MEM
)
19470 /* Recursively process the pattern. */
19471 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
19473 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
19476 ret
|= is_mem_ref (XEXP (pat
, i
));
19477 else if (fmt
[i
] == 'E')
19478 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
19479 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
19485 /* Determine if PAT is a PATTERN of a load insn. */
19488 is_load_insn1 (rtx pat
)
19490 if (!pat
|| pat
== NULL_RTX
)
19493 if (GET_CODE (pat
) == SET
)
19494 return is_mem_ref (SET_SRC (pat
));
19496 if (GET_CODE (pat
) == PARALLEL
)
19500 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
19501 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
19508 /* Determine if INSN loads from memory. */
19511 is_load_insn (rtx insn
)
19513 if (!insn
|| !INSN_P (insn
))
19516 if (GET_CODE (insn
) == CALL_INSN
)
19519 return is_load_insn1 (PATTERN (insn
));
19522 /* Determine if PAT is a PATTERN of a store insn. */
19525 is_store_insn1 (rtx pat
)
19527 if (!pat
|| pat
== NULL_RTX
)
19530 if (GET_CODE (pat
) == SET
)
19531 return is_mem_ref (SET_DEST (pat
));
19533 if (GET_CODE (pat
) == PARALLEL
)
19537 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
19538 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
19545 /* Determine if INSN stores to memory. */
19548 is_store_insn (rtx insn
)
19550 if (!insn
|| !INSN_P (insn
))
19553 return is_store_insn1 (PATTERN (insn
));
19556 /* Return the dest of a store insn. */
19559 get_store_dest (rtx pat
)
19561 gcc_assert (is_store_insn1 (pat
));
19563 if (GET_CODE (pat
) == SET
)
19564 return SET_DEST (pat
);
19565 else if (GET_CODE (pat
) == PARALLEL
)
19569 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
19571 rtx inner_pat
= XVECEXP (pat
, 0, i
);
19572 if (GET_CODE (inner_pat
) == SET
19573 && is_mem_ref (SET_DEST (inner_pat
)))
19577 /* We shouldn't get here, because we should have either a simple
19578 store insn or a store with update which are covered above. */
19582 /* Returns whether the dependence between INSN and NEXT is considered
19583 costly by the given target. */
19586 rs6000_is_costly_dependence (dep_t dep
, int cost
, int distance
)
19591 /* If the flag is not enabled - no dependence is considered costly;
19592 allow all dependent insns in the same group.
19593 This is the most aggressive option. */
19594 if (rs6000_sched_costly_dep
== no_dep_costly
)
19597 /* If the flag is set to 1 - a dependence is always considered costly;
19598 do not allow dependent instructions in the same group.
19599 This is the most conservative option. */
19600 if (rs6000_sched_costly_dep
== all_deps_costly
)
19603 insn
= DEP_PRO (dep
);
19604 next
= DEP_CON (dep
);
19606 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
19607 && is_load_insn (next
)
19608 && is_store_insn (insn
))
19609 /* Prevent load after store in the same group. */
19612 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
19613 && is_load_insn (next
)
19614 && is_store_insn (insn
)
19615 && DEP_TYPE (dep
) == REG_DEP_TRUE
)
19616 /* Prevent load after store in the same group if it is a true
19620 /* The flag is set to X; dependences with latency >= X are considered costly,
19621 and will not be scheduled in the same group. */
19622 if (rs6000_sched_costly_dep
<= max_dep_latency
19623 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
19629 /* Return the next insn after INSN that is found before TAIL is reached,
19630 skipping any "non-active" insns - insns that will not actually occupy
19631 an issue slot. Return NULL_RTX if such an insn is not found. */
19634 get_next_active_insn (rtx insn
, rtx tail
)
19636 if (insn
== NULL_RTX
|| insn
== tail
)
19641 insn
= NEXT_INSN (insn
);
19642 if (insn
== NULL_RTX
|| insn
== tail
)
19647 || (NONJUMP_INSN_P (insn
)
19648 && GET_CODE (PATTERN (insn
)) != USE
19649 && GET_CODE (PATTERN (insn
)) != CLOBBER
19650 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
19656 /* We are about to begin issuing insns for this clock cycle. */
19659 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED
, int sched_verbose
,
19660 rtx
*ready ATTRIBUTE_UNUSED
,
19661 int *pn_ready ATTRIBUTE_UNUSED
,
19662 int clock_var ATTRIBUTE_UNUSED
)
19664 int n_ready
= *pn_ready
;
19667 fprintf (dump
, "// rs6000_sched_reorder :\n");
19669 /* Reorder the ready list, if the second to last ready insn
19670 is a nonepipeline insn. */
19671 if (rs6000_cpu_attr
== CPU_CELL
&& n_ready
> 1)
19673 if (is_nonpipeline_insn (ready
[n_ready
- 1])
19674 && (recog_memoized (ready
[n_ready
- 2]) > 0))
19675 /* Simply swap first two insns. */
19677 rtx tmp
= ready
[n_ready
- 1];
19678 ready
[n_ready
- 1] = ready
[n_ready
- 2];
19679 ready
[n_ready
- 2] = tmp
;
19683 if (rs6000_cpu
== PROCESSOR_POWER6
)
19684 load_store_pendulum
= 0;
19686 return rs6000_issue_rate ();
19689 /* Like rs6000_sched_reorder, but called after issuing each insn. */
19692 rs6000_sched_reorder2 (FILE *dump
, int sched_verbose
, rtx
*ready
,
19693 int *pn_ready
, int clock_var ATTRIBUTE_UNUSED
)
19696 fprintf (dump
, "// rs6000_sched_reorder2 :\n");
19698 /* For Power6, we need to handle some special cases to try and keep the
19699 store queue from overflowing and triggering expensive flushes.
19701 This code monitors how load and store instructions are being issued
19702 and skews the ready list one way or the other to increase the likelihood
19703 that a desired instruction is issued at the proper time.
19705 A couple of things are done. First, we maintain a "load_store_pendulum"
19706 to track the current state of load/store issue.
19708 - If the pendulum is at zero, then no loads or stores have been
19709 issued in the current cycle so we do nothing.
19711 - If the pendulum is 1, then a single load has been issued in this
19712 cycle and we attempt to locate another load in the ready list to
19715 - If the pendulum is -2, then two stores have already been
19716 issued in this cycle, so we increase the priority of the first load
19717 in the ready list to increase it's likelihood of being chosen first
19720 - If the pendulum is -1, then a single store has been issued in this
19721 cycle and we attempt to locate another store in the ready list to
19722 issue with it, preferring a store to an adjacent memory location to
19723 facilitate store pairing in the store queue.
19725 - If the pendulum is 2, then two loads have already been
19726 issued in this cycle, so we increase the priority of the first store
19727 in the ready list to increase it's likelihood of being chosen first
19730 - If the pendulum < -2 or > 2, then do nothing.
19732 Note: This code covers the most common scenarios. There exist non
19733 load/store instructions which make use of the LSU and which
19734 would need to be accounted for to strictly model the behavior
19735 of the machine. Those instructions are currently unaccounted
19736 for to help minimize compile time overhead of this code.
19738 if (rs6000_cpu
== PROCESSOR_POWER6
&& last_scheduled_insn
)
19744 if (is_store_insn (last_scheduled_insn
))
19745 /* Issuing a store, swing the load_store_pendulum to the left */
19746 load_store_pendulum
--;
19747 else if (is_load_insn (last_scheduled_insn
))
19748 /* Issuing a load, swing the load_store_pendulum to the right */
19749 load_store_pendulum
++;
19751 return cached_can_issue_more
;
19753 /* If the pendulum is balanced, or there is only one instruction on
19754 the ready list, then all is well, so return. */
19755 if ((load_store_pendulum
== 0) || (*pn_ready
<= 1))
19756 return cached_can_issue_more
;
19758 if (load_store_pendulum
== 1)
19760 /* A load has been issued in this cycle. Scan the ready list
19761 for another load to issue with it */
19766 if (is_load_insn (ready
[pos
]))
19768 /* Found a load. Move it to the head of the ready list,
19769 and adjust it's priority so that it is more likely to
19772 for (i
=pos
; i
<*pn_ready
-1; i
++)
19773 ready
[i
] = ready
[i
+ 1];
19774 ready
[*pn_ready
-1] = tmp
;
19776 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
19777 INSN_PRIORITY (tmp
)++;
19783 else if (load_store_pendulum
== -2)
19785 /* Two stores have been issued in this cycle. Increase the
19786 priority of the first load in the ready list to favor it for
19787 issuing in the next cycle. */
19792 if (is_load_insn (ready
[pos
])
19794 && INSN_PRIORITY_KNOWN (ready
[pos
]))
19796 INSN_PRIORITY (ready
[pos
])++;
19798 /* Adjust the pendulum to account for the fact that a load
19799 was found and increased in priority. This is to prevent
19800 increasing the priority of multiple loads */
19801 load_store_pendulum
--;
19808 else if (load_store_pendulum
== -1)
19810 /* A store has been issued in this cycle. Scan the ready list for
19811 another store to issue with it, preferring a store to an adjacent
19813 int first_store_pos
= -1;
19819 if (is_store_insn (ready
[pos
]))
19821 /* Maintain the index of the first store found on the
19823 if (first_store_pos
== -1)
19824 first_store_pos
= pos
;
19826 if (is_store_insn (last_scheduled_insn
)
19827 && adjacent_mem_locations (last_scheduled_insn
,ready
[pos
]))
19829 /* Found an adjacent store. Move it to the head of the
19830 ready list, and adjust it's priority so that it is
19831 more likely to stay there */
19833 for (i
=pos
; i
<*pn_ready
-1; i
++)
19834 ready
[i
] = ready
[i
+ 1];
19835 ready
[*pn_ready
-1] = tmp
;
19837 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
19838 INSN_PRIORITY (tmp
)++;
19840 first_store_pos
= -1;
19848 if (first_store_pos
>= 0)
19850 /* An adjacent store wasn't found, but a non-adjacent store was,
19851 so move the non-adjacent store to the front of the ready
19852 list, and adjust its priority so that it is more likely to
19854 tmp
= ready
[first_store_pos
];
19855 for (i
=first_store_pos
; i
<*pn_ready
-1; i
++)
19856 ready
[i
] = ready
[i
+ 1];
19857 ready
[*pn_ready
-1] = tmp
;
19858 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
19859 INSN_PRIORITY (tmp
)++;
19862 else if (load_store_pendulum
== 2)
19864 /* Two loads have been issued in this cycle. Increase the priority
19865 of the first store in the ready list to favor it for issuing in
19871 if (is_store_insn (ready
[pos
])
19873 && INSN_PRIORITY_KNOWN (ready
[pos
]))
19875 INSN_PRIORITY (ready
[pos
])++;
19877 /* Adjust the pendulum to account for the fact that a store
19878 was found and increased in priority. This is to prevent
19879 increasing the priority of multiple stores */
19880 load_store_pendulum
++;
19889 return cached_can_issue_more
;
19892 /* Return whether the presence of INSN causes a dispatch group termination
19893 of group WHICH_GROUP.
19895 If WHICH_GROUP == current_group, this function will return true if INSN
19896 causes the termination of the current group (i.e, the dispatch group to
19897 which INSN belongs). This means that INSN will be the last insn in the
19898 group it belongs to.
19900 If WHICH_GROUP == previous_group, this function will return true if INSN
19901 causes the termination of the previous group (i.e, the dispatch group that
19902 precedes the group to which INSN belongs). This means that INSN will be
19903 the first insn in the group it belongs to). */
19906 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
19913 first
= insn_must_be_first_in_group (insn
);
19914 last
= insn_must_be_last_in_group (insn
);
19919 if (which_group
== current_group
)
19921 else if (which_group
== previous_group
)
19929 insn_must_be_first_in_group (rtx insn
)
19931 enum attr_type type
;
19934 || insn
== NULL_RTX
19935 || GET_CODE (insn
) == NOTE
19936 || GET_CODE (PATTERN (insn
)) == USE
19937 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19940 switch (rs6000_cpu
)
19942 case PROCESSOR_POWER5
:
19943 if (is_cracked_insn (insn
))
19945 case PROCESSOR_POWER4
:
19946 if (is_microcoded_insn (insn
))
19949 if (!rs6000_sched_groups
)
19952 type
= get_attr_type (insn
);
19959 case TYPE_DELAYED_CR
:
19960 case TYPE_CR_LOGICAL
:
19974 case PROCESSOR_POWER6
:
19975 type
= get_attr_type (insn
);
19979 case TYPE_INSERT_DWORD
:
19983 case TYPE_VAR_SHIFT_ROTATE
:
19990 case TYPE_INSERT_WORD
:
19991 case TYPE_DELAYED_COMPARE
:
19992 case TYPE_IMUL_COMPARE
:
19993 case TYPE_LMUL_COMPARE
:
19994 case TYPE_FPCOMPARE
:
20005 case TYPE_LOAD_EXT_UX
:
20007 case TYPE_STORE_UX
:
20008 case TYPE_FPLOAD_U
:
20009 case TYPE_FPLOAD_UX
:
20010 case TYPE_FPSTORE_U
:
20011 case TYPE_FPSTORE_UX
:
20025 insn_must_be_last_in_group (rtx insn
)
20027 enum attr_type type
;
20030 || insn
== NULL_RTX
20031 || GET_CODE (insn
) == NOTE
20032 || GET_CODE (PATTERN (insn
)) == USE
20033 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
20036 switch (rs6000_cpu
) {
20037 case PROCESSOR_POWER4
:
20038 case PROCESSOR_POWER5
:
20039 if (is_microcoded_insn (insn
))
20042 if (is_branch_slot_insn (insn
))
20046 case PROCESSOR_POWER6
:
20047 type
= get_attr_type (insn
);
20054 case TYPE_VAR_SHIFT_ROTATE
:
20061 case TYPE_DELAYED_COMPARE
:
20062 case TYPE_IMUL_COMPARE
:
20063 case TYPE_LMUL_COMPARE
:
20064 case TYPE_FPCOMPARE
:
20085 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
20086 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
20089 is_costly_group (rtx
*group_insns
, rtx next_insn
)
20092 int issue_rate
= rs6000_issue_rate ();
20094 for (i
= 0; i
< issue_rate
; i
++)
20096 sd_iterator_def sd_it
;
20098 rtx insn
= group_insns
[i
];
20103 FOR_EACH_DEP (insn
, SD_LIST_FORW
, sd_it
, dep
)
20105 rtx next
= DEP_CON (dep
);
20107 if (next
== next_insn
20108 && rs6000_is_costly_dependence (dep
, dep_cost (dep
), 0))
20116 /* Utility of the function redefine_groups.
20117 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
20118 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
20119 to keep it "far" (in a separate group) from GROUP_INSNS, following
20120 one of the following schemes, depending on the value of the flag
20121 -minsert_sched_nops = X:
20122 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
20123 in order to force NEXT_INSN into a separate group.
20124 (2) X < sched_finish_regroup_exact: insert exactly X nops.
20125 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
20126 insertion (has a group just ended, how many vacant issue slots remain in the
20127 last group, and how many dispatch groups were encountered so far). */
20130 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
20131 rtx next_insn
, bool *group_end
, int can_issue_more
,
20136 int issue_rate
= rs6000_issue_rate ();
20137 bool end
= *group_end
;
20140 if (next_insn
== NULL_RTX
)
20141 return can_issue_more
;
20143 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
20144 return can_issue_more
;
20146 force
= is_costly_group (group_insns
, next_insn
);
20148 return can_issue_more
;
20150 if (sched_verbose
> 6)
20151 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
20152 *group_count
,can_issue_more
);
20154 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
20157 can_issue_more
= 0;
20159 /* Since only a branch can be issued in the last issue_slot, it is
20160 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
20161 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
20162 in this case the last nop will start a new group and the branch
20163 will be forced to the new group. */
20164 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
20167 while (can_issue_more
> 0)
20170 emit_insn_before (nop
, next_insn
);
20178 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
20180 int n_nops
= rs6000_sched_insert_nops
;
20182 /* Nops can't be issued from the branch slot, so the effective
20183 issue_rate for nops is 'issue_rate - 1'. */
20184 if (can_issue_more
== 0)
20185 can_issue_more
= issue_rate
;
20187 if (can_issue_more
== 0)
20189 can_issue_more
= issue_rate
- 1;
20192 for (i
= 0; i
< issue_rate
; i
++)
20194 group_insns
[i
] = 0;
20201 emit_insn_before (nop
, next_insn
);
20202 if (can_issue_more
== issue_rate
- 1) /* new group begins */
20205 if (can_issue_more
== 0)
20207 can_issue_more
= issue_rate
- 1;
20210 for (i
= 0; i
< issue_rate
; i
++)
20212 group_insns
[i
] = 0;
20218 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
20221 /* Is next_insn going to start a new group? */
20224 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
20225 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
20226 || (can_issue_more
< issue_rate
&&
20227 insn_terminates_group_p (next_insn
, previous_group
)));
20228 if (*group_end
&& end
)
20231 if (sched_verbose
> 6)
20232 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
20233 *group_count
, can_issue_more
);
20234 return can_issue_more
;
20237 return can_issue_more
;
20240 /* This function tries to synch the dispatch groups that the compiler "sees"
20241 with the dispatch groups that the processor dispatcher is expected to
20242 form in practice. It tries to achieve this synchronization by forcing the
20243 estimated processor grouping on the compiler (as opposed to the function
20244 'pad_goups' which tries to force the scheduler's grouping on the processor).
20246 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
20247 examines the (estimated) dispatch groups that will be formed by the processor
20248 dispatcher. It marks these group boundaries to reflect the estimated
20249 processor grouping, overriding the grouping that the scheduler had marked.
20250 Depending on the value of the flag '-minsert-sched-nops' this function can
20251 force certain insns into separate groups or force a certain distance between
20252 them by inserting nops, for example, if there exists a "costly dependence"
20255 The function estimates the group boundaries that the processor will form as
20256 follows: It keeps track of how many vacant issue slots are available after
20257 each insn. A subsequent insn will start a new group if one of the following
20259 - no more vacant issue slots remain in the current dispatch group.
20260 - only the last issue slot, which is the branch slot, is vacant, but the next
20261 insn is not a branch.
20262 - only the last 2 or less issue slots, including the branch slot, are vacant,
20263 which means that a cracked insn (which occupies two issue slots) can't be
20264 issued in this group.
20265 - less than 'issue_rate' slots are vacant, and the next insn always needs to
20266 start a new group. */
20269 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
20271 rtx insn
, next_insn
;
20273 int can_issue_more
;
20276 int group_count
= 0;
20280 issue_rate
= rs6000_issue_rate ();
20281 group_insns
= XALLOCAVEC (rtx
, issue_rate
);
20282 for (i
= 0; i
< issue_rate
; i
++)
20284 group_insns
[i
] = 0;
20286 can_issue_more
= issue_rate
;
20288 insn
= get_next_active_insn (prev_head_insn
, tail
);
20291 while (insn
!= NULL_RTX
)
20293 slot
= (issue_rate
- can_issue_more
);
20294 group_insns
[slot
] = insn
;
20296 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
20297 if (insn_terminates_group_p (insn
, current_group
))
20298 can_issue_more
= 0;
20300 next_insn
= get_next_active_insn (insn
, tail
);
20301 if (next_insn
== NULL_RTX
)
20302 return group_count
+ 1;
20304 /* Is next_insn going to start a new group? */
20306 = (can_issue_more
== 0
20307 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
20308 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
20309 || (can_issue_more
< issue_rate
&&
20310 insn_terminates_group_p (next_insn
, previous_group
)));
20312 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
20313 next_insn
, &group_end
, can_issue_more
,
20319 can_issue_more
= 0;
20320 for (i
= 0; i
< issue_rate
; i
++)
20322 group_insns
[i
] = 0;
20326 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
20327 PUT_MODE (next_insn
, VOIDmode
);
20328 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
20329 PUT_MODE (next_insn
, TImode
);
20332 if (can_issue_more
== 0)
20333 can_issue_more
= issue_rate
;
20336 return group_count
;
20339 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
20340 dispatch group boundaries that the scheduler had marked. Pad with nops
20341 any dispatch groups which have vacant issue slots, in order to force the
20342 scheduler's grouping on the processor dispatcher. The function
20343 returns the number of dispatch groups found. */
20346 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
20348 rtx insn
, next_insn
;
20351 int can_issue_more
;
20353 int group_count
= 0;
20355 /* Initialize issue_rate. */
20356 issue_rate
= rs6000_issue_rate ();
20357 can_issue_more
= issue_rate
;
20359 insn
= get_next_active_insn (prev_head_insn
, tail
);
20360 next_insn
= get_next_active_insn (insn
, tail
);
20362 while (insn
!= NULL_RTX
)
20365 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
20367 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
20369 if (next_insn
== NULL_RTX
)
20374 /* If the scheduler had marked group termination at this location
20375 (between insn and next_insn), and neither insn nor next_insn will
20376 force group termination, pad the group with nops to force group
20379 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
20380 && !insn_terminates_group_p (insn
, current_group
)
20381 && !insn_terminates_group_p (next_insn
, previous_group
))
20383 if (!is_branch_slot_insn (next_insn
))
20386 while (can_issue_more
)
20389 emit_insn_before (nop
, next_insn
);
20394 can_issue_more
= issue_rate
;
20399 next_insn
= get_next_active_insn (insn
, tail
);
20402 return group_count
;
20405 /* We're beginning a new block. Initialize data structures as necessary. */
20408 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED
,
20409 int sched_verbose ATTRIBUTE_UNUSED
,
20410 int max_ready ATTRIBUTE_UNUSED
)
20412 last_scheduled_insn
= NULL_RTX
;
20413 load_store_pendulum
= 0;
20416 /* The following function is called at the end of scheduling BB.
20417 After reload, it inserts nops at insn group bundling. */
20420 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
20425 fprintf (dump
, "=== Finishing schedule.\n");
20427 if (reload_completed
&& rs6000_sched_groups
)
20429 /* Do not run sched_finish hook when selective scheduling enabled. */
20430 if (sel_sched_p ())
20433 if (rs6000_sched_insert_nops
== sched_finish_none
)
20436 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
20437 n_groups
= pad_groups (dump
, sched_verbose
,
20438 current_sched_info
->prev_head
,
20439 current_sched_info
->next_tail
);
20441 n_groups
= redefine_groups (dump
, sched_verbose
,
20442 current_sched_info
->prev_head
,
20443 current_sched_info
->next_tail
);
20445 if (sched_verbose
>= 6)
20447 fprintf (dump
, "ngroups = %d\n", n_groups
);
20448 print_rtl (dump
, current_sched_info
->prev_head
);
20449 fprintf (dump
, "Done finish_sched\n");
20454 struct _rs6000_sched_context
20456 short cached_can_issue_more
;
20457 rtx last_scheduled_insn
;
20458 int load_store_pendulum
;
20461 typedef struct _rs6000_sched_context rs6000_sched_context_def
;
20462 typedef rs6000_sched_context_def
*rs6000_sched_context_t
;
20464 /* Allocate store for new scheduling context. */
20466 rs6000_alloc_sched_context (void)
20468 return xmalloc (sizeof (rs6000_sched_context_def
));
20471 /* If CLEAN_P is true then initializes _SC with clean data,
20472 and from the global context otherwise. */
20474 rs6000_init_sched_context (void *_sc
, bool clean_p
)
20476 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
20480 sc
->cached_can_issue_more
= 0;
20481 sc
->last_scheduled_insn
= NULL_RTX
;
20482 sc
->load_store_pendulum
= 0;
20486 sc
->cached_can_issue_more
= cached_can_issue_more
;
20487 sc
->last_scheduled_insn
= last_scheduled_insn
;
20488 sc
->load_store_pendulum
= load_store_pendulum
;
20492 /* Sets the global scheduling context to the one pointed to by _SC. */
20494 rs6000_set_sched_context (void *_sc
)
20496 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
20498 gcc_assert (sc
!= NULL
);
20500 cached_can_issue_more
= sc
->cached_can_issue_more
;
20501 last_scheduled_insn
= sc
->last_scheduled_insn
;
20502 load_store_pendulum
= sc
->load_store_pendulum
;
20507 rs6000_free_sched_context (void *_sc
)
20509 gcc_assert (_sc
!= NULL
);
20515 /* Length in units of the trampoline for entering a nested function. */
20518 rs6000_trampoline_size (void)
20522 switch (DEFAULT_ABI
)
20525 gcc_unreachable ();
20528 ret
= (TARGET_32BIT
) ? 12 : 24;
20533 ret
= (TARGET_32BIT
) ? 40 : 48;
20540 /* Emit RTL insns to initialize the variable parts of a trampoline.
20541 FNADDR is an RTX for the address of the function's pure code.
20542 CXT is an RTX for the static chain value for the function. */
20545 rs6000_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
20547 int regsize
= (TARGET_32BIT
) ? 4 : 8;
20548 rtx ctx_reg
= force_reg (Pmode
, cxt
);
20550 switch (DEFAULT_ABI
)
20553 gcc_unreachable ();
20555 /* Macros to shorten the code expansions below. */
20556 #define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
20557 #define MEM_PLUS(addr,offset) \
20558 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
20560 /* Under AIX, just build the 3 word function descriptor */
20563 rtx fn_reg
= gen_reg_rtx (Pmode
);
20564 rtx toc_reg
= gen_reg_rtx (Pmode
);
20565 emit_move_insn (fn_reg
, MEM_DEREF (fnaddr
));
20566 emit_move_insn (toc_reg
, MEM_PLUS (fnaddr
, regsize
));
20567 emit_move_insn (MEM_DEREF (addr
), fn_reg
);
20568 emit_move_insn (MEM_PLUS (addr
, regsize
), toc_reg
);
20569 emit_move_insn (MEM_PLUS (addr
, 2*regsize
), ctx_reg
);
20573 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
20576 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__trampoline_setup"),
20577 LCT_NORMAL
, VOIDmode
, 4,
20579 GEN_INT (rs6000_trampoline_size ()), SImode
,
20589 /* Handle the "altivec" attribute. The attribute may have
20590 arguments as follows:
20592 __attribute__((altivec(vector__)))
20593 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
20594 __attribute__((altivec(bool__))) (always followed by 'unsigned')
20596 and may appear more than once (e.g., 'vector bool char') in a
20597 given declaration. */
20600 rs6000_handle_altivec_attribute (tree
*node
,
20601 tree name ATTRIBUTE_UNUSED
,
20603 int flags ATTRIBUTE_UNUSED
,
20604 bool *no_add_attrs
)
20606 tree type
= *node
, result
= NULL_TREE
;
20607 enum machine_mode mode
;
20610 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
20611 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
20612 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
20615 while (POINTER_TYPE_P (type
)
20616 || TREE_CODE (type
) == FUNCTION_TYPE
20617 || TREE_CODE (type
) == METHOD_TYPE
20618 || TREE_CODE (type
) == ARRAY_TYPE
)
20619 type
= TREE_TYPE (type
);
20621 mode
= TYPE_MODE (type
);
20623 /* Check for invalid AltiVec type qualifiers. */
20624 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
20627 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
20628 else if (rs6000_warn_altivec_long
)
20629 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
20631 else if (type
== long_long_unsigned_type_node
20632 || type
== long_long_integer_type_node
)
20633 error ("use of %<long long%> in AltiVec types is invalid");
20634 else if (type
== double_type_node
)
20635 error ("use of %<double%> in AltiVec types is invalid");
20636 else if (type
== long_double_type_node
)
20637 error ("use of %<long double%> in AltiVec types is invalid");
20638 else if (type
== boolean_type_node
)
20639 error ("use of boolean types in AltiVec types is invalid");
20640 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
20641 error ("use of %<complex%> in AltiVec types is invalid");
20642 else if (DECIMAL_FLOAT_MODE_P (mode
))
20643 error ("use of decimal floating point types in AltiVec types is invalid");
20645 switch (altivec_type
)
20648 unsigned_p
= TYPE_UNSIGNED (type
);
20652 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
20655 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
20658 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
20660 case SFmode
: result
= V4SF_type_node
; break;
20661 /* If the user says 'vector int bool', we may be handed the 'bool'
20662 attribute _before_ the 'vector' attribute, and so select the
20663 proper type in the 'b' case below. */
20664 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
20672 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
20673 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
20674 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
20681 case V8HImode
: result
= pixel_V8HI_type_node
;
20687 /* Propagate qualifiers attached to the element type
20688 onto the vector type. */
20689 if (result
&& result
!= type
&& TYPE_QUALS (type
))
20690 result
= build_qualified_type (result
, TYPE_QUALS (type
));
20692 *no_add_attrs
= true; /* No need to hang on to the attribute. */
20695 *node
= lang_hooks
.types
.reconstruct_complex_type (*node
, result
);
20700 /* AltiVec defines four built-in scalar types that serve as vector
20701 elements; we must teach the compiler how to mangle them. */
20703 static const char *
20704 rs6000_mangle_type (const_tree type
)
20706 type
= TYPE_MAIN_VARIANT (type
);
20708 if (TREE_CODE (type
) != VOID_TYPE
&& TREE_CODE (type
) != BOOLEAN_TYPE
20709 && TREE_CODE (type
) != INTEGER_TYPE
&& TREE_CODE (type
) != REAL_TYPE
)
20712 if (type
== bool_char_type_node
) return "U6__boolc";
20713 if (type
== bool_short_type_node
) return "U6__bools";
20714 if (type
== pixel_type_node
) return "u7__pixel";
20715 if (type
== bool_int_type_node
) return "U6__booli";
20717 /* Mangle IBM extended float long double as `g' (__float128) on
20718 powerpc*-linux where long-double-64 previously was the default. */
20719 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
20721 && TARGET_LONG_DOUBLE_128
20722 && !TARGET_IEEEQUAD
)
20725 /* For all other types, use normal C++ mangling. */
20729 /* Handle a "longcall" or "shortcall" attribute; arguments as in
20730 struct attribute_spec.handler. */
20733 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
20734 tree args ATTRIBUTE_UNUSED
,
20735 int flags ATTRIBUTE_UNUSED
,
20736 bool *no_add_attrs
)
20738 if (TREE_CODE (*node
) != FUNCTION_TYPE
20739 && TREE_CODE (*node
) != FIELD_DECL
20740 && TREE_CODE (*node
) != TYPE_DECL
)
20742 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
20744 *no_add_attrs
= true;
20750 /* Set longcall attributes on all functions declared when
20751 rs6000_default_long_calls is true. */
20753 rs6000_set_default_type_attributes (tree type
)
20755 if (rs6000_default_long_calls
20756 && (TREE_CODE (type
) == FUNCTION_TYPE
20757 || TREE_CODE (type
) == METHOD_TYPE
))
20758 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
20760 TYPE_ATTRIBUTES (type
));
20763 darwin_set_default_type_attributes (type
);
20767 /* Return a reference suitable for calling a function with the
20768 longcall attribute. */
20771 rs6000_longcall_ref (rtx call_ref
)
20773 const char *call_name
;
20776 if (GET_CODE (call_ref
) != SYMBOL_REF
)
20779 /* System V adds '.' to the internal name, so skip them. */
20780 call_name
= XSTR (call_ref
, 0);
20781 if (*call_name
== '.')
20783 while (*call_name
== '.')
20786 node
= get_identifier (call_name
);
20787 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
20790 return force_reg (Pmode
, call_ref
);
20793 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
20794 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
20797 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
20798 struct attribute_spec.handler. */
20800 rs6000_handle_struct_attribute (tree
*node
, tree name
,
20801 tree args ATTRIBUTE_UNUSED
,
20802 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
20805 if (DECL_P (*node
))
20807 if (TREE_CODE (*node
) == TYPE_DECL
)
20808 type
= &TREE_TYPE (*node
);
20813 if (!(type
&& (TREE_CODE (*type
) == RECORD_TYPE
20814 || TREE_CODE (*type
) == UNION_TYPE
)))
20816 warning (OPT_Wattributes
, "%qE attribute ignored", name
);
20817 *no_add_attrs
= true;
20820 else if ((is_attribute_p ("ms_struct", name
)
20821 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type
)))
20822 || ((is_attribute_p ("gcc_struct", name
)
20823 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type
)))))
20825 warning (OPT_Wattributes
, "%qE incompatible attribute ignored",
20827 *no_add_attrs
= true;
20834 rs6000_ms_bitfield_layout_p (const_tree record_type
)
20836 return (TARGET_USE_MS_BITFIELD_LAYOUT
&&
20837 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type
)))
20838 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type
));
20841 #ifdef USING_ELFOS_H
20843 /* A get_unnamed_section callback, used for switching to toc_section. */
20846 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
20848 if (DEFAULT_ABI
== ABI_AIX
20849 && TARGET_MINIMAL_TOC
20850 && !TARGET_RELOCATABLE
)
20852 if (!toc_initialized
)
20854 toc_initialized
= 1;
20855 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
20856 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LCTOC", 0);
20857 fprintf (asm_out_file
, "\t.tc ");
20858 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1[TC],");
20859 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
20860 fprintf (asm_out_file
, "\n");
20862 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
20863 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
20864 fprintf (asm_out_file
, " = .+32768\n");
20867 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
20869 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_RELOCATABLE
)
20870 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
20873 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
20874 if (!toc_initialized
)
20876 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
20877 fprintf (asm_out_file
, " = .+32768\n");
20878 toc_initialized
= 1;
20883 /* Implement TARGET_ASM_INIT_SECTIONS. */
20886 rs6000_elf_asm_init_sections (void)
20889 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op
, NULL
);
20892 = get_unnamed_section (SECTION_WRITE
, output_section_asm_op
,
20893 SDATA2_SECTION_ASM_OP
);
20896 /* Implement TARGET_SELECT_RTX_SECTION. */
20899 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
20900 unsigned HOST_WIDE_INT align
)
20902 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
20903 return toc_section
;
20905 return default_elf_select_rtx_section (mode
, x
, align
);
20908 /* For a SYMBOL_REF, set generic flags and then perform some
20909 target-specific processing.
20911 When the AIX ABI is requested on a non-AIX system, replace the
20912 function name with the real name (with a leading .) rather than the
20913 function descriptor name. This saves a lot of overriding code to
20914 read the prefixes. */
20917 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
20919 default_encode_section_info (decl
, rtl
, first
);
20922 && TREE_CODE (decl
) == FUNCTION_DECL
20924 && DEFAULT_ABI
== ABI_AIX
)
20926 rtx sym_ref
= XEXP (rtl
, 0);
20927 size_t len
= strlen (XSTR (sym_ref
, 0));
20928 char *str
= XALLOCAVEC (char, len
+ 2);
20930 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
20931 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
20936 compare_section_name (const char *section
, const char *templ
)
20940 len
= strlen (templ
);
20941 return (strncmp (section
, templ
, len
) == 0
20942 && (section
[len
] == 0 || section
[len
] == '.'));
20946 rs6000_elf_in_small_data_p (const_tree decl
)
20948 if (rs6000_sdata
== SDATA_NONE
)
20951 /* We want to merge strings, so we never consider them small data. */
20952 if (TREE_CODE (decl
) == STRING_CST
)
20955 /* Functions are never in the small data area. */
20956 if (TREE_CODE (decl
) == FUNCTION_DECL
)
20959 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
20961 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
20962 if (compare_section_name (section
, ".sdata")
20963 || compare_section_name (section
, ".sdata2")
20964 || compare_section_name (section
, ".gnu.linkonce.s")
20965 || compare_section_name (section
, ".sbss")
20966 || compare_section_name (section
, ".sbss2")
20967 || compare_section_name (section
, ".gnu.linkonce.sb")
20968 || strcmp (section
, ".PPC.EMB.sdata0") == 0
20969 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
20974 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
20977 && (unsigned HOST_WIDE_INT
) size
<= g_switch_value
20978 /* If it's not public, and we're not going to reference it there,
20979 there's no need to put it in the small data section. */
20980 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
20987 #endif /* USING_ELFOS_H */
20989 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
20992 rs6000_use_blocks_for_constant_p (enum machine_mode mode
, const_rtx x
)
20994 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
);
20997 /* Return a REG that occurs in ADDR with coefficient 1.
20998 ADDR can be effectively incremented by incrementing REG.
21000 r0 is special and we must not select it as an address
21001 register by this routine since our caller will try to
21002 increment the returned register via an "la" instruction. */
21005 find_addr_reg (rtx addr
)
21007 while (GET_CODE (addr
) == PLUS
)
21009 if (GET_CODE (XEXP (addr
, 0)) == REG
21010 && REGNO (XEXP (addr
, 0)) != 0)
21011 addr
= XEXP (addr
, 0);
21012 else if (GET_CODE (XEXP (addr
, 1)) == REG
21013 && REGNO (XEXP (addr
, 1)) != 0)
21014 addr
= XEXP (addr
, 1);
21015 else if (CONSTANT_P (XEXP (addr
, 0)))
21016 addr
= XEXP (addr
, 1);
21017 else if (CONSTANT_P (XEXP (addr
, 1)))
21018 addr
= XEXP (addr
, 0);
21020 gcc_unreachable ();
21022 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
21027 rs6000_fatal_bad_address (rtx op
)
21029 fatal_insn ("bad address", op
);
21034 static tree branch_island_list
= 0;
21036 /* Remember to generate a branch island for far calls to the given
21040 add_compiler_branch_island (tree label_name
, tree function_name
,
21043 tree branch_island
= build_tree_list (function_name
, label_name
);
21044 TREE_TYPE (branch_island
) = build_int_cst (NULL_TREE
, line_number
);
21045 TREE_CHAIN (branch_island
) = branch_island_list
;
21046 branch_island_list
= branch_island
;
21049 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
21050 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
21051 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
21052 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
21054 /* Generate far-jump branch islands for everything on the
21055 branch_island_list. Invoked immediately after the last instruction
21056 of the epilogue has been emitted; the branch-islands must be
21057 appended to, and contiguous with, the function body. Mach-O stubs
21058 are generated in machopic_output_stub(). */
21061 macho_branch_islands (void)
21064 tree branch_island
;
21066 for (branch_island
= branch_island_list
;
21068 branch_island
= TREE_CHAIN (branch_island
))
21070 const char *label
=
21071 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island
));
21073 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island
));
21074 char name_buf
[512];
21075 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
21076 if (name
[0] == '*' || name
[0] == '&')
21077 strcpy (name_buf
, name
+1);
21081 strcpy (name_buf
+1, name
);
21083 strcpy (tmp_buf
, "\n");
21084 strcat (tmp_buf
, label
);
21085 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
21086 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
21087 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
21088 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
21091 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
21092 strcat (tmp_buf
, label
);
21093 strcat (tmp_buf
, "_pic\n");
21094 strcat (tmp_buf
, label
);
21095 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
21097 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
21098 strcat (tmp_buf
, name_buf
);
21099 strcat (tmp_buf
, " - ");
21100 strcat (tmp_buf
, label
);
21101 strcat (tmp_buf
, "_pic)\n");
21103 strcat (tmp_buf
, "\tmtlr r0\n");
21105 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
21106 strcat (tmp_buf
, name_buf
);
21107 strcat (tmp_buf
, " - ");
21108 strcat (tmp_buf
, label
);
21109 strcat (tmp_buf
, "_pic)\n");
21111 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
21115 strcat (tmp_buf
, ":\nlis r12,hi16(");
21116 strcat (tmp_buf
, name_buf
);
21117 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
21118 strcat (tmp_buf
, name_buf
);
21119 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
21121 output_asm_insn (tmp_buf
, 0);
21122 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
21123 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
21124 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
21125 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
21128 branch_island_list
= 0;
21131 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
21132 already there or not. */
21135 no_previous_def (tree function_name
)
21137 tree branch_island
;
21138 for (branch_island
= branch_island_list
;
21140 branch_island
= TREE_CHAIN (branch_island
))
21141 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
21146 /* GET_PREV_LABEL gets the label name from the previous definition of
21150 get_prev_label (tree function_name
)
21152 tree branch_island
;
21153 for (branch_island
= branch_island_list
;
21155 branch_island
= TREE_CHAIN (branch_island
))
21156 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
21157 return BRANCH_ISLAND_LABEL_NAME (branch_island
);
21161 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
21162 #define DARWIN_LINKER_GENERATES_ISLANDS 0
21165 /* KEXTs still need branch islands. */
21166 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
21167 || flag_mkernel || flag_apple_kext)
21169 /* INSN is either a function call or a millicode call. It may have an
21170 unconditional jump in its delay slot.
21172 CALL_DEST is the routine we are calling. */
21175 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
21176 int cookie_operand_number
)
21178 static char buf
[256];
21179 if (DARWIN_GENERATE_ISLANDS
21180 && GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
21181 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
21184 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
21186 if (no_previous_def (funname
))
21188 rtx label_rtx
= gen_label_rtx ();
21189 char *label_buf
, temp_buf
[256];
21190 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
21191 CODE_LABEL_NUMBER (label_rtx
));
21192 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
21193 labelname
= get_identifier (label_buf
);
21194 add_compiler_branch_island (labelname
, funname
, insn_line (insn
));
21197 labelname
= get_prev_label (funname
);
21199 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
21200 instruction will reach 'foo', otherwise link as 'bl L42'".
21201 "L42" should be a 'branch island', that will do a far jump to
21202 'foo'. Branch islands are generated in
21203 macho_branch_islands(). */
21204 sprintf (buf
, "jbsr %%z%d,%.246s",
21205 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
21208 sprintf (buf
, "bl %%z%d", dest_operand_number
);
21212 /* Generate PIC and indirect symbol stubs. */
21215 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
21217 unsigned int length
;
21218 char *symbol_name
, *lazy_ptr_name
;
21219 char *local_label_0
;
21220 static int label
= 0;
21222 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
21223 symb
= (*targetm
.strip_name_encoding
) (symb
);
21226 length
= strlen (symb
);
21227 symbol_name
= XALLOCAVEC (char, length
+ 32);
21228 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
21230 lazy_ptr_name
= XALLOCAVEC (char, length
+ 32);
21231 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
21234 switch_to_section (darwin_sections
[machopic_picsymbol_stub1_section
]);
21236 switch_to_section (darwin_sections
[machopic_symbol_stub1_section
]);
21240 fprintf (file
, "\t.align 5\n");
21242 fprintf (file
, "%s:\n", stub
);
21243 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
21246 local_label_0
= XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
21247 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
21249 fprintf (file
, "\tmflr r0\n");
21250 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
21251 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
21252 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
21253 lazy_ptr_name
, local_label_0
);
21254 fprintf (file
, "\tmtlr r0\n");
21255 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
21256 (TARGET_64BIT
? "ldu" : "lwzu"),
21257 lazy_ptr_name
, local_label_0
);
21258 fprintf (file
, "\tmtctr r12\n");
21259 fprintf (file
, "\tbctr\n");
21263 fprintf (file
, "\t.align 4\n");
21265 fprintf (file
, "%s:\n", stub
);
21266 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
21268 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
21269 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
21270 (TARGET_64BIT
? "ldu" : "lwzu"),
21272 fprintf (file
, "\tmtctr r12\n");
21273 fprintf (file
, "\tbctr\n");
21276 switch_to_section (darwin_sections
[machopic_lazy_symbol_ptr_section
]);
21277 fprintf (file
, "%s:\n", lazy_ptr_name
);
21278 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
21279 fprintf (file
, "%sdyld_stub_binding_helper\n",
21280 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
21283 /* Legitimize PIC addresses. If the address is already
21284 position-independent, we return ORIG. Newly generated
21285 position-independent addresses go into a reg. This is REG if non
21286 zero, otherwise we allocate register(s) as necessary. */
21288 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
21291 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
21296 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
21297 reg
= gen_reg_rtx (Pmode
);
21299 if (GET_CODE (orig
) == CONST
)
21303 if (GET_CODE (XEXP (orig
, 0)) == PLUS
21304 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
21307 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
21309 /* Use a different reg for the intermediate value, as
21310 it will be marked UNCHANGING. */
21311 reg_temp
= !can_create_pseudo_p () ? reg
: gen_reg_rtx (Pmode
);
21312 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
21315 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
21318 if (GET_CODE (offset
) == CONST_INT
)
21320 if (SMALL_INT (offset
))
21321 return plus_constant (base
, INTVAL (offset
));
21322 else if (! reload_in_progress
&& ! reload_completed
)
21323 offset
= force_reg (Pmode
, offset
);
21326 rtx mem
= force_const_mem (Pmode
, orig
);
21327 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
21330 return gen_rtx_PLUS (Pmode
, base
, offset
);
21333 /* Fall back on generic machopic code. */
21334 return machopic_legitimize_pic_address (orig
, mode
, reg
);
21337 /* Output a .machine directive for the Darwin assembler, and call
21338 the generic start_file routine. */
21341 rs6000_darwin_file_start (void)
21343 static const struct
21349 { "ppc64", "ppc64", MASK_64BIT
},
21350 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
21351 { "power4", "ppc970", 0 },
21352 { "G5", "ppc970", 0 },
21353 { "7450", "ppc7450", 0 },
21354 { "7400", "ppc7400", MASK_ALTIVEC
},
21355 { "G4", "ppc7400", 0 },
21356 { "750", "ppc750", 0 },
21357 { "740", "ppc750", 0 },
21358 { "G3", "ppc750", 0 },
21359 { "604e", "ppc604e", 0 },
21360 { "604", "ppc604", 0 },
21361 { "603e", "ppc603", 0 },
21362 { "603", "ppc603", 0 },
21363 { "601", "ppc601", 0 },
21364 { NULL
, "ppc", 0 } };
21365 const char *cpu_id
= "";
21368 rs6000_file_start ();
21369 darwin_file_start ();
21371 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
21372 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
21373 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
21374 && rs6000_select
[i
].string
[0] != '\0')
21375 cpu_id
= rs6000_select
[i
].string
;
21377 /* Look through the mapping array. Pick the first name that either
21378 matches the argument, has a bit set in IF_SET that is also set
21379 in the target flags, or has a NULL name. */
21382 while (mapping
[i
].arg
!= NULL
21383 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
21384 && (mapping
[i
].if_set
& target_flags
) == 0)
21387 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
21390 #endif /* TARGET_MACHO */
21394 rs6000_elf_reloc_rw_mask (void)
21398 else if (DEFAULT_ABI
== ABI_AIX
)
21404 /* Record an element in the table of global constructors. SYMBOL is
21405 a SYMBOL_REF of the function to be called; PRIORITY is a number
21406 between 0 and MAX_INIT_PRIORITY.
21408 This differs from default_named_section_asm_out_constructor in
21409 that we have special handling for -mrelocatable. */
21412 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
21414 const char *section
= ".ctors";
21417 if (priority
!= DEFAULT_INIT_PRIORITY
)
21419 sprintf (buf
, ".ctors.%.5u",
21420 /* Invert the numbering so the linker puts us in the proper
21421 order; constructors are run from right to left, and the
21422 linker sorts in increasing order. */
21423 MAX_INIT_PRIORITY
- priority
);
21427 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
21428 assemble_align (POINTER_SIZE
);
21430 if (TARGET_RELOCATABLE
)
21432 fputs ("\t.long (", asm_out_file
);
21433 output_addr_const (asm_out_file
, symbol
);
21434 fputs (")@fixup\n", asm_out_file
);
21437 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
21441 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
21443 const char *section
= ".dtors";
21446 if (priority
!= DEFAULT_INIT_PRIORITY
)
21448 sprintf (buf
, ".dtors.%.5u",
21449 /* Invert the numbering so the linker puts us in the proper
21450 order; constructors are run from right to left, and the
21451 linker sorts in increasing order. */
21452 MAX_INIT_PRIORITY
- priority
);
21456 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
21457 assemble_align (POINTER_SIZE
);
21459 if (TARGET_RELOCATABLE
)
21461 fputs ("\t.long (", asm_out_file
);
21462 output_addr_const (asm_out_file
, symbol
);
21463 fputs (")@fixup\n", asm_out_file
);
21466 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
21470 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
21474 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
21475 ASM_OUTPUT_LABEL (file
, name
);
21476 fputs (DOUBLE_INT_ASM_OP
, file
);
21477 rs6000_output_function_entry (file
, name
);
21478 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
21481 fputs ("\t.size\t", file
);
21482 assemble_name (file
, name
);
21483 fputs (",24\n\t.type\t.", file
);
21484 assemble_name (file
, name
);
21485 fputs (",@function\n", file
);
21486 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
21488 fputs ("\t.globl\t.", file
);
21489 assemble_name (file
, name
);
21494 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
21495 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
21496 rs6000_output_function_entry (file
, name
);
21497 fputs (":\n", file
);
21501 if (TARGET_RELOCATABLE
21502 && !TARGET_SECURE_PLT
21503 && (get_pool_size () != 0 || crtl
->profile
)
21508 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
21510 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
21511 fprintf (file
, "\t.long ");
21512 assemble_name (file
, buf
);
21514 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
21515 assemble_name (file
, buf
);
21519 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
21520 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
21522 if (DEFAULT_ABI
== ABI_AIX
)
21524 const char *desc_name
, *orig_name
;
21526 orig_name
= (*targetm
.strip_name_encoding
) (name
);
21527 desc_name
= orig_name
;
21528 while (*desc_name
== '.')
21531 if (TREE_PUBLIC (decl
))
21532 fprintf (file
, "\t.globl %s\n", desc_name
);
21534 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
21535 fprintf (file
, "%s:\n", desc_name
);
21536 fprintf (file
, "\t.long %s\n", orig_name
);
21537 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
21538 if (DEFAULT_ABI
== ABI_AIX
)
21539 fputs ("\t.long 0\n", file
);
21540 fprintf (file
, "\t.previous\n");
21542 ASM_OUTPUT_LABEL (file
, name
);
21546 rs6000_elf_end_indicate_exec_stack (void)
21549 file_end_indicate_exec_stack ();
21555 rs6000_xcoff_asm_output_anchor (rtx symbol
)
21559 sprintf (buffer
, "$ + " HOST_WIDE_INT_PRINT_DEC
,
21560 SYMBOL_REF_BLOCK_OFFSET (symbol
));
21561 ASM_OUTPUT_DEF (asm_out_file
, XSTR (symbol
, 0), buffer
);
21565 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
21567 fputs (GLOBAL_ASM_OP
, stream
);
21568 RS6000_OUTPUT_BASENAME (stream
, name
);
21569 putc ('\n', stream
);
21572 /* A get_unnamed_decl callback, used for read-only sections. PTR
21573 points to the section string variable. */
21576 rs6000_xcoff_output_readonly_section_asm_op (const void *directive
)
21578 fprintf (asm_out_file
, "\t.csect %s[RO],%s\n",
21579 *(const char *const *) directive
,
21580 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
21583 /* Likewise for read-write sections. */
21586 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive
)
21588 fprintf (asm_out_file
, "\t.csect %s[RW],%s\n",
21589 *(const char *const *) directive
,
21590 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
21593 /* A get_unnamed_section callback, used for switching to toc_section. */
21596 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
21598 if (TARGET_MINIMAL_TOC
)
21600 /* toc_section is always selected at least once from
21601 rs6000_xcoff_file_start, so this is guaranteed to
21602 always be defined once and only once in each file. */
21603 if (!toc_initialized
)
21605 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file
);
21606 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file
);
21607 toc_initialized
= 1;
21609 fprintf (asm_out_file
, "\t.csect toc_table[RW]%s\n",
21610 (TARGET_32BIT
? "" : ",3"));
21613 fputs ("\t.toc\n", asm_out_file
);
21616 /* Implement TARGET_ASM_INIT_SECTIONS. */
21619 rs6000_xcoff_asm_init_sections (void)
21621 read_only_data_section
21622 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
21623 &xcoff_read_only_section_name
);
21625 private_data_section
21626 = get_unnamed_section (SECTION_WRITE
,
21627 rs6000_xcoff_output_readwrite_section_asm_op
,
21628 &xcoff_private_data_section_name
);
21630 read_only_private_data_section
21631 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
21632 &xcoff_private_data_section_name
);
21635 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op
, NULL
);
21637 readonly_data_section
= read_only_data_section
;
21638 exception_section
= data_section
;
21642 rs6000_xcoff_reloc_rw_mask (void)
21648 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
21649 tree decl ATTRIBUTE_UNUSED
)
21652 static const char * const suffix
[3] = { "PR", "RO", "RW" };
21654 if (flags
& SECTION_CODE
)
21656 else if (flags
& SECTION_WRITE
)
21661 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
21662 (flags
& SECTION_CODE
) ? "." : "",
21663 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
21667 rs6000_xcoff_select_section (tree decl
, int reloc
,
21668 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
21670 if (decl_readonly_section (decl
, reloc
))
21672 if (TREE_PUBLIC (decl
))
21673 return read_only_data_section
;
21675 return read_only_private_data_section
;
21679 if (TREE_PUBLIC (decl
))
21680 return data_section
;
21682 return private_data_section
;
21687 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
21691 /* Use select_section for private and uninitialized data. */
21692 if (!TREE_PUBLIC (decl
)
21693 || DECL_COMMON (decl
)
21694 || DECL_INITIAL (decl
) == NULL_TREE
21695 || DECL_INITIAL (decl
) == error_mark_node
21696 || (flag_zero_initialized_in_bss
21697 && initializer_zerop (DECL_INITIAL (decl
))))
21700 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
21701 name
= (*targetm
.strip_name_encoding
) (name
);
21702 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
21705 /* Select section for constant in constant pool.
21707 On RS/6000, all constants are in the private read-only data area.
21708 However, if this is being placed in the TOC it must be output as a
21712 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
21713 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
21715 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
21716 return toc_section
;
21718 return read_only_private_data_section
;
21721 /* Remove any trailing [DS] or the like from the symbol name. */
21723 static const char *
21724 rs6000_xcoff_strip_name_encoding (const char *name
)
21729 len
= strlen (name
);
21730 if (name
[len
- 1] == ']')
21731 return ggc_alloc_string (name
, len
- 4);
21736 /* Section attributes. AIX is always PIC. */
21738 static unsigned int
21739 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
21741 unsigned int align
;
21742 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
21744 /* Align to at least UNIT size. */
21745 if (flags
& SECTION_CODE
)
21746 align
= MIN_UNITS_PER_WORD
;
21748 /* Increase alignment of large objects if not already stricter. */
21749 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
21750 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
21751 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
21753 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
21756 /* Output at beginning of assembler file.
21758 Initialize the section names for the RS/6000 at this point.
21760 Specify filename, including full path, to assembler.
21762 We want to go into the TOC section so at least one .toc will be emitted.
21763 Also, in order to output proper .bs/.es pairs, we need at least one static
21764 [RW] section emitted.
21766 Finally, declare mcount when profiling to make the assembler happy. */
21769 rs6000_xcoff_file_start (void)
21771 rs6000_gen_section_name (&xcoff_bss_section_name
,
21772 main_input_filename
, ".bss_");
21773 rs6000_gen_section_name (&xcoff_private_data_section_name
,
21774 main_input_filename
, ".rw_");
21775 rs6000_gen_section_name (&xcoff_read_only_section_name
,
21776 main_input_filename
, ".ro_");
21778 fputs ("\t.file\t", asm_out_file
);
21779 output_quoted_string (asm_out_file
, main_input_filename
);
21780 fputc ('\n', asm_out_file
);
21781 if (write_symbols
!= NO_DEBUG
)
21782 switch_to_section (private_data_section
);
21783 switch_to_section (text_section
);
21785 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
21786 rs6000_file_start ();
21789 /* Output at end of assembler file.
21790 On the RS/6000, referencing data should automatically pull in text. */
21793 rs6000_xcoff_file_end (void)
21795 switch_to_section (text_section
);
21796 fputs ("_section_.text:\n", asm_out_file
);
21797 switch_to_section (data_section
);
21798 fputs (TARGET_32BIT
21799 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
21802 #endif /* TARGET_XCOFF */
21804 /* Compute a (partial) cost for rtx X. Return true if the complete
21805 cost has been computed, and false if subexpressions should be
21806 scanned. In either case, *TOTAL contains the cost result. */
21809 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
21812 enum machine_mode mode
= GET_MODE (x
);
21816 /* On the RS/6000, if it is valid in the insn, it is free. */
21818 if (((outer_code
== SET
21819 || outer_code
== PLUS
21820 || outer_code
== MINUS
)
21821 && (satisfies_constraint_I (x
)
21822 || satisfies_constraint_L (x
)))
21823 || (outer_code
== AND
21824 && (satisfies_constraint_K (x
)
21826 ? satisfies_constraint_L (x
)
21827 : satisfies_constraint_J (x
))
21828 || mask_operand (x
, mode
)
21830 && mask64_operand (x
, DImode
))))
21831 || ((outer_code
== IOR
|| outer_code
== XOR
)
21832 && (satisfies_constraint_K (x
)
21834 ? satisfies_constraint_L (x
)
21835 : satisfies_constraint_J (x
))))
21836 || outer_code
== ASHIFT
21837 || outer_code
== ASHIFTRT
21838 || outer_code
== LSHIFTRT
21839 || outer_code
== ROTATE
21840 || outer_code
== ROTATERT
21841 || outer_code
== ZERO_EXTRACT
21842 || (outer_code
== MULT
21843 && satisfies_constraint_I (x
))
21844 || ((outer_code
== DIV
|| outer_code
== UDIV
21845 || outer_code
== MOD
|| outer_code
== UMOD
)
21846 && exact_log2 (INTVAL (x
)) >= 0)
21847 || (outer_code
== COMPARE
21848 && (satisfies_constraint_I (x
)
21849 || satisfies_constraint_K (x
)))
21850 || (outer_code
== EQ
21851 && (satisfies_constraint_I (x
)
21852 || satisfies_constraint_K (x
)
21854 ? satisfies_constraint_L (x
)
21855 : satisfies_constraint_J (x
))))
21856 || (outer_code
== GTU
21857 && satisfies_constraint_I (x
))
21858 || (outer_code
== LTU
21859 && satisfies_constraint_P (x
)))
21864 else if ((outer_code
== PLUS
21865 && reg_or_add_cint_operand (x
, VOIDmode
))
21866 || (outer_code
== MINUS
21867 && reg_or_sub_cint_operand (x
, VOIDmode
))
21868 || ((outer_code
== SET
21869 || outer_code
== IOR
21870 || outer_code
== XOR
)
21872 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
21874 *total
= COSTS_N_INSNS (1);
21880 if (mode
== DImode
&& code
== CONST_DOUBLE
)
21882 if ((outer_code
== IOR
|| outer_code
== XOR
)
21883 && CONST_DOUBLE_HIGH (x
) == 0
21884 && (CONST_DOUBLE_LOW (x
)
21885 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)
21890 else if ((outer_code
== AND
&& and64_2_operand (x
, DImode
))
21891 || ((outer_code
== SET
21892 || outer_code
== IOR
21893 || outer_code
== XOR
)
21894 && CONST_DOUBLE_HIGH (x
) == 0))
21896 *total
= COSTS_N_INSNS (1);
21906 /* When optimizing for size, MEM should be slightly more expensive
21907 than generating address, e.g., (plus (reg) (const)).
21908 L1 cache latency is about two instructions. */
21909 *total
= !speed
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
21917 if (mode
== DFmode
)
21919 if (GET_CODE (XEXP (x
, 0)) == MULT
)
21921 /* FNMA accounted in outer NEG. */
21922 if (outer_code
== NEG
)
21923 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
21925 *total
= rs6000_cost
->dmul
;
21928 *total
= rs6000_cost
->fp
;
21930 else if (mode
== SFmode
)
21932 /* FNMA accounted in outer NEG. */
21933 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
21936 *total
= rs6000_cost
->fp
;
21939 *total
= COSTS_N_INSNS (1);
21943 if (mode
== DFmode
)
21945 if (GET_CODE (XEXP (x
, 0)) == MULT
21946 || GET_CODE (XEXP (x
, 1)) == MULT
)
21948 /* FNMA accounted in outer NEG. */
21949 if (outer_code
== NEG
)
21950 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
21952 *total
= rs6000_cost
->dmul
;
21955 *total
= rs6000_cost
->fp
;
21957 else if (mode
== SFmode
)
21959 /* FNMA accounted in outer NEG. */
21960 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
21963 *total
= rs6000_cost
->fp
;
21966 *total
= COSTS_N_INSNS (1);
21970 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
21971 && satisfies_constraint_I (XEXP (x
, 1)))
21973 if (INTVAL (XEXP (x
, 1)) >= -256
21974 && INTVAL (XEXP (x
, 1)) <= 255)
21975 *total
= rs6000_cost
->mulsi_const9
;
21977 *total
= rs6000_cost
->mulsi_const
;
21979 /* FMA accounted in outer PLUS/MINUS. */
21980 else if ((mode
== DFmode
|| mode
== SFmode
)
21981 && (outer_code
== PLUS
|| outer_code
== MINUS
))
21983 else if (mode
== DFmode
)
21984 *total
= rs6000_cost
->dmul
;
21985 else if (mode
== SFmode
)
21986 *total
= rs6000_cost
->fp
;
21987 else if (mode
== DImode
)
21988 *total
= rs6000_cost
->muldi
;
21990 *total
= rs6000_cost
->mulsi
;
21995 if (FLOAT_MODE_P (mode
))
21997 *total
= mode
== DFmode
? rs6000_cost
->ddiv
21998 : rs6000_cost
->sdiv
;
22005 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
22006 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
22008 if (code
== DIV
|| code
== MOD
)
22010 *total
= COSTS_N_INSNS (2);
22013 *total
= COSTS_N_INSNS (1);
22017 if (GET_MODE (XEXP (x
, 1)) == DImode
)
22018 *total
= rs6000_cost
->divdi
;
22020 *total
= rs6000_cost
->divsi
;
22022 /* Add in shift and subtract for MOD. */
22023 if (code
== MOD
|| code
== UMOD
)
22024 *total
+= COSTS_N_INSNS (2);
22029 *total
= COSTS_N_INSNS (4);
22033 *total
= COSTS_N_INSNS (6);
22037 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
22049 *total
= COSTS_N_INSNS (1);
22057 /* Handle mul_highpart. */
22058 if (outer_code
== TRUNCATE
22059 && GET_CODE (XEXP (x
, 0)) == MULT
)
22061 if (mode
== DImode
)
22062 *total
= rs6000_cost
->muldi
;
22064 *total
= rs6000_cost
->mulsi
;
22067 else if (outer_code
== AND
)
22070 *total
= COSTS_N_INSNS (1);
22075 if (GET_CODE (XEXP (x
, 0)) == MEM
)
22078 *total
= COSTS_N_INSNS (1);
22084 if (!FLOAT_MODE_P (mode
))
22086 *total
= COSTS_N_INSNS (1);
22092 case UNSIGNED_FLOAT
:
22095 case FLOAT_TRUNCATE
:
22096 *total
= rs6000_cost
->fp
;
22100 if (mode
== DFmode
)
22103 *total
= rs6000_cost
->fp
;
22107 switch (XINT (x
, 1))
22110 *total
= rs6000_cost
->fp
;
22122 *total
= COSTS_N_INSNS (1);
22125 else if (FLOAT_MODE_P (mode
)
22126 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
22128 *total
= rs6000_cost
->fp
;
22136 /* Carry bit requires mode == Pmode.
22137 NEG or PLUS already counted so only add one. */
22139 && (outer_code
== NEG
|| outer_code
== PLUS
))
22141 *total
= COSTS_N_INSNS (1);
22144 if (outer_code
== SET
)
22146 if (XEXP (x
, 1) == const0_rtx
)
22148 *total
= COSTS_N_INSNS (2);
22151 else if (mode
== Pmode
)
22153 *total
= COSTS_N_INSNS (3);
22162 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
22164 *total
= COSTS_N_INSNS (2);
22168 if (outer_code
== COMPARE
)
22182 /* A C expression returning the cost of moving data from a register of class
22183 CLASS1 to one of CLASS2. */
22186 rs6000_register_move_cost (enum machine_mode mode
,
22187 enum reg_class from
, enum reg_class to
)
22189 /* Moves from/to GENERAL_REGS. */
22190 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
22191 || reg_classes_intersect_p (from
, GENERAL_REGS
))
22193 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
22196 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
)
22197 return (rs6000_memory_move_cost (mode
, from
, 0)
22198 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, 0));
22200 /* It's more expensive to move CR_REGS than CR0_REGS because of the
22202 else if (from
== CR_REGS
)
22205 /* Power6 has slower LR/CTR moves so make them more expensive than
22206 memory in order to bias spills to memory .*/
22207 else if (rs6000_cpu
== PROCESSOR_POWER6
22208 && reg_classes_intersect_p (from
, LINK_OR_CTR_REGS
))
22209 return 6 * hard_regno_nregs
[0][mode
];
22212 /* A move will cost one instruction per GPR moved. */
22213 return 2 * hard_regno_nregs
[0][mode
];
22216 /* Moving between two similar registers is just one instruction. */
22217 else if (reg_classes_intersect_p (to
, from
))
22218 return (mode
== TFmode
|| mode
== TDmode
) ? 4 : 2;
22220 /* Everything else has to go through GENERAL_REGS. */
22222 return (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
22223 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
22226 /* A C expressions returning the cost of moving data of MODE from a register to
22230 rs6000_memory_move_cost (enum machine_mode mode
, enum reg_class rclass
,
22231 int in ATTRIBUTE_UNUSED
)
22233 if (reg_classes_intersect_p (rclass
, GENERAL_REGS
))
22234 return 4 * hard_regno_nregs
[0][mode
];
22235 else if (reg_classes_intersect_p (rclass
, FLOAT_REGS
))
22236 return 4 * hard_regno_nregs
[32][mode
];
22237 else if (reg_classes_intersect_p (rclass
, ALTIVEC_REGS
))
22238 return 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
22240 return 4 + rs6000_register_move_cost (mode
, rclass
, GENERAL_REGS
);
22243 /* Returns a code for a target-specific builtin that implements
22244 reciprocal of the function, or NULL_TREE if not available. */
22247 rs6000_builtin_reciprocal (unsigned int fn
, bool md_fn
,
22248 bool sqrt ATTRIBUTE_UNUSED
)
22250 if (! (TARGET_RECIP
&& TARGET_PPC_GFXOPT
&& !optimize_size
22251 && flag_finite_math_only
&& !flag_trapping_math
22252 && flag_unsafe_math_optimizations
))
22260 case BUILT_IN_SQRTF
:
22261 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRTF
];
22268 /* Newton-Raphson approximation of single-precision floating point divide n/d.
22269 Assumes no trapping math and finite arguments. */
22272 rs6000_emit_swdivsf (rtx dst
, rtx n
, rtx d
)
22274 rtx x0
, e0
, e1
, y1
, u0
, v0
, one
;
22276 x0
= gen_reg_rtx (SFmode
);
22277 e0
= gen_reg_rtx (SFmode
);
22278 e1
= gen_reg_rtx (SFmode
);
22279 y1
= gen_reg_rtx (SFmode
);
22280 u0
= gen_reg_rtx (SFmode
);
22281 v0
= gen_reg_rtx (SFmode
);
22282 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
22284 /* x0 = 1./d estimate */
22285 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
22286 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, d
),
22288 /* e0 = 1. - d * x0 */
22289 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
22290 gen_rtx_MINUS (SFmode
, one
,
22291 gen_rtx_MULT (SFmode
, d
, x0
))));
22292 /* e1 = e0 + e0 * e0 */
22293 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
22294 gen_rtx_PLUS (SFmode
,
22295 gen_rtx_MULT (SFmode
, e0
, e0
), e0
)));
22296 /* y1 = x0 + e1 * x0 */
22297 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
22298 gen_rtx_PLUS (SFmode
,
22299 gen_rtx_MULT (SFmode
, e1
, x0
), x0
)));
22301 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
22302 gen_rtx_MULT (SFmode
, n
, y1
)));
22303 /* v0 = n - d * u0 */
22304 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
22305 gen_rtx_MINUS (SFmode
, n
,
22306 gen_rtx_MULT (SFmode
, d
, u0
))));
22307 /* dst = u0 + v0 * y1 */
22308 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
22309 gen_rtx_PLUS (SFmode
,
22310 gen_rtx_MULT (SFmode
, v0
, y1
), u0
)));
22313 /* Newton-Raphson approximation of double-precision floating point divide n/d.
22314 Assumes no trapping math and finite arguments. */
22317 rs6000_emit_swdivdf (rtx dst
, rtx n
, rtx d
)
22319 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
22321 x0
= gen_reg_rtx (DFmode
);
22322 e0
= gen_reg_rtx (DFmode
);
22323 e1
= gen_reg_rtx (DFmode
);
22324 e2
= gen_reg_rtx (DFmode
);
22325 y1
= gen_reg_rtx (DFmode
);
22326 y2
= gen_reg_rtx (DFmode
);
22327 y3
= gen_reg_rtx (DFmode
);
22328 u0
= gen_reg_rtx (DFmode
);
22329 v0
= gen_reg_rtx (DFmode
);
22330 one
= force_reg (DFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, DFmode
));
22332 /* x0 = 1./d estimate */
22333 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
22334 gen_rtx_UNSPEC (DFmode
, gen_rtvec (1, d
),
22336 /* e0 = 1. - d * x0 */
22337 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
22338 gen_rtx_MINUS (DFmode
, one
,
22339 gen_rtx_MULT (SFmode
, d
, x0
))));
22340 /* y1 = x0 + e0 * x0 */
22341 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
22342 gen_rtx_PLUS (DFmode
,
22343 gen_rtx_MULT (DFmode
, e0
, x0
), x0
)));
22345 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
22346 gen_rtx_MULT (DFmode
, e0
, e0
)));
22347 /* y2 = y1 + e1 * y1 */
22348 emit_insn (gen_rtx_SET (VOIDmode
, y2
,
22349 gen_rtx_PLUS (DFmode
,
22350 gen_rtx_MULT (DFmode
, e1
, y1
), y1
)));
22352 emit_insn (gen_rtx_SET (VOIDmode
, e2
,
22353 gen_rtx_MULT (DFmode
, e1
, e1
)));
22354 /* y3 = y2 + e2 * y2 */
22355 emit_insn (gen_rtx_SET (VOIDmode
, y3
,
22356 gen_rtx_PLUS (DFmode
,
22357 gen_rtx_MULT (DFmode
, e2
, y2
), y2
)));
22359 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
22360 gen_rtx_MULT (DFmode
, n
, y3
)));
22361 /* v0 = n - d * u0 */
22362 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
22363 gen_rtx_MINUS (DFmode
, n
,
22364 gen_rtx_MULT (DFmode
, d
, u0
))));
22365 /* dst = u0 + v0 * y3 */
22366 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
22367 gen_rtx_PLUS (DFmode
,
22368 gen_rtx_MULT (DFmode
, v0
, y3
), u0
)));
22372 /* Newton-Raphson approximation of single-precision floating point rsqrt.
22373 Assumes no trapping math and finite arguments. */
22376 rs6000_emit_swrsqrtsf (rtx dst
, rtx src
)
22378 rtx x0
, x1
, x2
, y1
, u0
, u1
, u2
, v0
, v1
, v2
, t0
,
22379 half
, one
, halfthree
, c1
, cond
, label
;
22381 x0
= gen_reg_rtx (SFmode
);
22382 x1
= gen_reg_rtx (SFmode
);
22383 x2
= gen_reg_rtx (SFmode
);
22384 y1
= gen_reg_rtx (SFmode
);
22385 u0
= gen_reg_rtx (SFmode
);
22386 u1
= gen_reg_rtx (SFmode
);
22387 u2
= gen_reg_rtx (SFmode
);
22388 v0
= gen_reg_rtx (SFmode
);
22389 v1
= gen_reg_rtx (SFmode
);
22390 v2
= gen_reg_rtx (SFmode
);
22391 t0
= gen_reg_rtx (SFmode
);
22392 halfthree
= gen_reg_rtx (SFmode
);
22393 cond
= gen_rtx_REG (CCFPmode
, CR1_REGNO
);
22394 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
22396 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
22397 emit_insn (gen_rtx_SET (VOIDmode
, t0
,
22398 gen_rtx_MULT (SFmode
, src
, src
)));
22400 emit_insn (gen_rtx_SET (VOIDmode
, cond
,
22401 gen_rtx_COMPARE (CCFPmode
, t0
, src
)));
22402 c1
= gen_rtx_EQ (VOIDmode
, cond
, const0_rtx
);
22403 emit_unlikely_jump (c1
, label
);
22405 half
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf
, SFmode
));
22406 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
22408 /* halfthree = 1.5 = 1.0 + 0.5 */
22409 emit_insn (gen_rtx_SET (VOIDmode
, halfthree
,
22410 gen_rtx_PLUS (SFmode
, one
, half
)));
22412 /* x0 = rsqrt estimate */
22413 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
22414 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, src
),
22417 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
22418 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
22419 gen_rtx_MINUS (SFmode
,
22420 gen_rtx_MULT (SFmode
, src
, halfthree
),
22423 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
22424 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
22425 gen_rtx_MULT (SFmode
, x0
, x0
)));
22426 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
22427 gen_rtx_MINUS (SFmode
,
22429 gen_rtx_MULT (SFmode
, y1
, u0
))));
22430 emit_insn (gen_rtx_SET (VOIDmode
, x1
,
22431 gen_rtx_MULT (SFmode
, x0
, v0
)));
22433 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
22434 emit_insn (gen_rtx_SET (VOIDmode
, u1
,
22435 gen_rtx_MULT (SFmode
, x1
, x1
)));
22436 emit_insn (gen_rtx_SET (VOIDmode
, v1
,
22437 gen_rtx_MINUS (SFmode
,
22439 gen_rtx_MULT (SFmode
, y1
, u1
))));
22440 emit_insn (gen_rtx_SET (VOIDmode
, x2
,
22441 gen_rtx_MULT (SFmode
, x1
, v1
)));
22443 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
22444 emit_insn (gen_rtx_SET (VOIDmode
, u2
,
22445 gen_rtx_MULT (SFmode
, x2
, x2
)));
22446 emit_insn (gen_rtx_SET (VOIDmode
, v2
,
22447 gen_rtx_MINUS (SFmode
,
22449 gen_rtx_MULT (SFmode
, y1
, u2
))));
22450 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
22451 gen_rtx_MULT (SFmode
, x2
, v2
)));
22453 emit_label (XEXP (label
, 0));
22456 /* Emit popcount intrinsic on TARGET_POPCNTB targets. DST is the
22457 target, and SRC is the argument operand. */
22460 rs6000_emit_popcount (rtx dst
, rtx src
)
22462 enum machine_mode mode
= GET_MODE (dst
);
22465 tmp1
= gen_reg_rtx (mode
);
22467 if (mode
== SImode
)
22469 emit_insn (gen_popcntbsi2 (tmp1
, src
));
22470 tmp2
= expand_mult (SImode
, tmp1
, GEN_INT (0x01010101),
22472 tmp2
= force_reg (SImode
, tmp2
);
22473 emit_insn (gen_lshrsi3 (dst
, tmp2
, GEN_INT (24)));
22477 emit_insn (gen_popcntbdi2 (tmp1
, src
));
22478 tmp2
= expand_mult (DImode
, tmp1
,
22479 GEN_INT ((HOST_WIDE_INT
)
22480 0x01010101 << 32 | 0x01010101),
22482 tmp2
= force_reg (DImode
, tmp2
);
22483 emit_insn (gen_lshrdi3 (dst
, tmp2
, GEN_INT (56)));
22488 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
22489 target, and SRC is the argument operand. */
22492 rs6000_emit_parity (rtx dst
, rtx src
)
22494 enum machine_mode mode
= GET_MODE (dst
);
22497 tmp
= gen_reg_rtx (mode
);
22498 if (mode
== SImode
)
22500 /* Is mult+shift >= shift+xor+shift+xor? */
22501 if (rs6000_cost
->mulsi_const
>= COSTS_N_INSNS (3))
22503 rtx tmp1
, tmp2
, tmp3
, tmp4
;
22505 tmp1
= gen_reg_rtx (SImode
);
22506 emit_insn (gen_popcntbsi2 (tmp1
, src
));
22508 tmp2
= gen_reg_rtx (SImode
);
22509 emit_insn (gen_lshrsi3 (tmp2
, tmp1
, GEN_INT (16)));
22510 tmp3
= gen_reg_rtx (SImode
);
22511 emit_insn (gen_xorsi3 (tmp3
, tmp1
, tmp2
));
22513 tmp4
= gen_reg_rtx (SImode
);
22514 emit_insn (gen_lshrsi3 (tmp4
, tmp3
, GEN_INT (8)));
22515 emit_insn (gen_xorsi3 (tmp
, tmp3
, tmp4
));
22518 rs6000_emit_popcount (tmp
, src
);
22519 emit_insn (gen_andsi3 (dst
, tmp
, const1_rtx
));
22523 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
22524 if (rs6000_cost
->muldi
>= COSTS_N_INSNS (5))
22526 rtx tmp1
, tmp2
, tmp3
, tmp4
, tmp5
, tmp6
;
22528 tmp1
= gen_reg_rtx (DImode
);
22529 emit_insn (gen_popcntbdi2 (tmp1
, src
));
22531 tmp2
= gen_reg_rtx (DImode
);
22532 emit_insn (gen_lshrdi3 (tmp2
, tmp1
, GEN_INT (32)));
22533 tmp3
= gen_reg_rtx (DImode
);
22534 emit_insn (gen_xordi3 (tmp3
, tmp1
, tmp2
));
22536 tmp4
= gen_reg_rtx (DImode
);
22537 emit_insn (gen_lshrdi3 (tmp4
, tmp3
, GEN_INT (16)));
22538 tmp5
= gen_reg_rtx (DImode
);
22539 emit_insn (gen_xordi3 (tmp5
, tmp3
, tmp4
));
22541 tmp6
= gen_reg_rtx (DImode
);
22542 emit_insn (gen_lshrdi3 (tmp6
, tmp5
, GEN_INT (8)));
22543 emit_insn (gen_xordi3 (tmp
, tmp5
, tmp6
));
22546 rs6000_emit_popcount (tmp
, src
);
22547 emit_insn (gen_anddi3 (dst
, tmp
, const1_rtx
));
22551 /* Return an RTX representing where to find the function value of a
22552 function returning MODE. */
22554 rs6000_complex_function_value (enum machine_mode mode
)
22556 unsigned int regno
;
22558 enum machine_mode inner
= GET_MODE_INNER (mode
);
22559 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
22561 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
22562 regno
= FP_ARG_RETURN
;
22565 regno
= GP_ARG_RETURN
;
22567 /* 32-bit is OK since it'll go in r3/r4. */
22568 if (TARGET_32BIT
&& inner_bytes
>= 4)
22569 return gen_rtx_REG (mode
, regno
);
22572 if (inner_bytes
>= 8)
22573 return gen_rtx_REG (mode
, regno
);
22575 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
22577 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
22578 GEN_INT (inner_bytes
));
22579 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
22582 /* Define how to find the value returned by a function.
22583 VALTYPE is the data type of the value (as a tree).
22584 If the precise function being called is known, FUNC is its FUNCTION_DECL;
22585 otherwise, FUNC is 0.
22587 On the SPE, both FPs and vectors are returned in r3.
22589 On RS/6000 an integer value is in r3 and a floating-point value is in
22590 fp1, unless -msoft-float. */
22593 rs6000_function_value (const_tree valtype
, const_tree func ATTRIBUTE_UNUSED
)
22595 enum machine_mode mode
;
22596 unsigned int regno
;
22598 /* Special handling for structs in darwin64. */
22599 if (rs6000_darwin64_abi
22600 && TYPE_MODE (valtype
) == BLKmode
22601 && TREE_CODE (valtype
) == RECORD_TYPE
22602 && int_size_in_bytes (valtype
) > 0)
22604 CUMULATIVE_ARGS valcum
;
22608 valcum
.fregno
= FP_ARG_MIN_REG
;
22609 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
22610 /* Do a trial code generation as if this were going to be passed as
22611 an argument; if any part goes in memory, we return NULL. */
22612 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, 1, true);
22615 /* Otherwise fall through to standard ABI rules. */
22618 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
22620 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
22621 return gen_rtx_PARALLEL (DImode
,
22623 gen_rtx_EXPR_LIST (VOIDmode
,
22624 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
22626 gen_rtx_EXPR_LIST (VOIDmode
,
22627 gen_rtx_REG (SImode
,
22628 GP_ARG_RETURN
+ 1),
22631 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
22633 return gen_rtx_PARALLEL (DCmode
,
22635 gen_rtx_EXPR_LIST (VOIDmode
,
22636 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
22638 gen_rtx_EXPR_LIST (VOIDmode
,
22639 gen_rtx_REG (SImode
,
22640 GP_ARG_RETURN
+ 1),
22642 gen_rtx_EXPR_LIST (VOIDmode
,
22643 gen_rtx_REG (SImode
,
22644 GP_ARG_RETURN
+ 2),
22646 gen_rtx_EXPR_LIST (VOIDmode
,
22647 gen_rtx_REG (SImode
,
22648 GP_ARG_RETURN
+ 3),
22652 mode
= TYPE_MODE (valtype
);
22653 if ((INTEGRAL_TYPE_P (valtype
) && GET_MODE_BITSIZE (mode
) < BITS_PER_WORD
)
22654 || POINTER_TYPE_P (valtype
))
22655 mode
= TARGET_32BIT
? SImode
: DImode
;
22657 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
22658 /* _Decimal128 must use an even/odd register pair. */
22659 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
22660 else if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
22661 && ((TARGET_SINGLE_FLOAT
&& (mode
== SFmode
)) || TARGET_DOUBLE_FLOAT
))
22662 regno
= FP_ARG_RETURN
;
22663 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
22664 && targetm
.calls
.split_complex_arg
)
22665 return rs6000_complex_function_value (mode
);
22666 else if (TREE_CODE (valtype
) == VECTOR_TYPE
22667 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
22668 && ALTIVEC_VECTOR_MODE (mode
))
22669 regno
= ALTIVEC_ARG_RETURN
;
22670 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
22671 && (mode
== DFmode
|| mode
== DCmode
22672 || mode
== TFmode
|| mode
== TCmode
))
22673 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
22675 regno
= GP_ARG_RETURN
;
22677 return gen_rtx_REG (mode
, regno
);
22680 /* Define how to find the value returned by a library function
22681 assuming the value has mode MODE. */
22683 rs6000_libcall_value (enum machine_mode mode
)
22685 unsigned int regno
;
22687 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
22689 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
22690 return gen_rtx_PARALLEL (DImode
,
22692 gen_rtx_EXPR_LIST (VOIDmode
,
22693 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
22695 gen_rtx_EXPR_LIST (VOIDmode
,
22696 gen_rtx_REG (SImode
,
22697 GP_ARG_RETURN
+ 1),
22701 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
22702 /* _Decimal128 must use an even/odd register pair. */
22703 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
22704 else if (SCALAR_FLOAT_MODE_P (mode
)
22705 && TARGET_HARD_FLOAT
&& TARGET_FPRS
22706 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
) || TARGET_DOUBLE_FLOAT
))
22707 regno
= FP_ARG_RETURN
;
22708 else if (ALTIVEC_VECTOR_MODE (mode
)
22709 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
22710 regno
= ALTIVEC_ARG_RETURN
;
22711 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
22712 return rs6000_complex_function_value (mode
);
22713 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
22714 && (mode
== DFmode
|| mode
== DCmode
22715 || mode
== TFmode
|| mode
== TCmode
))
22716 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
22718 regno
= GP_ARG_RETURN
;
22720 return gen_rtx_REG (mode
, regno
);
22723 /* Define the offset between two registers, FROM to be eliminated and its
22724 replacement TO, at the start of a routine. */
22726 rs6000_initial_elimination_offset (int from
, int to
)
22728 rs6000_stack_t
*info
= rs6000_stack_info ();
22729 HOST_WIDE_INT offset
;
22731 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
22732 offset
= info
->push_p
? 0 : -info
->total_size
;
22733 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
22735 offset
= info
->push_p
? 0 : -info
->total_size
;
22736 if (FRAME_GROWS_DOWNWARD
)
22737 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
22739 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
22740 offset
= FRAME_GROWS_DOWNWARD
22741 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
22743 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
22744 offset
= info
->total_size
;
22745 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
22746 offset
= info
->push_p
? info
->total_size
: 0;
22747 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
22750 gcc_unreachable ();
22756 rs6000_dwarf_register_span (rtx reg
)
22760 unsigned regno
= REGNO (reg
);
22761 enum machine_mode mode
= GET_MODE (reg
);
22765 && (SPE_VECTOR_MODE (GET_MODE (reg
))
22766 || (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
)
22767 && mode
!= SFmode
&& mode
!= SDmode
&& mode
!= SCmode
)))
22772 regno
= REGNO (reg
);
22774 /* The duality of the SPE register size wreaks all kinds of havoc.
22775 This is a way of distinguishing r0 in 32-bits from r0 in
22777 words
= (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
22778 gcc_assert (words
<= 4);
22779 for (i
= 0; i
< words
; i
++, regno
++)
22781 if (BYTES_BIG_ENDIAN
)
22783 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
+ 1200);
22784 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
);
22788 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
);
22789 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
+ 1200);
22793 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (words
* 2, parts
));
22796 /* Fill in sizes for SPE register high parts in table used by unwinder. */
22799 rs6000_init_dwarf_reg_sizes_extra (tree address
)
22804 enum machine_mode mode
= TYPE_MODE (char_type_node
);
22805 rtx addr
= expand_expr (address
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
22806 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
22807 rtx value
= gen_int_mode (4, mode
);
22809 for (i
= 1201; i
< 1232; i
++)
22811 int column
= DWARF_REG_TO_UNWIND_COLUMN (i
);
22812 HOST_WIDE_INT offset
22813 = DWARF_FRAME_REGNUM (column
) * GET_MODE_SIZE (mode
);
22815 emit_move_insn (adjust_address (mem
, mode
, offset
), value
);
22820 /* Map internal gcc register numbers to DWARF2 register numbers. */
22823 rs6000_dbx_register_number (unsigned int regno
)
22825 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
22827 if (regno
== MQ_REGNO
)
22829 if (regno
== LR_REGNO
)
22831 if (regno
== CTR_REGNO
)
22833 if (CR_REGNO_P (regno
))
22834 return regno
- CR0_REGNO
+ 86;
22835 if (regno
== XER_REGNO
)
22837 if (ALTIVEC_REGNO_P (regno
))
22838 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
22839 if (regno
== VRSAVE_REGNO
)
22841 if (regno
== VSCR_REGNO
)
22843 if (regno
== SPE_ACC_REGNO
)
22845 if (regno
== SPEFSCR_REGNO
)
22847 /* SPE high reg number. We get these values of regno from
22848 rs6000_dwarf_register_span. */
22849 gcc_assert (regno
>= 1200 && regno
< 1232);
22853 /* target hook eh_return_filter_mode */
22854 static enum machine_mode
22855 rs6000_eh_return_filter_mode (void)
22857 return TARGET_32BIT
? SImode
: word_mode
;
22860 /* Target hook for scalar_mode_supported_p. */
22862 rs6000_scalar_mode_supported_p (enum machine_mode mode
)
22864 if (DECIMAL_FLOAT_MODE_P (mode
))
22867 return default_scalar_mode_supported_p (mode
);
22870 /* Target hook for vector_mode_supported_p. */
22872 rs6000_vector_mode_supported_p (enum machine_mode mode
)
22875 if (TARGET_PAIRED_FLOAT
&& PAIRED_VECTOR_MODE (mode
))
22878 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
22881 else if (TARGET_ALTIVEC
&& ALTIVEC_VECTOR_MODE (mode
))
22888 /* Target hook for invalid_arg_for_unprototyped_fn. */
22889 static const char *
22890 invalid_arg_for_unprototyped_fn (const_tree typelist
, const_tree funcdecl
, const_tree val
)
22892 return (!rs6000_darwin64_abi
22894 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
22895 && (funcdecl
== NULL_TREE
22896 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
22897 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
22898 ? N_("AltiVec argument passed to unprototyped function")
22902 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
22903 setup by using __stack_chk_fail_local hidden function instead of
22904 calling __stack_chk_fail directly. Otherwise it is better to call
22905 __stack_chk_fail directly. */
22908 rs6000_stack_protect_fail (void)
22910 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
22911 ? default_hidden_stack_protect_fail ()
22912 : default_external_stack_protect_fail ();
22916 rs6000_final_prescan_insn (rtx insn
, rtx
*operand ATTRIBUTE_UNUSED
,
22917 int num_operands ATTRIBUTE_UNUSED
)
22919 if (rs6000_warn_cell_microcode
)
22922 int insn_code_number
= recog_memoized (insn
);
22923 location_t location
= locator_location (INSN_LOCATOR (insn
));
22925 /* Punt on insns we cannot recognize. */
22926 if (insn_code_number
< 0)
22929 temp
= get_insn_template (insn_code_number
, insn
);
22931 if (get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
)
22932 warning_at (location
, OPT_mwarn_cell_microcode
,
22933 "emitting microcode insn %s\t[%s] #%d",
22934 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
22935 else if (get_attr_cell_micro (insn
) == CELL_MICRO_CONDITIONAL
)
22936 warning_at (location
, OPT_mwarn_cell_microcode
,
22937 "emitting conditional microcode insn %s\t[%s] #%d",
22938 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
22942 #include "gt-rs6000.h"