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 /* Save information from a "cmpxx" operation until the branch or scc is
195 rtx rs6000_compare_op0
, rs6000_compare_op1
;
196 int rs6000_compare_fp_p
;
198 /* Label number of label created for -mrelocatable, to call to so we can
199 get the address of the GOT section */
200 int rs6000_pic_labelno
;
203 /* Which abi to adhere to */
204 const char *rs6000_abi_name
;
206 /* Semantics of the small data area */
207 enum rs6000_sdata_type rs6000_sdata
= SDATA_DATA
;
209 /* Which small data model to use */
210 const char *rs6000_sdata_name
= (char *)0;
212 /* Counter for labels which are to be placed in .fixup. */
213 int fixuplabelno
= 0;
216 /* Bit size of immediate TLS offsets and string from which it is decoded. */
217 int rs6000_tls_size
= 32;
218 const char *rs6000_tls_size_string
;
220 /* ABI enumeration available for subtarget to use. */
221 enum rs6000_abi rs6000_current_abi
;
223 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
227 const char *rs6000_debug_name
;
228 int rs6000_debug_stack
; /* debug stack applications */
229 int rs6000_debug_arg
; /* debug argument handling */
231 /* Value is TRUE if register/mode pair is acceptable. */
232 bool rs6000_hard_regno_mode_ok_p
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
234 /* Built in types. */
236 tree rs6000_builtin_types
[RS6000_BTI_MAX
];
237 tree rs6000_builtin_decls
[RS6000_BUILTIN_COUNT
];
239 const char *rs6000_traceback_name
;
241 traceback_default
= 0,
247 /* Flag to say the TOC is initialized */
249 char toc_label_name
[10];
251 /* Cached value of rs6000_variable_issue. This is cached in
252 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
253 static short cached_can_issue_more
;
255 static GTY(()) section
*read_only_data_section
;
256 static GTY(()) section
*private_data_section
;
257 static GTY(()) section
*read_only_private_data_section
;
258 static GTY(()) section
*sdata2_section
;
259 static GTY(()) section
*toc_section
;
261 /* Control alignment for fields within structures. */
262 /* String from -malign-XXXXX. */
263 int rs6000_alignment_flags
;
265 /* True for any options that were explicitly set. */
267 bool aix_struct_ret
; /* True if -maix-struct-ret was used. */
268 bool alignment
; /* True if -malign- was used. */
269 bool spe_abi
; /* True if -mabi=spe/no-spe was used. */
270 bool altivec_abi
; /* True if -mabi=altivec/no-altivec used. */
271 bool spe
; /* True if -mspe= was used. */
272 bool float_gprs
; /* True if -mfloat-gprs= was used. */
273 bool isel
; /* True if -misel was used. */
274 bool long_double
; /* True if -mlong-double- was used. */
275 bool ieee
; /* True if -mabi=ieee/ibmlongdouble used. */
276 bool vrsave
; /* True if -mvrsave was used. */
277 } rs6000_explicit_options
;
279 struct builtin_description
281 /* mask is not const because we're going to alter it below. This
282 nonsense will go away when we rewrite the -march infrastructure
283 to give us more target flag bits. */
285 const enum insn_code icode
;
286 const char *const name
;
287 const enum rs6000_builtins code
;
290 /* Target cpu costs. */
292 struct processor_costs
{
293 const int mulsi
; /* cost of SImode multiplication. */
294 const int mulsi_const
; /* cost of SImode multiplication by constant. */
295 const int mulsi_const9
; /* cost of SImode mult by short constant. */
296 const int muldi
; /* cost of DImode multiplication. */
297 const int divsi
; /* cost of SImode division. */
298 const int divdi
; /* cost of DImode division. */
299 const int fp
; /* cost of simple SFmode and DFmode insns. */
300 const int dmul
; /* cost of DFmode multiplication (and fmadd). */
301 const int sdiv
; /* cost of SFmode division (fdivs). */
302 const int ddiv
; /* cost of DFmode division (fdiv). */
303 const int cache_line_size
; /* cache line size in bytes. */
304 const int l1_cache_size
; /* size of l1 cache, in kilobytes. */
305 const int l2_cache_size
; /* size of l2 cache, in kilobytes. */
306 const int simultaneous_prefetches
; /* number of parallel prefetch
310 const struct processor_costs
*rs6000_cost
;
312 /* Processor costs (relative to an add) */
314 /* Instruction size costs on 32bit processors. */
316 struct processor_costs size32_cost
= {
317 COSTS_N_INSNS (1), /* mulsi */
318 COSTS_N_INSNS (1), /* mulsi_const */
319 COSTS_N_INSNS (1), /* mulsi_const9 */
320 COSTS_N_INSNS (1), /* muldi */
321 COSTS_N_INSNS (1), /* divsi */
322 COSTS_N_INSNS (1), /* divdi */
323 COSTS_N_INSNS (1), /* fp */
324 COSTS_N_INSNS (1), /* dmul */
325 COSTS_N_INSNS (1), /* sdiv */
326 COSTS_N_INSNS (1), /* ddiv */
333 /* Instruction size costs on 64bit processors. */
335 struct processor_costs size64_cost
= {
336 COSTS_N_INSNS (1), /* mulsi */
337 COSTS_N_INSNS (1), /* mulsi_const */
338 COSTS_N_INSNS (1), /* mulsi_const9 */
339 COSTS_N_INSNS (1), /* muldi */
340 COSTS_N_INSNS (1), /* divsi */
341 COSTS_N_INSNS (1), /* divdi */
342 COSTS_N_INSNS (1), /* fp */
343 COSTS_N_INSNS (1), /* dmul */
344 COSTS_N_INSNS (1), /* sdiv */
345 COSTS_N_INSNS (1), /* ddiv */
352 /* Instruction costs on RIOS1 processors. */
354 struct processor_costs rios1_cost
= {
355 COSTS_N_INSNS (5), /* mulsi */
356 COSTS_N_INSNS (4), /* mulsi_const */
357 COSTS_N_INSNS (3), /* mulsi_const9 */
358 COSTS_N_INSNS (5), /* muldi */
359 COSTS_N_INSNS (19), /* divsi */
360 COSTS_N_INSNS (19), /* divdi */
361 COSTS_N_INSNS (2), /* fp */
362 COSTS_N_INSNS (2), /* dmul */
363 COSTS_N_INSNS (19), /* sdiv */
364 COSTS_N_INSNS (19), /* ddiv */
365 128, /* cache line size */
371 /* Instruction costs on RIOS2 processors. */
373 struct processor_costs rios2_cost
= {
374 COSTS_N_INSNS (2), /* mulsi */
375 COSTS_N_INSNS (2), /* mulsi_const */
376 COSTS_N_INSNS (2), /* mulsi_const9 */
377 COSTS_N_INSNS (2), /* muldi */
378 COSTS_N_INSNS (13), /* divsi */
379 COSTS_N_INSNS (13), /* divdi */
380 COSTS_N_INSNS (2), /* fp */
381 COSTS_N_INSNS (2), /* dmul */
382 COSTS_N_INSNS (17), /* sdiv */
383 COSTS_N_INSNS (17), /* ddiv */
384 256, /* cache line size */
390 /* Instruction costs on RS64A processors. */
392 struct processor_costs rs64a_cost
= {
393 COSTS_N_INSNS (20), /* mulsi */
394 COSTS_N_INSNS (12), /* mulsi_const */
395 COSTS_N_INSNS (8), /* mulsi_const9 */
396 COSTS_N_INSNS (34), /* muldi */
397 COSTS_N_INSNS (65), /* divsi */
398 COSTS_N_INSNS (67), /* divdi */
399 COSTS_N_INSNS (4), /* fp */
400 COSTS_N_INSNS (4), /* dmul */
401 COSTS_N_INSNS (31), /* sdiv */
402 COSTS_N_INSNS (31), /* ddiv */
403 128, /* cache line size */
409 /* Instruction costs on MPCCORE processors. */
411 struct processor_costs mpccore_cost
= {
412 COSTS_N_INSNS (2), /* mulsi */
413 COSTS_N_INSNS (2), /* mulsi_const */
414 COSTS_N_INSNS (2), /* mulsi_const9 */
415 COSTS_N_INSNS (2), /* muldi */
416 COSTS_N_INSNS (6), /* divsi */
417 COSTS_N_INSNS (6), /* divdi */
418 COSTS_N_INSNS (4), /* fp */
419 COSTS_N_INSNS (5), /* dmul */
420 COSTS_N_INSNS (10), /* sdiv */
421 COSTS_N_INSNS (17), /* ddiv */
422 32, /* cache line size */
428 /* Instruction costs on PPC403 processors. */
430 struct processor_costs ppc403_cost
= {
431 COSTS_N_INSNS (4), /* mulsi */
432 COSTS_N_INSNS (4), /* mulsi_const */
433 COSTS_N_INSNS (4), /* mulsi_const9 */
434 COSTS_N_INSNS (4), /* muldi */
435 COSTS_N_INSNS (33), /* divsi */
436 COSTS_N_INSNS (33), /* divdi */
437 COSTS_N_INSNS (11), /* fp */
438 COSTS_N_INSNS (11), /* dmul */
439 COSTS_N_INSNS (11), /* sdiv */
440 COSTS_N_INSNS (11), /* ddiv */
441 32, /* cache line size */
447 /* Instruction costs on PPC405 processors. */
449 struct processor_costs ppc405_cost
= {
450 COSTS_N_INSNS (5), /* mulsi */
451 COSTS_N_INSNS (4), /* mulsi_const */
452 COSTS_N_INSNS (3), /* mulsi_const9 */
453 COSTS_N_INSNS (5), /* muldi */
454 COSTS_N_INSNS (35), /* divsi */
455 COSTS_N_INSNS (35), /* divdi */
456 COSTS_N_INSNS (11), /* fp */
457 COSTS_N_INSNS (11), /* dmul */
458 COSTS_N_INSNS (11), /* sdiv */
459 COSTS_N_INSNS (11), /* ddiv */
460 32, /* cache line size */
466 /* Instruction costs on PPC440 processors. */
468 struct processor_costs ppc440_cost
= {
469 COSTS_N_INSNS (3), /* mulsi */
470 COSTS_N_INSNS (2), /* mulsi_const */
471 COSTS_N_INSNS (2), /* mulsi_const9 */
472 COSTS_N_INSNS (3), /* muldi */
473 COSTS_N_INSNS (34), /* divsi */
474 COSTS_N_INSNS (34), /* divdi */
475 COSTS_N_INSNS (5), /* fp */
476 COSTS_N_INSNS (5), /* dmul */
477 COSTS_N_INSNS (19), /* sdiv */
478 COSTS_N_INSNS (33), /* ddiv */
479 32, /* cache line size */
485 /* Instruction costs on PPC601 processors. */
487 struct processor_costs ppc601_cost
= {
488 COSTS_N_INSNS (5), /* mulsi */
489 COSTS_N_INSNS (5), /* mulsi_const */
490 COSTS_N_INSNS (5), /* mulsi_const9 */
491 COSTS_N_INSNS (5), /* muldi */
492 COSTS_N_INSNS (36), /* divsi */
493 COSTS_N_INSNS (36), /* divdi */
494 COSTS_N_INSNS (4), /* fp */
495 COSTS_N_INSNS (5), /* dmul */
496 COSTS_N_INSNS (17), /* sdiv */
497 COSTS_N_INSNS (31), /* ddiv */
498 32, /* cache line size */
504 /* Instruction costs on PPC603 processors. */
506 struct processor_costs ppc603_cost
= {
507 COSTS_N_INSNS (5), /* mulsi */
508 COSTS_N_INSNS (3), /* mulsi_const */
509 COSTS_N_INSNS (2), /* mulsi_const9 */
510 COSTS_N_INSNS (5), /* muldi */
511 COSTS_N_INSNS (37), /* divsi */
512 COSTS_N_INSNS (37), /* divdi */
513 COSTS_N_INSNS (3), /* fp */
514 COSTS_N_INSNS (4), /* dmul */
515 COSTS_N_INSNS (18), /* sdiv */
516 COSTS_N_INSNS (33), /* ddiv */
517 32, /* cache line size */
523 /* Instruction costs on PPC604 processors. */
525 struct processor_costs ppc604_cost
= {
526 COSTS_N_INSNS (4), /* mulsi */
527 COSTS_N_INSNS (4), /* mulsi_const */
528 COSTS_N_INSNS (4), /* mulsi_const9 */
529 COSTS_N_INSNS (4), /* muldi */
530 COSTS_N_INSNS (20), /* divsi */
531 COSTS_N_INSNS (20), /* divdi */
532 COSTS_N_INSNS (3), /* fp */
533 COSTS_N_INSNS (3), /* dmul */
534 COSTS_N_INSNS (18), /* sdiv */
535 COSTS_N_INSNS (32), /* ddiv */
536 32, /* cache line size */
542 /* Instruction costs on PPC604e processors. */
544 struct processor_costs ppc604e_cost
= {
545 COSTS_N_INSNS (2), /* mulsi */
546 COSTS_N_INSNS (2), /* mulsi_const */
547 COSTS_N_INSNS (2), /* mulsi_const9 */
548 COSTS_N_INSNS (2), /* muldi */
549 COSTS_N_INSNS (20), /* divsi */
550 COSTS_N_INSNS (20), /* divdi */
551 COSTS_N_INSNS (3), /* fp */
552 COSTS_N_INSNS (3), /* dmul */
553 COSTS_N_INSNS (18), /* sdiv */
554 COSTS_N_INSNS (32), /* ddiv */
555 32, /* cache line size */
561 /* Instruction costs on PPC620 processors. */
563 struct processor_costs ppc620_cost
= {
564 COSTS_N_INSNS (5), /* mulsi */
565 COSTS_N_INSNS (4), /* mulsi_const */
566 COSTS_N_INSNS (3), /* mulsi_const9 */
567 COSTS_N_INSNS (7), /* muldi */
568 COSTS_N_INSNS (21), /* divsi */
569 COSTS_N_INSNS (37), /* divdi */
570 COSTS_N_INSNS (3), /* fp */
571 COSTS_N_INSNS (3), /* dmul */
572 COSTS_N_INSNS (18), /* sdiv */
573 COSTS_N_INSNS (32), /* ddiv */
574 128, /* cache line size */
580 /* Instruction costs on PPC630 processors. */
582 struct processor_costs ppc630_cost
= {
583 COSTS_N_INSNS (5), /* mulsi */
584 COSTS_N_INSNS (4), /* mulsi_const */
585 COSTS_N_INSNS (3), /* mulsi_const9 */
586 COSTS_N_INSNS (7), /* muldi */
587 COSTS_N_INSNS (21), /* divsi */
588 COSTS_N_INSNS (37), /* divdi */
589 COSTS_N_INSNS (3), /* fp */
590 COSTS_N_INSNS (3), /* dmul */
591 COSTS_N_INSNS (17), /* sdiv */
592 COSTS_N_INSNS (21), /* ddiv */
593 128, /* cache line size */
599 /* Instruction costs on Cell processor. */
600 /* COSTS_N_INSNS (1) ~ one add. */
602 struct processor_costs ppccell_cost
= {
603 COSTS_N_INSNS (9/2)+2, /* mulsi */
604 COSTS_N_INSNS (6/2), /* mulsi_const */
605 COSTS_N_INSNS (6/2), /* mulsi_const9 */
606 COSTS_N_INSNS (15/2)+2, /* muldi */
607 COSTS_N_INSNS (38/2), /* divsi */
608 COSTS_N_INSNS (70/2), /* divdi */
609 COSTS_N_INSNS (10/2), /* fp */
610 COSTS_N_INSNS (10/2), /* dmul */
611 COSTS_N_INSNS (74/2), /* sdiv */
612 COSTS_N_INSNS (74/2), /* ddiv */
613 128, /* cache line size */
619 /* Instruction costs on PPC750 and PPC7400 processors. */
621 struct processor_costs ppc750_cost
= {
622 COSTS_N_INSNS (5), /* mulsi */
623 COSTS_N_INSNS (3), /* mulsi_const */
624 COSTS_N_INSNS (2), /* mulsi_const9 */
625 COSTS_N_INSNS (5), /* muldi */
626 COSTS_N_INSNS (17), /* divsi */
627 COSTS_N_INSNS (17), /* divdi */
628 COSTS_N_INSNS (3), /* fp */
629 COSTS_N_INSNS (3), /* dmul */
630 COSTS_N_INSNS (17), /* sdiv */
631 COSTS_N_INSNS (31), /* ddiv */
632 32, /* cache line size */
638 /* Instruction costs on PPC7450 processors. */
640 struct processor_costs ppc7450_cost
= {
641 COSTS_N_INSNS (4), /* mulsi */
642 COSTS_N_INSNS (3), /* mulsi_const */
643 COSTS_N_INSNS (3), /* mulsi_const9 */
644 COSTS_N_INSNS (4), /* muldi */
645 COSTS_N_INSNS (23), /* divsi */
646 COSTS_N_INSNS (23), /* divdi */
647 COSTS_N_INSNS (5), /* fp */
648 COSTS_N_INSNS (5), /* dmul */
649 COSTS_N_INSNS (21), /* sdiv */
650 COSTS_N_INSNS (35), /* ddiv */
651 32, /* cache line size */
657 /* Instruction costs on PPC8540 processors. */
659 struct processor_costs ppc8540_cost
= {
660 COSTS_N_INSNS (4), /* mulsi */
661 COSTS_N_INSNS (4), /* mulsi_const */
662 COSTS_N_INSNS (4), /* mulsi_const9 */
663 COSTS_N_INSNS (4), /* muldi */
664 COSTS_N_INSNS (19), /* divsi */
665 COSTS_N_INSNS (19), /* divdi */
666 COSTS_N_INSNS (4), /* fp */
667 COSTS_N_INSNS (4), /* dmul */
668 COSTS_N_INSNS (29), /* sdiv */
669 COSTS_N_INSNS (29), /* ddiv */
670 32, /* cache line size */
673 1, /* prefetch streams /*/
676 /* Instruction costs on E300C2 and E300C3 cores. */
678 struct processor_costs ppce300c2c3_cost
= {
679 COSTS_N_INSNS (4), /* mulsi */
680 COSTS_N_INSNS (4), /* mulsi_const */
681 COSTS_N_INSNS (4), /* mulsi_const9 */
682 COSTS_N_INSNS (4), /* muldi */
683 COSTS_N_INSNS (19), /* divsi */
684 COSTS_N_INSNS (19), /* divdi */
685 COSTS_N_INSNS (3), /* fp */
686 COSTS_N_INSNS (4), /* dmul */
687 COSTS_N_INSNS (18), /* sdiv */
688 COSTS_N_INSNS (33), /* ddiv */
692 1, /* prefetch streams /*/
695 /* Instruction costs on PPCE500MC processors. */
697 struct processor_costs ppce500mc_cost
= {
698 COSTS_N_INSNS (4), /* mulsi */
699 COSTS_N_INSNS (4), /* mulsi_const */
700 COSTS_N_INSNS (4), /* mulsi_const9 */
701 COSTS_N_INSNS (4), /* muldi */
702 COSTS_N_INSNS (14), /* divsi */
703 COSTS_N_INSNS (14), /* divdi */
704 COSTS_N_INSNS (8), /* fp */
705 COSTS_N_INSNS (10), /* dmul */
706 COSTS_N_INSNS (36), /* sdiv */
707 COSTS_N_INSNS (66), /* ddiv */
708 64, /* cache line size */
711 1, /* prefetch streams /*/
714 /* Instruction costs on POWER4 and POWER5 processors. */
716 struct processor_costs power4_cost
= {
717 COSTS_N_INSNS (3), /* mulsi */
718 COSTS_N_INSNS (2), /* mulsi_const */
719 COSTS_N_INSNS (2), /* mulsi_const9 */
720 COSTS_N_INSNS (4), /* muldi */
721 COSTS_N_INSNS (18), /* divsi */
722 COSTS_N_INSNS (34), /* divdi */
723 COSTS_N_INSNS (3), /* fp */
724 COSTS_N_INSNS (3), /* dmul */
725 COSTS_N_INSNS (17), /* sdiv */
726 COSTS_N_INSNS (17), /* ddiv */
727 128, /* cache line size */
730 8, /* prefetch streams /*/
733 /* Instruction costs on POWER6 processors. */
735 struct processor_costs power6_cost
= {
736 COSTS_N_INSNS (8), /* mulsi */
737 COSTS_N_INSNS (8), /* mulsi_const */
738 COSTS_N_INSNS (8), /* mulsi_const9 */
739 COSTS_N_INSNS (8), /* muldi */
740 COSTS_N_INSNS (22), /* divsi */
741 COSTS_N_INSNS (28), /* divdi */
742 COSTS_N_INSNS (3), /* fp */
743 COSTS_N_INSNS (3), /* dmul */
744 COSTS_N_INSNS (13), /* sdiv */
745 COSTS_N_INSNS (16), /* ddiv */
746 128, /* cache line size */
749 16, /* prefetch streams */
753 static bool rs6000_function_ok_for_sibcall (tree
, tree
);
754 static const char *rs6000_invalid_within_doloop (const_rtx
);
755 static rtx
rs6000_generate_compare (enum rtx_code
);
756 static void rs6000_emit_stack_tie (void);
757 static void rs6000_frame_related (rtx
, rtx
, HOST_WIDE_INT
, rtx
, rtx
);
758 static bool spe_func_has_64bit_regs_p (void);
759 static void emit_frame_save (rtx
, rtx
, enum machine_mode
, unsigned int,
761 static rtx
gen_frame_mem_offset (enum machine_mode
, rtx
, int);
762 static void rs6000_emit_allocate_stack (HOST_WIDE_INT
, int, int);
763 static unsigned rs6000_hash_constant (rtx
);
764 static unsigned toc_hash_function (const void *);
765 static int toc_hash_eq (const void *, const void *);
766 static bool constant_pool_expr_p (rtx
);
767 static bool legitimate_small_data_p (enum machine_mode
, rtx
);
768 static bool legitimate_lo_sum_address_p (enum machine_mode
, rtx
, int);
769 static struct machine_function
* rs6000_init_machine_status (void);
770 static bool rs6000_assemble_integer (rtx
, unsigned int, int);
771 static bool no_global_regs_above (int, bool);
772 #ifdef HAVE_GAS_HIDDEN
773 static void rs6000_assemble_visibility (tree
, int);
775 static int rs6000_ra_ever_killed (void);
776 static tree
rs6000_handle_longcall_attribute (tree
*, tree
, tree
, int, bool *);
777 static tree
rs6000_handle_altivec_attribute (tree
*, tree
, tree
, int, bool *);
778 static bool rs6000_ms_bitfield_layout_p (const_tree
);
779 static tree
rs6000_handle_struct_attribute (tree
*, tree
, tree
, int, bool *);
780 static void rs6000_eliminate_indexed_memrefs (rtx operands
[2]);
781 static const char *rs6000_mangle_type (const_tree
);
782 extern const struct attribute_spec rs6000_attribute_table
[];
783 static void rs6000_set_default_type_attributes (tree
);
784 static rtx
rs6000_savres_routine_sym (rs6000_stack_t
*, bool, bool, bool);
785 static void rs6000_emit_stack_reset (rs6000_stack_t
*, rtx
, rtx
, int, bool);
786 static rtx
rs6000_make_savres_rtx (rs6000_stack_t
*, rtx
, int,
787 enum machine_mode
, bool, bool, bool);
788 static bool rs6000_reg_live_or_pic_offset_p (int);
789 static int rs6000_savres_strategy (rs6000_stack_t
*, bool, int, int);
790 static void rs6000_restore_saved_cr (rtx
, int);
791 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT
);
792 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT
);
793 static void rs6000_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
795 static rtx
rs6000_emit_set_long_const (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
796 static bool rs6000_return_in_memory (const_tree
, const_tree
);
797 static void rs6000_file_start (void);
799 static int rs6000_elf_reloc_rw_mask (void);
800 static void rs6000_elf_asm_out_constructor (rtx
, int);
801 static void rs6000_elf_asm_out_destructor (rtx
, int);
802 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED
;
803 static void rs6000_elf_asm_init_sections (void);
804 static section
*rs6000_elf_select_rtx_section (enum machine_mode
, rtx
,
805 unsigned HOST_WIDE_INT
);
806 static void rs6000_elf_encode_section_info (tree
, rtx
, int)
809 static bool rs6000_use_blocks_for_constant_p (enum machine_mode
, const_rtx
);
810 static void rs6000_alloc_sdmode_stack_slot (void);
811 static void rs6000_instantiate_decls (void);
813 static void rs6000_xcoff_asm_output_anchor (rtx
);
814 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
815 static void rs6000_xcoff_asm_init_sections (void);
816 static int rs6000_xcoff_reloc_rw_mask (void);
817 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree
);
818 static section
*rs6000_xcoff_select_section (tree
, int,
819 unsigned HOST_WIDE_INT
);
820 static void rs6000_xcoff_unique_section (tree
, int);
821 static section
*rs6000_xcoff_select_rtx_section
822 (enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
);
823 static const char * rs6000_xcoff_strip_name_encoding (const char *);
824 static unsigned int rs6000_xcoff_section_type_flags (tree
, const char *, int);
825 static void rs6000_xcoff_file_start (void);
826 static void rs6000_xcoff_file_end (void);
828 static int rs6000_variable_issue (FILE *, int, rtx
, int);
829 static bool rs6000_rtx_costs (rtx
, int, int, int *, bool);
830 static int rs6000_adjust_cost (rtx
, rtx
, rtx
, int);
831 static void rs6000_sched_init (FILE *, int, int);
832 static bool is_microcoded_insn (rtx
);
833 static bool is_nonpipeline_insn (rtx
);
834 static bool is_cracked_insn (rtx
);
835 static bool is_branch_slot_insn (rtx
);
836 static bool is_load_insn (rtx
);
837 static rtx
get_store_dest (rtx pat
);
838 static bool is_store_insn (rtx
);
839 static bool set_to_load_agen (rtx
,rtx
);
840 static bool adjacent_mem_locations (rtx
,rtx
);
841 static int rs6000_adjust_priority (rtx
, int);
842 static int rs6000_issue_rate (void);
843 static bool rs6000_is_costly_dependence (dep_t
, int, int);
844 static rtx
get_next_active_insn (rtx
, rtx
);
845 static bool insn_terminates_group_p (rtx
, enum group_termination
);
846 static bool insn_must_be_first_in_group (rtx
);
847 static bool insn_must_be_last_in_group (rtx
);
848 static bool is_costly_group (rtx
*, rtx
);
849 static int force_new_group (int, FILE *, rtx
*, rtx
, bool *, int, int *);
850 static int redefine_groups (FILE *, int, rtx
, rtx
);
851 static int pad_groups (FILE *, int, rtx
, rtx
);
852 static void rs6000_sched_finish (FILE *, int);
853 static int rs6000_sched_reorder (FILE *, int, rtx
*, int *, int);
854 static int rs6000_sched_reorder2 (FILE *, int, rtx
*, int *, int);
855 static int rs6000_use_sched_lookahead (void);
856 static int rs6000_use_sched_lookahead_guard (rtx
);
857 static void * rs6000_alloc_sched_context (void);
858 static void rs6000_init_sched_context (void *, bool);
859 static void rs6000_set_sched_context (void *);
860 static void rs6000_free_sched_context (void *);
861 static tree
rs6000_builtin_reciprocal (unsigned int, bool, bool);
862 static tree
rs6000_builtin_mask_for_load (void);
863 static tree
rs6000_builtin_mul_widen_even (tree
);
864 static tree
rs6000_builtin_mul_widen_odd (tree
);
865 static tree
rs6000_builtin_conversion (enum tree_code
, tree
);
866 static tree
rs6000_builtin_vec_perm (tree
, tree
*);
868 static void def_builtin (int, const char *, tree
, int);
869 static bool rs6000_vector_alignment_reachable (const_tree
, bool);
870 static void rs6000_init_builtins (void);
871 static rtx
rs6000_expand_unop_builtin (enum insn_code
, tree
, rtx
);
872 static rtx
rs6000_expand_binop_builtin (enum insn_code
, tree
, rtx
);
873 static rtx
rs6000_expand_ternop_builtin (enum insn_code
, tree
, rtx
);
874 static rtx
rs6000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
875 static void altivec_init_builtins (void);
876 static void rs6000_common_init_builtins (void);
877 static void rs6000_init_libfuncs (void);
879 static void paired_init_builtins (void);
880 static rtx
paired_expand_builtin (tree
, rtx
, bool *);
881 static rtx
paired_expand_lv_builtin (enum insn_code
, tree
, rtx
);
882 static rtx
paired_expand_stv_builtin (enum insn_code
, tree
);
883 static rtx
paired_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
885 static void enable_mask_for_builtins (struct builtin_description
*, int,
886 enum rs6000_builtins
,
887 enum rs6000_builtins
);
888 static void spe_init_builtins (void);
889 static rtx
spe_expand_builtin (tree
, rtx
, bool *);
890 static rtx
spe_expand_stv_builtin (enum insn_code
, tree
);
891 static rtx
spe_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
892 static rtx
spe_expand_evsel_builtin (enum insn_code
, tree
, rtx
);
893 static int rs6000_emit_int_cmove (rtx
, rtx
, rtx
, rtx
);
894 static rs6000_stack_t
*rs6000_stack_info (void);
895 static void debug_stack_info (rs6000_stack_t
*);
897 static rtx
altivec_expand_builtin (tree
, rtx
, bool *);
898 static rtx
altivec_expand_ld_builtin (tree
, rtx
, bool *);
899 static rtx
altivec_expand_st_builtin (tree
, rtx
, bool *);
900 static rtx
altivec_expand_dst_builtin (tree
, rtx
, bool *);
901 static rtx
altivec_expand_abs_builtin (enum insn_code
, tree
, rtx
);
902 static rtx
altivec_expand_predicate_builtin (enum insn_code
,
903 const char *, tree
, rtx
);
904 static rtx
altivec_expand_stv_builtin (enum insn_code
, tree
);
905 static rtx
altivec_expand_vec_init_builtin (tree
, tree
, rtx
);
906 static rtx
altivec_expand_vec_set_builtin (tree
);
907 static rtx
altivec_expand_vec_ext_builtin (tree
, rtx
);
908 static int get_element_number (tree
, tree
);
909 static bool rs6000_handle_option (size_t, const char *, int);
910 static void rs6000_parse_tls_size_option (void);
911 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
912 static int first_altivec_reg_to_save (void);
913 static unsigned int compute_vrsave_mask (void);
914 static void compute_save_world_info (rs6000_stack_t
*info_ptr
);
915 static void is_altivec_return_reg (rtx
, void *);
916 static rtx
generate_set_vrsave (rtx
, rs6000_stack_t
*, int);
917 int easy_vector_constant (rtx
, enum machine_mode
);
918 static rtx
rs6000_dwarf_register_span (rtx
);
919 static void rs6000_init_dwarf_reg_sizes_extra (tree
);
920 static rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
921 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
922 static rtx
rs6000_tls_get_addr (void);
923 static rtx
rs6000_got_sym (void);
924 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
925 static const char *rs6000_get_some_local_dynamic_name (void);
926 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
927 static rtx
rs6000_complex_function_value (enum machine_mode
);
928 static rtx
rs6000_spe_function_arg (CUMULATIVE_ARGS
*,
929 enum machine_mode
, tree
);
930 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
932 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
933 tree
, HOST_WIDE_INT
);
934 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
937 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
938 const_tree
, HOST_WIDE_INT
,
940 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, const_tree
, int, bool);
941 static rtx
rs6000_mixed_function_arg (enum machine_mode
, tree
, int);
942 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
943 static void setup_incoming_varargs (CUMULATIVE_ARGS
*,
944 enum machine_mode
, tree
,
946 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
948 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
950 static const char *invalid_arg_for_unprototyped_fn (const_tree
, const_tree
, const_tree
);
952 static void macho_branch_islands (void);
953 static int no_previous_def (tree function_name
);
954 static tree
get_prev_label (tree function_name
);
955 static void rs6000_darwin_file_start (void);
958 static tree
rs6000_build_builtin_va_list (void);
959 static void rs6000_va_start (tree
, rtx
);
960 static tree
rs6000_gimplify_va_arg (tree
, tree
, gimple_seq
*, gimple_seq
*);
961 static bool rs6000_must_pass_in_stack (enum machine_mode
, const_tree
);
962 static bool rs6000_scalar_mode_supported_p (enum machine_mode
);
963 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
964 static int get_vec_cmp_insn (enum rtx_code
, enum machine_mode
,
966 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
968 static int get_vsel_insn (enum machine_mode
);
969 static void rs6000_emit_vector_select (rtx
, rtx
, rtx
, rtx
);
970 static tree
rs6000_stack_protect_fail (void);
972 const int INSN_NOT_AVAILABLE
= -1;
973 static enum machine_mode
rs6000_eh_return_filter_mode (void);
975 /* Hash table stuff for keeping track of TOC entries. */
977 struct GTY(()) toc_hash_struct
979 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
980 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
982 enum machine_mode key_mode
;
986 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
988 /* Default register names. */
989 char rs6000_reg_names
[][8] =
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 "0", "1", "2", "3", "4", "5", "6", "7",
996 "8", "9", "10", "11", "12", "13", "14", "15",
997 "16", "17", "18", "19", "20", "21", "22", "23",
998 "24", "25", "26", "27", "28", "29", "30", "31",
999 "mq", "lr", "ctr","ap",
1000 "0", "1", "2", "3", "4", "5", "6", "7",
1002 /* AltiVec registers. */
1003 "0", "1", "2", "3", "4", "5", "6", "7",
1004 "8", "9", "10", "11", "12", "13", "14", "15",
1005 "16", "17", "18", "19", "20", "21", "22", "23",
1006 "24", "25", "26", "27", "28", "29", "30", "31",
1008 /* SPE registers. */
1009 "spe_acc", "spefscr",
1010 /* Soft frame pointer. */
1014 #ifdef TARGET_REGNAMES
1015 static const char alt_reg_names
[][8] =
1017 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1018 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1019 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1020 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1021 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1022 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1023 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1024 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1025 "mq", "lr", "ctr", "ap",
1026 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1028 /* AltiVec registers. */
1029 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1030 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1031 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1032 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1034 /* SPE registers. */
1035 "spe_acc", "spefscr",
1036 /* Soft frame pointer. */
1041 #ifndef MASK_STRICT_ALIGN
1042 #define MASK_STRICT_ALIGN 0
1044 #ifndef TARGET_PROFILE_KERNEL
1045 #define TARGET_PROFILE_KERNEL 0
1048 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1049 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1051 /* Initialize the GCC target structure. */
1052 #undef TARGET_ATTRIBUTE_TABLE
1053 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1054 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1055 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1057 #undef TARGET_ASM_ALIGNED_DI_OP
1058 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1060 /* Default unaligned ops are only provided for ELF. Find the ops needed
1061 for non-ELF systems. */
1062 #ifndef OBJECT_FORMAT_ELF
1064 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1066 #undef TARGET_ASM_UNALIGNED_HI_OP
1067 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1068 #undef TARGET_ASM_UNALIGNED_SI_OP
1069 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1070 #undef TARGET_ASM_UNALIGNED_DI_OP
1071 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1074 #undef TARGET_ASM_UNALIGNED_HI_OP
1075 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1076 #undef TARGET_ASM_UNALIGNED_SI_OP
1077 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1078 #undef TARGET_ASM_UNALIGNED_DI_OP
1079 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1080 #undef TARGET_ASM_ALIGNED_DI_OP
1081 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1085 /* This hook deals with fixups for relocatable code and DI-mode objects
1087 #undef TARGET_ASM_INTEGER
1088 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1090 #ifdef HAVE_GAS_HIDDEN
1091 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1092 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1095 #undef TARGET_HAVE_TLS
1096 #define TARGET_HAVE_TLS HAVE_AS_TLS
1098 #undef TARGET_CANNOT_FORCE_CONST_MEM
1099 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1101 #undef TARGET_ASM_FUNCTION_PROLOGUE
1102 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1103 #undef TARGET_ASM_FUNCTION_EPILOGUE
1104 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1106 #undef TARGET_SCHED_VARIABLE_ISSUE
1107 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1109 #undef TARGET_SCHED_ISSUE_RATE
1110 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1111 #undef TARGET_SCHED_ADJUST_COST
1112 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1113 #undef TARGET_SCHED_ADJUST_PRIORITY
1114 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1115 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1116 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1117 #undef TARGET_SCHED_INIT
1118 #define TARGET_SCHED_INIT rs6000_sched_init
1119 #undef TARGET_SCHED_FINISH
1120 #define TARGET_SCHED_FINISH rs6000_sched_finish
1121 #undef TARGET_SCHED_REORDER
1122 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1123 #undef TARGET_SCHED_REORDER2
1124 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1126 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1127 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1129 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1130 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1132 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1133 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1134 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1135 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1136 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1137 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1138 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1139 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1141 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1142 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1143 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1144 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1145 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1146 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1147 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1148 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1149 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1150 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1152 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1153 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1155 #undef TARGET_INIT_BUILTINS
1156 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1158 #undef TARGET_EXPAND_BUILTIN
1159 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1161 #undef TARGET_MANGLE_TYPE
1162 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1164 #undef TARGET_INIT_LIBFUNCS
1165 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1168 #undef TARGET_BINDS_LOCAL_P
1169 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1172 #undef TARGET_MS_BITFIELD_LAYOUT_P
1173 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1175 #undef TARGET_ASM_OUTPUT_MI_THUNK
1176 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1178 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1179 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1181 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1182 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1184 #undef TARGET_INVALID_WITHIN_DOLOOP
1185 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1187 #undef TARGET_RTX_COSTS
1188 #define TARGET_RTX_COSTS rs6000_rtx_costs
1189 #undef TARGET_ADDRESS_COST
1190 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1192 #undef TARGET_DWARF_REGISTER_SPAN
1193 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1195 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1196 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1198 /* On rs6000, function arguments are promoted, as are function return
1200 #undef TARGET_PROMOTE_FUNCTION_ARGS
1201 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
1202 #undef TARGET_PROMOTE_FUNCTION_RETURN
1203 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
1205 #undef TARGET_RETURN_IN_MEMORY
1206 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1208 #undef TARGET_SETUP_INCOMING_VARARGS
1209 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1211 /* Always strict argument naming on rs6000. */
1212 #undef TARGET_STRICT_ARGUMENT_NAMING
1213 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1214 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1215 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1216 #undef TARGET_SPLIT_COMPLEX_ARG
1217 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1218 #undef TARGET_MUST_PASS_IN_STACK
1219 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1220 #undef TARGET_PASS_BY_REFERENCE
1221 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1222 #undef TARGET_ARG_PARTIAL_BYTES
1223 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1225 #undef TARGET_BUILD_BUILTIN_VA_LIST
1226 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1228 #undef TARGET_EXPAND_BUILTIN_VA_START
1229 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1231 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1232 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1234 #undef TARGET_EH_RETURN_FILTER_MODE
1235 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1237 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1238 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1240 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1241 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1243 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1244 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1246 #undef TARGET_HANDLE_OPTION
1247 #define TARGET_HANDLE_OPTION rs6000_handle_option
1249 #undef TARGET_DEFAULT_TARGET_FLAGS
1250 #define TARGET_DEFAULT_TARGET_FLAGS \
1253 #undef TARGET_STACK_PROTECT_FAIL
1254 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1256 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1257 The PowerPC architecture requires only weak consistency among
1258 processors--that is, memory accesses between processors need not be
1259 sequentially consistent and memory accesses among processors can occur
1260 in any order. The ability to order memory accesses weakly provides
1261 opportunities for more efficient use of the system bus. Unless a
1262 dependency exists, the 604e allows read operations to precede store
1264 #undef TARGET_RELAXED_ORDERING
1265 #define TARGET_RELAXED_ORDERING true
1268 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1269 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1272 /* Use a 32-bit anchor range. This leads to sequences like:
1274 addis tmp,anchor,high
1277 where tmp itself acts as an anchor, and can be shared between
1278 accesses to the same 64k page. */
1279 #undef TARGET_MIN_ANCHOR_OFFSET
1280 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1281 #undef TARGET_MAX_ANCHOR_OFFSET
1282 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1283 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1284 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1286 #undef TARGET_BUILTIN_RECIPROCAL
1287 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1289 #undef TARGET_EXPAND_TO_RTL_HOOK
1290 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1292 #undef TARGET_INSTANTIATE_DECLS
1293 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1295 struct gcc_target targetm
= TARGET_INITIALIZER
;
1298 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1301 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
1303 /* The GPRs can hold any mode, but values bigger than one register
1304 cannot go past R31. */
1305 if (INT_REGNO_P (regno
))
1306 return INT_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1);
1308 /* The float registers can only hold floating modes and DImode.
1309 This excludes the 32-bit decimal float mode for now. */
1310 if (FP_REGNO_P (regno
))
1312 ((SCALAR_FLOAT_MODE_P (mode
)
1313 && (mode
!= TDmode
|| (regno
% 2) == 0)
1314 && FP_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1))
1315 || (GET_MODE_CLASS (mode
) == MODE_INT
1316 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
)
1317 || (PAIRED_SIMD_REGNO_P (regno
) && TARGET_PAIRED_FLOAT
1318 && PAIRED_VECTOR_MODE (mode
)));
1320 /* The CR register can only hold CC modes. */
1321 if (CR_REGNO_P (regno
))
1322 return GET_MODE_CLASS (mode
) == MODE_CC
;
1324 if (XER_REGNO_P (regno
))
1325 return mode
== PSImode
;
1327 /* AltiVec only in AldyVec registers. */
1328 if (ALTIVEC_REGNO_P (regno
))
1329 return ALTIVEC_VECTOR_MODE (mode
);
1331 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1332 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1335 /* We cannot put TImode anywhere except general register and it must be
1336 able to fit within the register set. */
1338 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1341 /* Initialize rs6000_hard_regno_mode_ok_p table. */
1343 rs6000_init_hard_regno_mode_ok (void)
1347 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
1348 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1349 if (rs6000_hard_regno_mode_ok (r
, (enum machine_mode
) m
))
1350 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
1354 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
1357 darwin_rs6000_override_options (void)
1359 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
1361 rs6000_altivec_abi
= 1;
1362 TARGET_ALTIVEC_VRSAVE
= 1;
1363 if (DEFAULT_ABI
== ABI_DARWIN
)
1365 if (MACHO_DYNAMIC_NO_PIC_P
)
1368 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
1371 else if (flag_pic
== 1)
1376 if (TARGET_64BIT
&& ! TARGET_POWERPC64
)
1378 target_flags
|= MASK_POWERPC64
;
1379 warning (0, "-m64 requires PowerPC64 architecture, enabling");
1383 rs6000_default_long_calls
= 1;
1384 target_flags
|= MASK_SOFT_FLOAT
;
1387 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
1389 if (!flag_mkernel
&& !flag_apple_kext
1391 && ! (target_flags_explicit
& MASK_ALTIVEC
))
1392 target_flags
|= MASK_ALTIVEC
;
1394 /* Unless the user (not the configurer) has explicitly overridden
1395 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
1396 G4 unless targetting the kernel. */
1399 && strverscmp (darwin_macosx_version_min
, "10.5") >= 0
1400 && ! (target_flags_explicit
& MASK_ALTIVEC
)
1401 && ! rs6000_select
[1].string
)
1403 target_flags
|= MASK_ALTIVEC
;
1408 /* If not otherwise specified by a target, make 'long double' equivalent to
1411 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1412 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1415 /* Override command line options. Mostly we process the processor
1416 type and sometimes adjust other TARGET_ options. */
1419 rs6000_override_options (const char *default_cpu
)
1422 struct rs6000_cpu_select
*ptr
;
1425 /* Simplifications for entries below. */
1428 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
1429 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
1432 /* This table occasionally claims that a processor does not support
1433 a particular feature even though it does, but the feature is slower
1434 than the alternative. Thus, it shouldn't be relied on as a
1435 complete description of the processor's support.
1437 Please keep this list in order, and don't forget to update the
1438 documentation in invoke.texi when adding a new processor or
1442 const char *const name
; /* Canonical processor name. */
1443 const enum processor_type processor
; /* Processor type enum value. */
1444 const int target_enable
; /* Target flags to enable. */
1445 } const processor_target_table
[]
1446 = {{"401", PROCESSOR_PPC403
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1447 {"403", PROCESSOR_PPC403
,
1448 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_STRICT_ALIGN
},
1449 {"405", PROCESSOR_PPC405
,
1450 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1451 {"405fp", PROCESSOR_PPC405
,
1452 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1453 {"440", PROCESSOR_PPC440
,
1454 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1455 {"440fp", PROCESSOR_PPC440
,
1456 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1457 {"464", PROCESSOR_PPC440
,
1458 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1459 {"464fp", PROCESSOR_PPC440
,
1460 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1461 {"505", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
},
1462 {"601", PROCESSOR_PPC601
,
1463 MASK_POWER
| POWERPC_BASE_MASK
| MASK_MULTIPLE
| MASK_STRING
},
1464 {"602", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1465 {"603", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1466 {"603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1467 {"604", PROCESSOR_PPC604
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1468 {"604e", PROCESSOR_PPC604e
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1469 {"620", PROCESSOR_PPC620
,
1470 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1471 {"630", PROCESSOR_PPC630
,
1472 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1473 {"740", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1474 {"7400", PROCESSOR_PPC7400
, POWERPC_7400_MASK
},
1475 {"7450", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1476 {"750", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1477 {"801", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1478 {"821", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1479 {"823", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1480 {"8540", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
},
1481 /* 8548 has a dummy entry for now. */
1482 {"8548", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
},
1483 {"e300c2", PROCESSOR_PPCE300C2
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1484 {"e300c3", PROCESSOR_PPCE300C3
, POWERPC_BASE_MASK
},
1485 {"e500mc", PROCESSOR_PPCE500MC
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1486 {"860", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1487 {"970", PROCESSOR_POWER4
,
1488 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1489 {"cell", PROCESSOR_CELL
,
1490 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1491 {"common", PROCESSOR_COMMON
, MASK_NEW_MNEMONICS
},
1492 {"ec603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1493 {"G3", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1494 {"G4", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1495 {"G5", PROCESSOR_POWER4
,
1496 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1497 {"power", PROCESSOR_POWER
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1498 {"power2", PROCESSOR_POWER
,
1499 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1500 {"power3", PROCESSOR_PPC630
,
1501 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1502 {"power4", PROCESSOR_POWER4
,
1503 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1505 {"power5", PROCESSOR_POWER5
,
1506 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1507 | MASK_MFCRF
| MASK_POPCNTB
},
1508 {"power5+", PROCESSOR_POWER5
,
1509 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1510 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
},
1511 {"power6", PROCESSOR_POWER6
,
1512 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1513 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
},
1514 {"power6x", PROCESSOR_POWER6
,
1515 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1516 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
1518 {"power7", PROCESSOR_POWER5
,
1519 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_MFCRF
1520 | MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
},
1521 {"powerpc", PROCESSOR_POWERPC
, POWERPC_BASE_MASK
},
1522 {"powerpc64", PROCESSOR_POWERPC64
,
1523 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1524 {"rios", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1525 {"rios1", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1526 {"rios2", PROCESSOR_RIOS2
,
1527 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1528 {"rsc", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1529 {"rsc1", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1530 {"rs64", PROCESSOR_RS64A
,
1531 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
}
1534 const size_t ptt_size
= ARRAY_SIZE (processor_target_table
);
1536 /* Some OSs don't support saving the high part of 64-bit registers on
1537 context switch. Other OSs don't support saving Altivec registers.
1538 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1539 settings; if the user wants either, the user must explicitly specify
1540 them and we won't interfere with the user's specification. */
1543 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
1544 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
| MASK_STRICT_ALIGN
1545 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
1546 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_MULHW
1547 | MASK_DLMZB
| MASK_CMPB
| MASK_MFPGPR
| MASK_DFP
)
1550 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
1551 #ifdef OS_MISSING_POWERPC64
1552 if (OS_MISSING_POWERPC64
)
1553 set_masks
&= ~MASK_POWERPC64
;
1555 #ifdef OS_MISSING_ALTIVEC
1556 if (OS_MISSING_ALTIVEC
)
1557 set_masks
&= ~MASK_ALTIVEC
;
1560 /* Don't override by the processor default if given explicitly. */
1561 set_masks
&= ~target_flags_explicit
;
1563 /* Identify the processor type. */
1564 rs6000_select
[0].string
= default_cpu
;
1565 rs6000_cpu
= TARGET_POWERPC64
? PROCESSOR_DEFAULT64
: PROCESSOR_DEFAULT
;
1567 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
1569 ptr
= &rs6000_select
[i
];
1570 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
1572 for (j
= 0; j
< ptt_size
; j
++)
1573 if (! strcmp (ptr
->string
, processor_target_table
[j
].name
))
1575 if (ptr
->set_tune_p
)
1576 rs6000_cpu
= processor_target_table
[j
].processor
;
1578 if (ptr
->set_arch_p
)
1580 target_flags
&= ~set_masks
;
1581 target_flags
|= (processor_target_table
[j
].target_enable
1588 error ("bad value (%s) for %s switch", ptr
->string
, ptr
->name
);
1592 if ((TARGET_E500
|| rs6000_cpu
== PROCESSOR_PPCE500MC
)
1593 && !rs6000_explicit_options
.isel
)
1596 if (rs6000_cpu
== PROCESSOR_PPCE300C2
|| rs6000_cpu
== PROCESSOR_PPCE300C3
1597 || rs6000_cpu
== PROCESSOR_PPCE500MC
)
1600 error ("AltiVec not supported in this target");
1602 error ("Spe not supported in this target");
1605 /* Disable Cell microcode if we are optimizing for the Cell
1606 and not optimizing for size. */
1607 if (rs6000_gen_cell_microcode
== -1)
1608 rs6000_gen_cell_microcode
= !(rs6000_cpu
== PROCESSOR_CELL
1611 /* If we are optimizing big endian systems for space, use the load/store
1612 multiple and string instructions unless we are not generating
1614 if (BYTES_BIG_ENDIAN
&& optimize_size
&& !rs6000_gen_cell_microcode
)
1615 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
1617 /* Don't allow -mmultiple or -mstring on little endian systems
1618 unless the cpu is a 750, because the hardware doesn't support the
1619 instructions used in little endian mode, and causes an alignment
1620 trap. The 750 does not cause an alignment trap (except when the
1621 target is unaligned). */
1623 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
1625 if (TARGET_MULTIPLE
)
1627 target_flags
&= ~MASK_MULTIPLE
;
1628 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
1629 warning (0, "-mmultiple is not supported on little endian systems");
1634 target_flags
&= ~MASK_STRING
;
1635 if ((target_flags_explicit
& MASK_STRING
) != 0)
1636 warning (0, "-mstring is not supported on little endian systems");
1640 /* Set debug flags */
1641 if (rs6000_debug_name
)
1643 if (! strcmp (rs6000_debug_name
, "all"))
1644 rs6000_debug_stack
= rs6000_debug_arg
= 1;
1645 else if (! strcmp (rs6000_debug_name
, "stack"))
1646 rs6000_debug_stack
= 1;
1647 else if (! strcmp (rs6000_debug_name
, "arg"))
1648 rs6000_debug_arg
= 1;
1650 error ("unknown -mdebug-%s switch", rs6000_debug_name
);
1653 if (rs6000_traceback_name
)
1655 if (! strncmp (rs6000_traceback_name
, "full", 4))
1656 rs6000_traceback
= traceback_full
;
1657 else if (! strncmp (rs6000_traceback_name
, "part", 4))
1658 rs6000_traceback
= traceback_part
;
1659 else if (! strncmp (rs6000_traceback_name
, "no", 2))
1660 rs6000_traceback
= traceback_none
;
1662 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
1663 rs6000_traceback_name
);
1666 if (!rs6000_explicit_options
.long_double
)
1667 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1669 #ifndef POWERPC_LINUX
1670 if (!rs6000_explicit_options
.ieee
)
1671 rs6000_ieeequad
= 1;
1674 /* Enable Altivec ABI for AIX -maltivec. */
1675 if (TARGET_XCOFF
&& TARGET_ALTIVEC
)
1676 rs6000_altivec_abi
= 1;
1678 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
1679 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
1680 be explicitly overridden in either case. */
1683 if (!rs6000_explicit_options
.altivec_abi
1684 && (TARGET_64BIT
|| TARGET_ALTIVEC
))
1685 rs6000_altivec_abi
= 1;
1687 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
1688 if (!rs6000_explicit_options
.vrsave
)
1689 TARGET_ALTIVEC_VRSAVE
= rs6000_altivec_abi
;
1692 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1693 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
1695 rs6000_darwin64_abi
= 1;
1697 darwin_one_byte_bool
= 1;
1699 /* Default to natural alignment, for better performance. */
1700 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
1703 /* Place FP constants in the constant pool instead of TOC
1704 if section anchors enabled. */
1705 if (flag_section_anchors
)
1706 TARGET_NO_FP_IN_TOC
= 1;
1708 /* Handle -mtls-size option. */
1709 rs6000_parse_tls_size_option ();
1711 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1712 SUBTARGET_OVERRIDE_OPTIONS
;
1714 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1715 SUBSUBTARGET_OVERRIDE_OPTIONS
;
1717 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
1718 SUB3TARGET_OVERRIDE_OPTIONS
;
1721 if (TARGET_E500
|| rs6000_cpu
== PROCESSOR_PPCE500MC
)
1723 /* The e500 and e500mc do not have string instructions, and we set
1724 MASK_STRING above when optimizing for size. */
1725 if ((target_flags
& MASK_STRING
) != 0)
1726 target_flags
= target_flags
& ~MASK_STRING
;
1728 else if (rs6000_select
[1].string
!= NULL
)
1730 /* For the powerpc-eabispe configuration, we set all these by
1731 default, so let's unset them if we manually set another
1732 CPU that is not the E500. */
1733 if (!rs6000_explicit_options
.spe_abi
)
1735 if (!rs6000_explicit_options
.spe
)
1737 if (!rs6000_explicit_options
.float_gprs
)
1738 rs6000_float_gprs
= 0;
1739 if (!rs6000_explicit_options
.isel
)
1743 /* Detect invalid option combinations with E500. */
1746 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
1747 && rs6000_cpu
!= PROCESSOR_POWER5
1748 && rs6000_cpu
!= PROCESSOR_POWER6
1749 && rs6000_cpu
!= PROCESSOR_CELL
);
1750 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
1751 || rs6000_cpu
== PROCESSOR_POWER5
);
1752 rs6000_align_branch_targets
= (rs6000_cpu
== PROCESSOR_POWER4
1753 || rs6000_cpu
== PROCESSOR_POWER5
1754 || rs6000_cpu
== PROCESSOR_POWER6
);
1756 rs6000_sched_restricted_insns_priority
1757 = (rs6000_sched_groups
? 1 : 0);
1759 /* Handle -msched-costly-dep option. */
1760 rs6000_sched_costly_dep
1761 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
1763 if (rs6000_sched_costly_dep_str
)
1765 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
1766 rs6000_sched_costly_dep
= no_dep_costly
;
1767 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
1768 rs6000_sched_costly_dep
= all_deps_costly
;
1769 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
1770 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
1771 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
1772 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
1774 rs6000_sched_costly_dep
= ((enum rs6000_dependence_cost
)
1775 atoi (rs6000_sched_costly_dep_str
));
1778 /* Handle -minsert-sched-nops option. */
1779 rs6000_sched_insert_nops
1780 = (rs6000_sched_groups
? sched_finish_regroup_exact
: sched_finish_none
);
1782 if (rs6000_sched_insert_nops_str
)
1784 if (! strcmp (rs6000_sched_insert_nops_str
, "no"))
1785 rs6000_sched_insert_nops
= sched_finish_none
;
1786 else if (! strcmp (rs6000_sched_insert_nops_str
, "pad"))
1787 rs6000_sched_insert_nops
= sched_finish_pad_groups
;
1788 else if (! strcmp (rs6000_sched_insert_nops_str
, "regroup_exact"))
1789 rs6000_sched_insert_nops
= sched_finish_regroup_exact
;
1791 rs6000_sched_insert_nops
= ((enum rs6000_nop_insertion
)
1792 atoi (rs6000_sched_insert_nops_str
));
1795 #ifdef TARGET_REGNAMES
1796 /* If the user desires alternate register names, copy in the
1797 alternate names now. */
1798 if (TARGET_REGNAMES
)
1799 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
1802 /* Set aix_struct_return last, after the ABI is determined.
1803 If -maix-struct-return or -msvr4-struct-return was explicitly
1804 used, don't override with the ABI default. */
1805 if (!rs6000_explicit_options
.aix_struct_ret
)
1806 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
1808 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
1809 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
1812 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
1814 /* We can only guarantee the availability of DI pseudo-ops when
1815 assembling for 64-bit targets. */
1818 targetm
.asm_out
.aligned_op
.di
= NULL
;
1819 targetm
.asm_out
.unaligned_op
.di
= NULL
;
1822 /* Set branch target alignment, if not optimizing for size. */
1825 /* Cell wants to be aligned 8byte for dual issue. */
1826 if (rs6000_cpu
== PROCESSOR_CELL
)
1828 if (align_functions
<= 0)
1829 align_functions
= 8;
1830 if (align_jumps
<= 0)
1832 if (align_loops
<= 0)
1835 if (rs6000_align_branch_targets
)
1837 if (align_functions
<= 0)
1838 align_functions
= 16;
1839 if (align_jumps
<= 0)
1841 if (align_loops
<= 0)
1844 if (align_jumps_max_skip
<= 0)
1845 align_jumps_max_skip
= 15;
1846 if (align_loops_max_skip
<= 0)
1847 align_loops_max_skip
= 15;
1850 /* Arrange to save and restore machine status around nested functions. */
1851 init_machine_status
= rs6000_init_machine_status
;
1853 /* We should always be splitting complex arguments, but we can't break
1854 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1855 if (DEFAULT_ABI
!= ABI_AIX
)
1856 targetm
.calls
.split_complex_arg
= NULL
;
1858 /* Initialize rs6000_cost with the appropriate target costs. */
1860 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
1864 case PROCESSOR_RIOS1
:
1865 rs6000_cost
= &rios1_cost
;
1868 case PROCESSOR_RIOS2
:
1869 rs6000_cost
= &rios2_cost
;
1872 case PROCESSOR_RS64A
:
1873 rs6000_cost
= &rs64a_cost
;
1876 case PROCESSOR_MPCCORE
:
1877 rs6000_cost
= &mpccore_cost
;
1880 case PROCESSOR_PPC403
:
1881 rs6000_cost
= &ppc403_cost
;
1884 case PROCESSOR_PPC405
:
1885 rs6000_cost
= &ppc405_cost
;
1888 case PROCESSOR_PPC440
:
1889 rs6000_cost
= &ppc440_cost
;
1892 case PROCESSOR_PPC601
:
1893 rs6000_cost
= &ppc601_cost
;
1896 case PROCESSOR_PPC603
:
1897 rs6000_cost
= &ppc603_cost
;
1900 case PROCESSOR_PPC604
:
1901 rs6000_cost
= &ppc604_cost
;
1904 case PROCESSOR_PPC604e
:
1905 rs6000_cost
= &ppc604e_cost
;
1908 case PROCESSOR_PPC620
:
1909 rs6000_cost
= &ppc620_cost
;
1912 case PROCESSOR_PPC630
:
1913 rs6000_cost
= &ppc630_cost
;
1916 case PROCESSOR_CELL
:
1917 rs6000_cost
= &ppccell_cost
;
1920 case PROCESSOR_PPC750
:
1921 case PROCESSOR_PPC7400
:
1922 rs6000_cost
= &ppc750_cost
;
1925 case PROCESSOR_PPC7450
:
1926 rs6000_cost
= &ppc7450_cost
;
1929 case PROCESSOR_PPC8540
:
1930 rs6000_cost
= &ppc8540_cost
;
1933 case PROCESSOR_PPCE300C2
:
1934 case PROCESSOR_PPCE300C3
:
1935 rs6000_cost
= &ppce300c2c3_cost
;
1938 case PROCESSOR_PPCE500MC
:
1939 rs6000_cost
= &ppce500mc_cost
;
1942 case PROCESSOR_POWER4
:
1943 case PROCESSOR_POWER5
:
1944 rs6000_cost
= &power4_cost
;
1947 case PROCESSOR_POWER6
:
1948 rs6000_cost
= &power6_cost
;
1955 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES
))
1956 set_param_value ("simultaneous-prefetches",
1957 rs6000_cost
->simultaneous_prefetches
);
1958 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE
))
1959 set_param_value ("l1-cache-size", rs6000_cost
->l1_cache_size
);
1960 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE
))
1961 set_param_value ("l1-cache-line-size", rs6000_cost
->cache_line_size
);
1962 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE
))
1963 set_param_value ("l2-cache-size", rs6000_cost
->l2_cache_size
);
1965 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
1966 can be optimized to ap = __builtin_next_arg (0). */
1967 if (DEFAULT_ABI
!= ABI_V4
)
1968 targetm
.expand_builtin_va_start
= NULL
;
1970 /* Set up single/double float flags.
1971 If TARGET_HARD_FLOAT is set, but neither single or double is set,
1972 then set both flags. */
1973 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
1974 && rs6000_single_float
== 0 && rs6000_double_float
== 0)
1975 rs6000_single_float
= rs6000_double_float
= 1;
1977 /* Reset single and double FP flags if target is E500. */
1980 rs6000_single_float
= rs6000_double_float
= 0;
1981 if (TARGET_E500_SINGLE
)
1982 rs6000_single_float
= 1;
1983 if (TARGET_E500_DOUBLE
)
1984 rs6000_single_float
= rs6000_double_float
= 1;
1987 /* If not explicitly specified via option, decide whether to generate indexed
1988 load/store instructions. */
1989 if (TARGET_AVOID_XFORM
== -1)
1990 /* Avoid indexed addressing when targeting Power6 in order to avoid
1991 the DERAT mispredict penalty. */
1992 TARGET_AVOID_XFORM
= (rs6000_cpu
== PROCESSOR_POWER6
&& TARGET_CMPB
);
1994 rs6000_init_hard_regno_mode_ok ();
1997 /* Implement targetm.vectorize.builtin_mask_for_load. */
1999 rs6000_builtin_mask_for_load (void)
2002 return altivec_builtin_mask_for_load
;
2007 /* Implement targetm.vectorize.builtin_conversion.
2008 Returns a decl of a function that implements conversion of an integer vector
2009 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2010 side of the conversion.
2011 Return NULL_TREE if it is not available. */
2013 rs6000_builtin_conversion (enum tree_code code
, tree type
)
2015 if (!TARGET_ALTIVEC
)
2020 case FIX_TRUNC_EXPR
:
2021 switch (TYPE_MODE (type
))
2024 return TYPE_UNSIGNED (type
)
2025 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCTUXS
]
2026 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCTSXS
];
2032 switch (TYPE_MODE (type
))
2035 return TYPE_UNSIGNED (type
)
2036 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCFUX
]
2037 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCFSX
];
2047 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2049 rs6000_builtin_mul_widen_even (tree type
)
2051 if (!TARGET_ALTIVEC
)
2054 switch (TYPE_MODE (type
))
2057 return TYPE_UNSIGNED (type
)
2058 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUH
]
2059 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESH
];
2062 return TYPE_UNSIGNED (type
)
2063 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUB
]
2064 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESB
];
2070 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2072 rs6000_builtin_mul_widen_odd (tree type
)
2074 if (!TARGET_ALTIVEC
)
2077 switch (TYPE_MODE (type
))
2080 return TYPE_UNSIGNED (type
)
2081 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUH
]
2082 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSH
];
2085 return TYPE_UNSIGNED (type
)
2086 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUB
]
2087 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSB
];
2094 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2095 after applying N number of iterations. This routine does not determine
2096 how may iterations are required to reach desired alignment. */
2099 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED
, bool is_packed
)
2106 if (rs6000_alignment_flags
== MASK_ALIGN_NATURAL
)
2109 if (rs6000_alignment_flags
== MASK_ALIGN_POWER
)
2119 /* Assuming that all other types are naturally aligned. CHECKME! */
2124 /* Implement targetm.vectorize.builtin_vec_perm. */
2126 rs6000_builtin_vec_perm (tree type
, tree
*mask_element_type
)
2130 *mask_element_type
= unsigned_char_type_node
;
2132 switch (TYPE_MODE (type
))
2135 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_16QI
];
2139 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_8HI
];
2143 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SI
];
2147 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SF
];
2158 /* Handle generic options of the form -mfoo=yes/no.
2159 NAME is the option name.
2160 VALUE is the option value.
2161 FLAG is the pointer to the flag where to store a 1 or 0, depending on
2162 whether the option value is 'yes' or 'no' respectively. */
2164 rs6000_parse_yes_no_option (const char *name
, const char *value
, int *flag
)
2168 else if (!strcmp (value
, "yes"))
2170 else if (!strcmp (value
, "no"))
2173 error ("unknown -m%s= option specified: '%s'", name
, value
);
2176 /* Validate and record the size specified with the -mtls-size option. */
2179 rs6000_parse_tls_size_option (void)
2181 if (rs6000_tls_size_string
== 0)
2183 else if (strcmp (rs6000_tls_size_string
, "16") == 0)
2184 rs6000_tls_size
= 16;
2185 else if (strcmp (rs6000_tls_size_string
, "32") == 0)
2186 rs6000_tls_size
= 32;
2187 else if (strcmp (rs6000_tls_size_string
, "64") == 0)
2188 rs6000_tls_size
= 64;
2190 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string
);
2194 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
2196 if (DEFAULT_ABI
== ABI_DARWIN
)
2197 /* The Darwin libraries never set errno, so we might as well
2198 avoid calling them when that's the only reason we would. */
2199 flag_errno_math
= 0;
2201 /* Double growth factor to counter reduced min jump length. */
2202 set_param_value ("max-grow-copy-bb-insns", 16);
2204 /* Enable section anchors by default.
2205 Skip section anchors for Objective C and Objective C++
2206 until front-ends fixed. */
2207 if (!TARGET_MACHO
&& lang_hooks
.name
[4] != 'O')
2208 flag_section_anchors
= 2;
2211 static enum fpu_type_t
2212 rs6000_parse_fpu_option (const char *option
)
2214 if (!strcmp("none", option
)) return FPU_NONE
;
2215 if (!strcmp("sp_lite", option
)) return FPU_SF_LITE
;
2216 if (!strcmp("dp_lite", option
)) return FPU_DF_LITE
;
2217 if (!strcmp("sp_full", option
)) return FPU_SF_FULL
;
2218 if (!strcmp("dp_full", option
)) return FPU_DF_FULL
;
2219 error("unknown value %s for -mfpu", option
);
2223 /* Implement TARGET_HANDLE_OPTION. */
2226 rs6000_handle_option (size_t code
, const char *arg
, int value
)
2228 enum fpu_type_t fpu_type
= FPU_NONE
;
2233 target_flags
&= ~(MASK_POWER
| MASK_POWER2
2234 | MASK_MULTIPLE
| MASK_STRING
);
2235 target_flags_explicit
|= (MASK_POWER
| MASK_POWER2
2236 | MASK_MULTIPLE
| MASK_STRING
);
2238 case OPT_mno_powerpc
:
2239 target_flags
&= ~(MASK_POWERPC
| MASK_PPC_GPOPT
2240 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
2241 target_flags_explicit
|= (MASK_POWERPC
| MASK_PPC_GPOPT
2242 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
2245 target_flags
&= ~MASK_MINIMAL_TOC
;
2246 TARGET_NO_FP_IN_TOC
= 0;
2247 TARGET_NO_SUM_IN_TOC
= 0;
2248 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2249 #ifdef TARGET_USES_SYSV4_OPT
2250 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
2251 just the same as -mminimal-toc. */
2252 target_flags
|= MASK_MINIMAL_TOC
;
2253 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2257 #ifdef TARGET_USES_SYSV4_OPT
2259 /* Make -mtoc behave like -mminimal-toc. */
2260 target_flags
|= MASK_MINIMAL_TOC
;
2261 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2265 #ifdef TARGET_USES_AIX64_OPT
2270 target_flags
|= MASK_POWERPC64
| MASK_POWERPC
;
2271 target_flags
|= ~target_flags_explicit
& MASK_PPC_GFXOPT
;
2272 target_flags_explicit
|= MASK_POWERPC64
| MASK_POWERPC
;
2275 #ifdef TARGET_USES_AIX64_OPT
2280 target_flags
&= ~MASK_POWERPC64
;
2281 target_flags_explicit
|= MASK_POWERPC64
;
2284 case OPT_minsert_sched_nops_
:
2285 rs6000_sched_insert_nops_str
= arg
;
2288 case OPT_mminimal_toc
:
2291 TARGET_NO_FP_IN_TOC
= 0;
2292 TARGET_NO_SUM_IN_TOC
= 0;
2299 target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
2300 target_flags_explicit
|= (MASK_MULTIPLE
| MASK_STRING
);
2307 target_flags
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
2308 target_flags_explicit
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
2312 case OPT_mpowerpc_gpopt
:
2313 case OPT_mpowerpc_gfxopt
:
2316 target_flags
|= MASK_POWERPC
;
2317 target_flags_explicit
|= MASK_POWERPC
;
2321 case OPT_maix_struct_return
:
2322 case OPT_msvr4_struct_return
:
2323 rs6000_explicit_options
.aix_struct_ret
= true;
2327 rs6000_explicit_options
.vrsave
= true;
2328 TARGET_ALTIVEC_VRSAVE
= value
;
2332 rs6000_explicit_options
.vrsave
= true;
2333 rs6000_parse_yes_no_option ("vrsave", arg
, &(TARGET_ALTIVEC_VRSAVE
));
2337 rs6000_explicit_options
.isel
= true;
2338 rs6000_isel
= value
;
2342 rs6000_explicit_options
.isel
= true;
2343 rs6000_parse_yes_no_option ("isel", arg
, &(rs6000_isel
));
2347 rs6000_explicit_options
.spe
= true;
2352 rs6000_explicit_options
.spe
= true;
2353 rs6000_parse_yes_no_option ("spe", arg
, &(rs6000_spe
));
2357 rs6000_debug_name
= arg
;
2360 #ifdef TARGET_USES_SYSV4_OPT
2362 rs6000_abi_name
= arg
;
2366 rs6000_sdata_name
= arg
;
2369 case OPT_mtls_size_
:
2370 rs6000_tls_size_string
= arg
;
2373 case OPT_mrelocatable
:
2376 target_flags
|= MASK_MINIMAL_TOC
;
2377 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2378 TARGET_NO_FP_IN_TOC
= 1;
2382 case OPT_mrelocatable_lib
:
2385 target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
2386 target_flags_explicit
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
2387 TARGET_NO_FP_IN_TOC
= 1;
2391 target_flags
&= ~MASK_RELOCATABLE
;
2392 target_flags_explicit
|= MASK_RELOCATABLE
;
2398 if (!strcmp (arg
, "altivec"))
2400 rs6000_explicit_options
.altivec_abi
= true;
2401 rs6000_altivec_abi
= 1;
2403 /* Enabling the AltiVec ABI turns off the SPE ABI. */
2406 else if (! strcmp (arg
, "no-altivec"))
2408 rs6000_explicit_options
.altivec_abi
= true;
2409 rs6000_altivec_abi
= 0;
2411 else if (! strcmp (arg
, "spe"))
2413 rs6000_explicit_options
.spe_abi
= true;
2415 rs6000_altivec_abi
= 0;
2416 if (!TARGET_SPE_ABI
)
2417 error ("not configured for ABI: '%s'", arg
);
2419 else if (! strcmp (arg
, "no-spe"))
2421 rs6000_explicit_options
.spe_abi
= true;
2425 /* These are here for testing during development only, do not
2426 document in the manual please. */
2427 else if (! strcmp (arg
, "d64"))
2429 rs6000_darwin64_abi
= 1;
2430 warning (0, "Using darwin64 ABI");
2432 else if (! strcmp (arg
, "d32"))
2434 rs6000_darwin64_abi
= 0;
2435 warning (0, "Using old darwin ABI");
2438 else if (! strcmp (arg
, "ibmlongdouble"))
2440 rs6000_explicit_options
.ieee
= true;
2441 rs6000_ieeequad
= 0;
2442 warning (0, "Using IBM extended precision long double");
2444 else if (! strcmp (arg
, "ieeelongdouble"))
2446 rs6000_explicit_options
.ieee
= true;
2447 rs6000_ieeequad
= 1;
2448 warning (0, "Using IEEE extended precision long double");
2453 error ("unknown ABI specified: '%s'", arg
);
2459 rs6000_select
[1].string
= arg
;
2463 rs6000_select
[2].string
= arg
;
2466 case OPT_mtraceback_
:
2467 rs6000_traceback_name
= arg
;
2470 case OPT_mfloat_gprs_
:
2471 rs6000_explicit_options
.float_gprs
= true;
2472 if (! strcmp (arg
, "yes") || ! strcmp (arg
, "single"))
2473 rs6000_float_gprs
= 1;
2474 else if (! strcmp (arg
, "double"))
2475 rs6000_float_gprs
= 2;
2476 else if (! strcmp (arg
, "no"))
2477 rs6000_float_gprs
= 0;
2480 error ("invalid option for -mfloat-gprs: '%s'", arg
);
2485 case OPT_mlong_double_
:
2486 rs6000_explicit_options
.long_double
= true;
2487 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2488 if (value
!= 64 && value
!= 128)
2490 error ("Unknown switch -mlong-double-%s", arg
);
2491 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2495 rs6000_long_double_type_size
= value
;
2498 case OPT_msched_costly_dep_
:
2499 rs6000_sched_costly_dep_str
= arg
;
2503 rs6000_explicit_options
.alignment
= true;
2504 if (! strcmp (arg
, "power"))
2506 /* On 64-bit Darwin, power alignment is ABI-incompatible with
2507 some C library functions, so warn about it. The flag may be
2508 useful for performance studies from time to time though, so
2509 don't disable it entirely. */
2510 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
2511 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2512 " it is incompatible with the installed C and C++ libraries");
2513 rs6000_alignment_flags
= MASK_ALIGN_POWER
;
2515 else if (! strcmp (arg
, "natural"))
2516 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
2519 error ("unknown -malign-XXXXX option specified: '%s'", arg
);
2524 case OPT_msingle_float
:
2525 if (!TARGET_SINGLE_FPU
)
2526 warning (0, "-msingle-float option equivalent to -mhard-float");
2527 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
2528 rs6000_double_float
= 0;
2529 target_flags
&= ~MASK_SOFT_FLOAT
;
2530 target_flags_explicit
|= MASK_SOFT_FLOAT
;
2533 case OPT_mdouble_float
:
2534 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
2535 rs6000_single_float
= 1;
2536 target_flags
&= ~MASK_SOFT_FLOAT
;
2537 target_flags_explicit
|= MASK_SOFT_FLOAT
;
2540 case OPT_msimple_fpu
:
2541 if (!TARGET_SINGLE_FPU
)
2542 warning (0, "-msimple-fpu option ignored");
2545 case OPT_mhard_float
:
2546 /* -mhard_float implies -msingle-float and -mdouble-float. */
2547 rs6000_single_float
= rs6000_double_float
= 1;
2550 case OPT_msoft_float
:
2551 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
2552 rs6000_single_float
= rs6000_double_float
= 0;
2556 fpu_type
= rs6000_parse_fpu_option(arg
);
2557 if (fpu_type
!= FPU_NONE
)
2558 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
2560 target_flags
&= ~MASK_SOFT_FLOAT
;
2561 target_flags_explicit
|= MASK_SOFT_FLOAT
;
2562 rs6000_xilinx_fpu
= 1;
2563 if (fpu_type
== FPU_SF_LITE
|| fpu_type
== FPU_SF_FULL
)
2564 rs6000_single_float
= 1;
2565 if (fpu_type
== FPU_DF_LITE
|| fpu_type
== FPU_DF_FULL
)
2566 rs6000_single_float
= rs6000_double_float
= 1;
2567 if (fpu_type
== FPU_SF_LITE
|| fpu_type
== FPU_DF_LITE
)
2568 rs6000_simple_fpu
= 1;
2572 /* -mfpu=none is equivalent to -msoft-float */
2573 target_flags
|= MASK_SOFT_FLOAT
;
2574 target_flags_explicit
|= MASK_SOFT_FLOAT
;
2575 rs6000_single_float
= rs6000_double_float
= 0;
2582 /* Do anything needed at the start of the asm file. */
2585 rs6000_file_start (void)
2589 const char *start
= buffer
;
2590 struct rs6000_cpu_select
*ptr
;
2591 const char *default_cpu
= TARGET_CPU_DEFAULT
;
2592 FILE *file
= asm_out_file
;
2594 default_file_start ();
2596 #ifdef TARGET_BI_ARCH
2597 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
2601 if (flag_verbose_asm
)
2603 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
2604 rs6000_select
[0].string
= default_cpu
;
2606 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
2608 ptr
= &rs6000_select
[i
];
2609 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
2611 fprintf (file
, "%s %s%s", start
, ptr
->name
, ptr
->string
);
2616 if (PPC405_ERRATUM77
)
2618 fprintf (file
, "%s PPC405CR_ERRATUM77", start
);
2622 #ifdef USING_ELFOS_H
2623 switch (rs6000_sdata
)
2625 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
2626 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
2627 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
2628 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
2631 if (rs6000_sdata
&& g_switch_value
)
2633 fprintf (file
, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED
, start
,
2643 #ifdef HAVE_AS_GNU_ATTRIBUTE
2644 if (TARGET_32BIT
&& DEFAULT_ABI
== ABI_V4
)
2646 fprintf (file
, "\t.gnu_attribute 4, %d\n",
2647 ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
) ? 1
2648 : (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_SINGLE_FLOAT
) ? 3
2650 fprintf (file
, "\t.gnu_attribute 8, %d\n",
2651 (TARGET_ALTIVEC_ABI
? 2
2652 : TARGET_SPE_ABI
? 3
2654 fprintf (file
, "\t.gnu_attribute 12, %d\n",
2655 aix_struct_return
? 2 : 1);
2660 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
2662 switch_to_section (toc_section
);
2663 switch_to_section (text_section
);
2668 /* Return nonzero if this function is known to have a null epilogue. */
2671 direct_return (void)
2673 if (reload_completed
)
2675 rs6000_stack_t
*info
= rs6000_stack_info ();
2677 if (info
->first_gp_reg_save
== 32
2678 && info
->first_fp_reg_save
== 64
2679 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
2680 && ! info
->lr_save_p
2681 && ! info
->cr_save_p
2682 && info
->vrsave_mask
== 0
2690 /* Return the number of instructions it takes to form a constant in an
2691 integer register. */
2694 num_insns_constant_wide (HOST_WIDE_INT value
)
2696 /* signed constant loadable with {cal|addi} */
2697 if ((unsigned HOST_WIDE_INT
) (value
+ 0x8000) < 0x10000)
2700 /* constant loadable with {cau|addis} */
2701 else if ((value
& 0xffff) == 0
2702 && (value
>> 31 == -1 || value
>> 31 == 0))
2705 #if HOST_BITS_PER_WIDE_INT == 64
2706 else if (TARGET_POWERPC64
)
2708 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
2709 HOST_WIDE_INT high
= value
>> 31;
2711 if (high
== 0 || high
== -1)
2717 return num_insns_constant_wide (high
) + 1;
2719 return (num_insns_constant_wide (high
)
2720 + num_insns_constant_wide (low
) + 1);
2729 num_insns_constant (rtx op
, enum machine_mode mode
)
2731 HOST_WIDE_INT low
, high
;
2733 switch (GET_CODE (op
))
2736 #if HOST_BITS_PER_WIDE_INT == 64
2737 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
2738 && mask64_operand (op
, mode
))
2742 return num_insns_constant_wide (INTVAL (op
));
2745 if (mode
== SFmode
|| mode
== SDmode
)
2750 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2751 if (DECIMAL_FLOAT_MODE_P (mode
))
2752 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
2754 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
2755 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
2758 if (mode
== VOIDmode
|| mode
== DImode
)
2760 high
= CONST_DOUBLE_HIGH (op
);
2761 low
= CONST_DOUBLE_LOW (op
);
2768 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2769 if (DECIMAL_FLOAT_MODE_P (mode
))
2770 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, l
);
2772 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
2773 high
= l
[WORDS_BIG_ENDIAN
== 0];
2774 low
= l
[WORDS_BIG_ENDIAN
!= 0];
2778 return (num_insns_constant_wide (low
)
2779 + num_insns_constant_wide (high
));
2782 if ((high
== 0 && low
>= 0)
2783 || (high
== -1 && low
< 0))
2784 return num_insns_constant_wide (low
);
2786 else if (mask64_operand (op
, mode
))
2790 return num_insns_constant_wide (high
) + 1;
2793 return (num_insns_constant_wide (high
)
2794 + num_insns_constant_wide (low
) + 1);
2802 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
2803 If the mode of OP is MODE_VECTOR_INT, this simply returns the
2804 corresponding element of the vector, but for V4SFmode and V2SFmode,
2805 the corresponding "float" is interpreted as an SImode integer. */
2808 const_vector_elt_as_int (rtx op
, unsigned int elt
)
2810 rtx tmp
= CONST_VECTOR_ELT (op
, elt
);
2811 if (GET_MODE (op
) == V4SFmode
2812 || GET_MODE (op
) == V2SFmode
)
2813 tmp
= gen_lowpart (SImode
, tmp
);
2814 return INTVAL (tmp
);
2817 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
2818 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2819 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2820 all items are set to the same value and contain COPIES replicas of the
2821 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2822 operand and the others are set to the value of the operand's msb. */
2825 vspltis_constant (rtx op
, unsigned step
, unsigned copies
)
2827 enum machine_mode mode
= GET_MODE (op
);
2828 enum machine_mode inner
= GET_MODE_INNER (mode
);
2831 unsigned nunits
= GET_MODE_NUNITS (mode
);
2832 unsigned bitsize
= GET_MODE_BITSIZE (inner
);
2833 unsigned mask
= GET_MODE_MASK (inner
);
2835 HOST_WIDE_INT val
= const_vector_elt_as_int (op
, nunits
- 1);
2836 HOST_WIDE_INT splat_val
= val
;
2837 HOST_WIDE_INT msb_val
= val
> 0 ? 0 : -1;
2839 /* Construct the value to be splatted, if possible. If not, return 0. */
2840 for (i
= 2; i
<= copies
; i
*= 2)
2842 HOST_WIDE_INT small_val
;
2844 small_val
= splat_val
>> bitsize
;
2846 if (splat_val
!= ((small_val
<< bitsize
) | (small_val
& mask
)))
2848 splat_val
= small_val
;
2851 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2852 if (EASY_VECTOR_15 (splat_val
))
2855 /* Also check if we can splat, and then add the result to itself. Do so if
2856 the value is positive, of if the splat instruction is using OP's mode;
2857 for splat_val < 0, the splat and the add should use the same mode. */
2858 else if (EASY_VECTOR_15_ADD_SELF (splat_val
)
2859 && (splat_val
>= 0 || (step
== 1 && copies
== 1)))
2865 /* Check if VAL is present in every STEP-th element, and the
2866 other elements are filled with its most significant bit. */
2867 for (i
= 0; i
< nunits
- 1; ++i
)
2869 HOST_WIDE_INT desired_val
;
2870 if (((i
+ 1) & (step
- 1)) == 0)
2873 desired_val
= msb_val
;
2875 if (desired_val
!= const_vector_elt_as_int (op
, i
))
2883 /* Return true if OP is of the given MODE and can be synthesized
2884 with a vspltisb, vspltish or vspltisw. */
2887 easy_altivec_constant (rtx op
, enum machine_mode mode
)
2889 unsigned step
, copies
;
2891 if (mode
== VOIDmode
)
2892 mode
= GET_MODE (op
);
2893 else if (mode
!= GET_MODE (op
))
2896 /* Start with a vspltisw. */
2897 step
= GET_MODE_NUNITS (mode
) / 4;
2900 if (vspltis_constant (op
, step
, copies
))
2903 /* Then try with a vspltish. */
2909 if (vspltis_constant (op
, step
, copies
))
2912 /* And finally a vspltisb. */
2918 if (vspltis_constant (op
, step
, copies
))
2924 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2925 result is OP. Abort if it is not possible. */
2928 gen_easy_altivec_constant (rtx op
)
2930 enum machine_mode mode
= GET_MODE (op
);
2931 int nunits
= GET_MODE_NUNITS (mode
);
2932 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
2933 unsigned step
= nunits
/ 4;
2934 unsigned copies
= 1;
2936 /* Start with a vspltisw. */
2937 if (vspltis_constant (op
, step
, copies
))
2938 return gen_rtx_VEC_DUPLICATE (V4SImode
, gen_lowpart (SImode
, last
));
2940 /* Then try with a vspltish. */
2946 if (vspltis_constant (op
, step
, copies
))
2947 return gen_rtx_VEC_DUPLICATE (V8HImode
, gen_lowpart (HImode
, last
));
2949 /* And finally a vspltisb. */
2955 if (vspltis_constant (op
, step
, copies
))
2956 return gen_rtx_VEC_DUPLICATE (V16QImode
, gen_lowpart (QImode
, last
));
2962 output_vec_const_move (rtx
*operands
)
2965 enum machine_mode mode
;
2970 mode
= GET_MODE (dest
);
2975 if (zero_constant (vec
, mode
))
2976 return "vxor %0,%0,%0";
2978 splat_vec
= gen_easy_altivec_constant (vec
);
2979 gcc_assert (GET_CODE (splat_vec
) == VEC_DUPLICATE
);
2980 operands
[1] = XEXP (splat_vec
, 0);
2981 if (!EASY_VECTOR_15 (INTVAL (operands
[1])))
2984 switch (GET_MODE (splat_vec
))
2987 return "vspltisw %0,%1";
2990 return "vspltish %0,%1";
2993 return "vspltisb %0,%1";
3000 gcc_assert (TARGET_SPE
);
3002 /* Vector constant 0 is handled as a splitter of V2SI, and in the
3003 pattern of V1DI, V4HI, and V2SF.
3005 FIXME: We should probably return # and add post reload
3006 splitters for these, but this way is so easy ;-). */
3007 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
3008 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
3009 operands
[1] = CONST_VECTOR_ELT (vec
, 0);
3010 operands
[2] = CONST_VECTOR_ELT (vec
, 1);
3012 return "li %0,%1\n\tevmergelo %0,%0,%0";
3014 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
3017 /* Initialize TARGET of vector PAIRED to VALS. */
3020 paired_expand_vector_init (rtx target
, rtx vals
)
3022 enum machine_mode mode
= GET_MODE (target
);
3023 int n_elts
= GET_MODE_NUNITS (mode
);
3025 rtx x
, new_rtx
, tmp
, constant_op
, op1
, op2
;
3028 for (i
= 0; i
< n_elts
; ++i
)
3030 x
= XVECEXP (vals
, 0, i
);
3031 if (!CONSTANT_P (x
))
3036 /* Load from constant pool. */
3037 emit_move_insn (target
, gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0)));
3043 /* The vector is initialized only with non-constants. */
3044 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, XVECEXP (vals
, 0, 0),
3045 XVECEXP (vals
, 0, 1));
3047 emit_move_insn (target
, new_rtx
);
3051 /* One field is non-constant and the other one is a constant. Load the
3052 constant from the constant pool and use ps_merge instruction to
3053 construct the whole vector. */
3054 op1
= XVECEXP (vals
, 0, 0);
3055 op2
= XVECEXP (vals
, 0, 1);
3057 constant_op
= (CONSTANT_P (op1
)) ? op1
: op2
;
3059 tmp
= gen_reg_rtx (GET_MODE (constant_op
));
3060 emit_move_insn (tmp
, constant_op
);
3062 if (CONSTANT_P (op1
))
3063 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, tmp
, op2
);
3065 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, op1
, tmp
);
3067 emit_move_insn (target
, new_rtx
);
3071 paired_expand_vector_move (rtx operands
[])
3073 rtx op0
= operands
[0], op1
= operands
[1];
3075 emit_move_insn (op0
, op1
);
3078 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
3079 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
3080 operands for the relation operation COND. This is a recursive
3084 paired_emit_vector_compare (enum rtx_code rcode
,
3085 rtx dest
, rtx op0
, rtx op1
,
3086 rtx cc_op0
, rtx cc_op1
)
3088 rtx tmp
= gen_reg_rtx (V2SFmode
);
3089 rtx tmp1
, max
, min
, equal_zero
;
3091 gcc_assert (TARGET_PAIRED_FLOAT
);
3092 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
3098 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3102 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
3103 emit_insn (gen_selv2sf4 (dest
, tmp
, op0
, op1
, CONST0_RTX (SFmode
)));
3107 paired_emit_vector_compare (GE
, dest
, op0
, op1
, cc_op1
, cc_op0
);
3110 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3113 tmp1
= gen_reg_rtx (V2SFmode
);
3114 max
= gen_reg_rtx (V2SFmode
);
3115 min
= gen_reg_rtx (V2SFmode
);
3116 equal_zero
= gen_reg_rtx (V2SFmode
);
3118 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
3119 emit_insn (gen_selv2sf4
3120 (max
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
3121 emit_insn (gen_subv2sf3 (tmp
, cc_op1
, cc_op0
));
3122 emit_insn (gen_selv2sf4
3123 (min
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
3124 emit_insn (gen_subv2sf3 (tmp1
, min
, max
));
3125 emit_insn (gen_selv2sf4 (dest
, tmp1
, op0
, op1
, CONST0_RTX (SFmode
)));
3128 paired_emit_vector_compare (EQ
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3131 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3134 paired_emit_vector_compare (LT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3137 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3140 paired_emit_vector_compare (GT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3149 /* Emit vector conditional expression.
3150 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
3151 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
3154 paired_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
3155 rtx cond
, rtx cc_op0
, rtx cc_op1
)
3157 enum rtx_code rcode
= GET_CODE (cond
);
3159 if (!TARGET_PAIRED_FLOAT
)
3162 paired_emit_vector_compare (rcode
, dest
, op1
, op2
, cc_op0
, cc_op1
);
3167 /* Initialize vector TARGET to VALS. */
3170 rs6000_expand_vector_init (rtx target
, rtx vals
)
3172 enum machine_mode mode
= GET_MODE (target
);
3173 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
3174 int n_elts
= GET_MODE_NUNITS (mode
);
3175 int n_var
= 0, one_var
= -1;
3176 bool all_same
= true, all_const_zero
= true;
3180 for (i
= 0; i
< n_elts
; ++i
)
3182 x
= XVECEXP (vals
, 0, i
);
3183 if (!CONSTANT_P (x
))
3184 ++n_var
, one_var
= i
;
3185 else if (x
!= CONST0_RTX (inner_mode
))
3186 all_const_zero
= false;
3188 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
3194 rtx const_vec
= gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0));
3195 if (mode
!= V4SFmode
&& all_const_zero
)
3197 /* Zero register. */
3198 emit_insn (gen_rtx_SET (VOIDmode
, target
,
3199 gen_rtx_XOR (mode
, target
, target
)));
3202 else if (mode
!= V4SFmode
&& easy_vector_constant (const_vec
, mode
))
3204 /* Splat immediate. */
3205 emit_insn (gen_rtx_SET (VOIDmode
, target
, const_vec
));
3209 ; /* Splat vector element. */
3212 /* Load from constant pool. */
3213 emit_move_insn (target
, const_vec
);
3218 /* Store value to stack temp. Load vector element. Splat. */
3221 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
3222 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0),
3223 XVECEXP (vals
, 0, 0));
3224 x
= gen_rtx_UNSPEC (VOIDmode
,
3225 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
3226 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3228 gen_rtx_SET (VOIDmode
,
3231 x
= gen_rtx_VEC_SELECT (inner_mode
, target
,
3232 gen_rtx_PARALLEL (VOIDmode
,
3233 gen_rtvec (1, const0_rtx
)));
3234 emit_insn (gen_rtx_SET (VOIDmode
, target
,
3235 gen_rtx_VEC_DUPLICATE (mode
, x
)));
3239 /* One field is non-constant. Load constant then overwrite
3243 rtx copy
= copy_rtx (vals
);
3245 /* Load constant part of vector, substitute neighboring value for
3247 XVECEXP (copy
, 0, one_var
) = XVECEXP (vals
, 0, (one_var
+ 1) % n_elts
);
3248 rs6000_expand_vector_init (target
, copy
);
3250 /* Insert variable. */
3251 rs6000_expand_vector_set (target
, XVECEXP (vals
, 0, one_var
), one_var
);
3255 /* Construct the vector in memory one field at a time
3256 and load the whole vector. */
3257 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
3258 for (i
= 0; i
< n_elts
; i
++)
3259 emit_move_insn (adjust_address_nv (mem
, inner_mode
,
3260 i
* GET_MODE_SIZE (inner_mode
)),
3261 XVECEXP (vals
, 0, i
));
3262 emit_move_insn (target
, mem
);
3265 /* Set field ELT of TARGET to VAL. */
3268 rs6000_expand_vector_set (rtx target
, rtx val
, int elt
)
3270 enum machine_mode mode
= GET_MODE (target
);
3271 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
3272 rtx reg
= gen_reg_rtx (mode
);
3274 int width
= GET_MODE_SIZE (inner_mode
);
3277 /* Load single variable value. */
3278 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
3279 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0), val
);
3280 x
= gen_rtx_UNSPEC (VOIDmode
,
3281 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
3282 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3284 gen_rtx_SET (VOIDmode
,
3288 /* Linear sequence. */
3289 mask
= gen_rtx_PARALLEL (V16QImode
, rtvec_alloc (16));
3290 for (i
= 0; i
< 16; ++i
)
3291 XVECEXP (mask
, 0, i
) = GEN_INT (i
);
3293 /* Set permute mask to insert element into target. */
3294 for (i
= 0; i
< width
; ++i
)
3295 XVECEXP (mask
, 0, elt
*width
+ i
)
3296 = GEN_INT (i
+ 0x10);
3297 x
= gen_rtx_CONST_VECTOR (V16QImode
, XVEC (mask
, 0));
3298 x
= gen_rtx_UNSPEC (mode
,
3299 gen_rtvec (3, target
, reg
,
3300 force_reg (V16QImode
, x
)),
3302 emit_insn (gen_rtx_SET (VOIDmode
, target
, x
));
3305 /* Extract field ELT from VEC into TARGET. */
3308 rs6000_expand_vector_extract (rtx target
, rtx vec
, int elt
)
3310 enum machine_mode mode
= GET_MODE (vec
);
3311 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
3314 /* Allocate mode-sized buffer. */
3315 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
3317 /* Add offset to field within buffer matching vector element. */
3318 mem
= adjust_address_nv (mem
, mode
, elt
* GET_MODE_SIZE (inner_mode
));
3320 /* Store single field into mode-sized buffer. */
3321 x
= gen_rtx_UNSPEC (VOIDmode
,
3322 gen_rtvec (1, const0_rtx
), UNSPEC_STVE
);
3323 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3325 gen_rtx_SET (VOIDmode
,
3328 emit_move_insn (target
, adjust_address_nv (mem
, inner_mode
, 0));
3331 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
3332 implement ANDing by the mask IN. */
3334 build_mask64_2_operands (rtx in
, rtx
*out
)
3336 #if HOST_BITS_PER_WIDE_INT >= 64
3337 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
3340 gcc_assert (GET_CODE (in
) == CONST_INT
);
3345 /* Assume c initially something like 0x00fff000000fffff. The idea
3346 is to rotate the word so that the middle ^^^^^^ group of zeros
3347 is at the MS end and can be cleared with an rldicl mask. We then
3348 rotate back and clear off the MS ^^ group of zeros with a
3350 c
= ~c
; /* c == 0xff000ffffff00000 */
3351 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
3352 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
3353 c
= ~c
; /* c == 0x00fff000000fffff */
3354 c
&= -lsb
; /* c == 0x00fff00000000000 */
3355 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
3356 c
= ~c
; /* c == 0xff000fffffffffff */
3357 c
&= -lsb
; /* c == 0xff00000000000000 */
3359 while ((lsb
>>= 1) != 0)
3360 shift
++; /* shift == 44 on exit from loop */
3361 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
3362 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
3363 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
3367 /* Assume c initially something like 0xff000f0000000000. The idea
3368 is to rotate the word so that the ^^^ middle group of zeros
3369 is at the LS end and can be cleared with an rldicr mask. We then
3370 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
3372 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
3373 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
3374 c
= ~c
; /* c == 0x00fff0ffffffffff */
3375 c
&= -lsb
; /* c == 0x00fff00000000000 */
3376 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
3377 c
= ~c
; /* c == 0xff000fffffffffff */
3378 c
&= -lsb
; /* c == 0xff00000000000000 */
3380 while ((lsb
>>= 1) != 0)
3381 shift
++; /* shift == 44 on exit from loop */
3382 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
3383 m1
>>= shift
; /* m1 == 0x0000000000000fff */
3384 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
3387 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
3388 masks will be all 1's. We are guaranteed more than one transition. */
3389 out
[0] = GEN_INT (64 - shift
);
3390 out
[1] = GEN_INT (m1
);
3391 out
[2] = GEN_INT (shift
);
3392 out
[3] = GEN_INT (m2
);
3400 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
3403 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
3405 if (TARGET_E500_DOUBLE
)
3407 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
3408 subreg:TI and reg:TF. Decimal float modes are like integer
3409 modes (only low part of each register used) for this
3411 if (GET_CODE (op
) == SUBREG
3412 && (mode
== SImode
|| mode
== DImode
|| mode
== TImode
3413 || mode
== DDmode
|| mode
== TDmode
)
3414 && REG_P (SUBREG_REG (op
))
3415 && (GET_MODE (SUBREG_REG (op
)) == DFmode
3416 || GET_MODE (SUBREG_REG (op
)) == TFmode
))
3419 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
3421 if (GET_CODE (op
) == SUBREG
3422 && (mode
== DFmode
|| mode
== TFmode
)
3423 && REG_P (SUBREG_REG (op
))
3424 && (GET_MODE (SUBREG_REG (op
)) == DImode
3425 || GET_MODE (SUBREG_REG (op
)) == TImode
3426 || GET_MODE (SUBREG_REG (op
)) == DDmode
3427 || GET_MODE (SUBREG_REG (op
)) == TDmode
))
3432 && GET_CODE (op
) == SUBREG
3434 && REG_P (SUBREG_REG (op
))
3435 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op
))))
3441 /* AIX increases natural record alignment to doubleword if the first
3442 field is an FP double while the FP fields remain word aligned. */
3445 rs6000_special_round_type_align (tree type
, unsigned int computed
,
3446 unsigned int specified
)
3448 unsigned int align
= MAX (computed
, specified
);
3449 tree field
= TYPE_FIELDS (type
);
3451 /* Skip all non field decls */
3452 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
3453 field
= TREE_CHAIN (field
);
3455 if (field
!= NULL
&& field
!= type
)
3457 type
= TREE_TYPE (field
);
3458 while (TREE_CODE (type
) == ARRAY_TYPE
)
3459 type
= TREE_TYPE (type
);
3461 if (type
!= error_mark_node
&& TYPE_MODE (type
) == DFmode
)
3462 align
= MAX (align
, 64);
3468 /* Darwin increases record alignment to the natural alignment of
3472 darwin_rs6000_special_round_type_align (tree type
, unsigned int computed
,
3473 unsigned int specified
)
3475 unsigned int align
= MAX (computed
, specified
);
3477 if (TYPE_PACKED (type
))
3480 /* Find the first field, looking down into aggregates. */
3482 tree field
= TYPE_FIELDS (type
);
3483 /* Skip all non field decls */
3484 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
3485 field
= TREE_CHAIN (field
);
3488 type
= TREE_TYPE (field
);
3489 while (TREE_CODE (type
) == ARRAY_TYPE
)
3490 type
= TREE_TYPE (type
);
3491 } while (AGGREGATE_TYPE_P (type
));
3493 if (! AGGREGATE_TYPE_P (type
) && type
!= error_mark_node
)
3494 align
= MAX (align
, TYPE_ALIGN (type
));
3499 /* Return 1 for an operand in small memory on V.4/eabi. */
3502 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
3503 enum machine_mode mode ATTRIBUTE_UNUSED
)
3508 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
3511 if (DEFAULT_ABI
!= ABI_V4
)
3514 /* Vector and float memory instructions have a limited offset on the
3515 SPE, so using a vector or float variable directly as an operand is
3518 && (SPE_VECTOR_MODE (mode
) || FLOAT_MODE_P (mode
)))
3521 if (GET_CODE (op
) == SYMBOL_REF
)
3524 else if (GET_CODE (op
) != CONST
3525 || GET_CODE (XEXP (op
, 0)) != PLUS
3526 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
3527 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
3532 rtx sum
= XEXP (op
, 0);
3533 HOST_WIDE_INT summand
;
3535 /* We have to be careful here, because it is the referenced address
3536 that must be 32k from _SDA_BASE_, not just the symbol. */
3537 summand
= INTVAL (XEXP (sum
, 1));
3538 if (summand
< 0 || (unsigned HOST_WIDE_INT
) summand
> g_switch_value
)
3541 sym_ref
= XEXP (sum
, 0);
3544 return SYMBOL_REF_SMALL_P (sym_ref
);
3550 /* Return true if either operand is a general purpose register. */
3553 gpr_or_gpr_p (rtx op0
, rtx op1
)
3555 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
3556 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
3560 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
3563 constant_pool_expr_p (rtx op
)
3567 split_const (op
, &base
, &offset
);
3568 return (GET_CODE (base
) == SYMBOL_REF
3569 && CONSTANT_POOL_ADDRESS_P (base
)
3570 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base
), Pmode
));
3574 toc_relative_expr_p (rtx op
)
3578 if (GET_CODE (op
) != CONST
)
3581 split_const (op
, &base
, &offset
);
3582 return (GET_CODE (base
) == UNSPEC
3583 && XINT (base
, 1) == UNSPEC_TOCREL
);
3587 legitimate_constant_pool_address_p (rtx x
)
3590 && GET_CODE (x
) == PLUS
3591 && GET_CODE (XEXP (x
, 0)) == REG
3592 && (TARGET_MINIMAL_TOC
|| REGNO (XEXP (x
, 0)) == TOC_REGISTER
)
3593 && toc_relative_expr_p (XEXP (x
, 1)));
3597 legitimate_small_data_p (enum machine_mode mode
, rtx x
)
3599 return (DEFAULT_ABI
== ABI_V4
3600 && !flag_pic
&& !TARGET_TOC
3601 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
3602 && small_data_operand (x
, mode
));
3605 /* SPE offset addressing is limited to 5-bits worth of double words. */
3606 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
3609 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
3611 unsigned HOST_WIDE_INT offset
, extra
;
3613 if (GET_CODE (x
) != PLUS
)
3615 if (GET_CODE (XEXP (x
, 0)) != REG
)
3617 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
3619 if (legitimate_constant_pool_address_p (x
))
3621 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
3624 offset
= INTVAL (XEXP (x
, 1));
3632 /* AltiVec vector modes. Only reg+reg addressing is valid and
3633 constant offset zero should not occur due to canonicalization. */
3640 /* Paired vector modes. Only reg+reg addressing is valid and
3641 constant offset zero should not occur due to canonicalization. */
3642 if (TARGET_PAIRED_FLOAT
)
3644 /* SPE vector modes. */
3645 return SPE_CONST_OFFSET_OK (offset
);
3648 if (TARGET_E500_DOUBLE
)
3649 return SPE_CONST_OFFSET_OK (offset
);
3653 /* On e500v2, we may have:
3655 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
3657 Which gets addressed with evldd instructions. */
3658 if (TARGET_E500_DOUBLE
)
3659 return SPE_CONST_OFFSET_OK (offset
);
3661 if (mode
== DFmode
|| mode
== DDmode
|| !TARGET_POWERPC64
)
3663 else if (offset
& 3)
3668 if (TARGET_E500_DOUBLE
)
3669 return (SPE_CONST_OFFSET_OK (offset
)
3670 && SPE_CONST_OFFSET_OK (offset
+ 8));
3674 if (mode
== TFmode
|| mode
== TDmode
|| !TARGET_POWERPC64
)
3676 else if (offset
& 3)
3687 return (offset
< 0x10000) && (offset
+ extra
< 0x10000);
3691 legitimate_indexed_address_p (rtx x
, int strict
)
3695 if (GET_CODE (x
) != PLUS
)
3701 /* Recognize the rtl generated by reload which we know will later be
3702 replaced with proper base and index regs. */
3704 && reload_in_progress
3705 && (REG_P (op0
) || GET_CODE (op0
) == PLUS
)
3709 return (REG_P (op0
) && REG_P (op1
)
3710 && ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
3711 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
3712 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
3713 && INT_REG_OK_FOR_INDEX_P (op0
, strict
))));
3717 avoiding_indexed_address_p (enum machine_mode mode
)
3719 /* Avoid indexed addressing for modes that have non-indexed
3720 load/store instruction forms. */
3721 return TARGET_AVOID_XFORM
&& !ALTIVEC_VECTOR_MODE (mode
);
3725 legitimate_indirect_address_p (rtx x
, int strict
)
3727 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
3731 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
3733 if (!TARGET_MACHO
|| !flag_pic
3734 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
3738 if (GET_CODE (x
) != LO_SUM
)
3740 if (GET_CODE (XEXP (x
, 0)) != REG
)
3742 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
3746 return CONSTANT_P (x
);
3750 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
3752 if (GET_CODE (x
) != LO_SUM
)
3754 if (GET_CODE (XEXP (x
, 0)) != REG
)
3756 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
3758 /* Restrict addressing for DI because of our SUBREG hackery. */
3759 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3760 || mode
== DDmode
|| mode
== TDmode
3765 if (TARGET_ELF
|| TARGET_MACHO
)
3767 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
3771 if (GET_MODE_NUNITS (mode
) != 1)
3773 if (GET_MODE_BITSIZE (mode
) > 64
3774 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
3775 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
3776 && (mode
== DFmode
|| mode
== DDmode
))))
3779 return CONSTANT_P (x
);
3786 /* Try machine-dependent ways of modifying an illegitimate address
3787 to be legitimate. If we find one, return the new, valid address.
3788 This is used from only one place: `memory_address' in explow.c.
3790 OLDX is the address as it was before break_out_memory_refs was
3791 called. In some cases it is useful to look at this to decide what
3794 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
3796 It is always safe for this function to do nothing. It exists to
3797 recognize opportunities to optimize the output.
3799 On RS/6000, first check for the sum of a register with a constant
3800 integer that is out of range. If so, generate code to add the
3801 constant with the low-order 16 bits masked to the register and force
3802 this result into another register (this can be done with `cau').
3803 Then generate an address of REG+(CONST&0xffff), allowing for the
3804 possibility of bit 16 being a one.
3806 Then check for the sum of a register and something not constant, try to
3807 load the other things into a register and return the sum. */
3810 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3811 enum machine_mode mode
)
3813 if (GET_CODE (x
) == SYMBOL_REF
)
3815 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
3817 return rs6000_legitimize_tls_address (x
, model
);
3820 if (GET_CODE (x
) == PLUS
3821 && GET_CODE (XEXP (x
, 0)) == REG
3822 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3823 && (unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000) >= 0x10000
3824 && !((TARGET_POWERPC64
3825 && (mode
== DImode
|| mode
== TImode
)
3826 && (INTVAL (XEXP (x
, 1)) & 3) != 0)
3827 || SPE_VECTOR_MODE (mode
)
3828 || ALTIVEC_VECTOR_MODE (mode
)
3829 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3830 || mode
== DImode
|| mode
== DDmode
3831 || mode
== TDmode
))))
3833 HOST_WIDE_INT high_int
, low_int
;
3835 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
3836 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
3837 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
3838 GEN_INT (high_int
)), 0);
3839 return gen_rtx_PLUS (Pmode
, sum
, GEN_INT (low_int
));
3841 else if (GET_CODE (x
) == PLUS
3842 && GET_CODE (XEXP (x
, 0)) == REG
3843 && GET_CODE (XEXP (x
, 1)) != CONST_INT
3844 && GET_MODE_NUNITS (mode
) == 1
3845 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
3847 || ((mode
!= DImode
&& mode
!= DFmode
&& mode
!= DDmode
)
3848 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
)))
3849 && (TARGET_POWERPC64
|| mode
!= DImode
)
3850 && !avoiding_indexed_address_p (mode
)
3855 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
3856 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
3858 else if (ALTIVEC_VECTOR_MODE (mode
))
3862 /* Make sure both operands are registers. */
3863 if (GET_CODE (x
) == PLUS
)
3864 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, XEXP (x
, 0)),
3865 force_reg (Pmode
, XEXP (x
, 1)));
3867 reg
= force_reg (Pmode
, x
);
3870 else if (SPE_VECTOR_MODE (mode
)
3871 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3872 || mode
== DDmode
|| mode
== TDmode
3873 || mode
== DImode
)))
3877 /* We accept [reg + reg] and [reg + OFFSET]. */
3879 if (GET_CODE (x
) == PLUS
)
3881 rtx op1
= XEXP (x
, 0);
3882 rtx op2
= XEXP (x
, 1);
3885 op1
= force_reg (Pmode
, op1
);
3887 if (GET_CODE (op2
) != REG
3888 && (GET_CODE (op2
) != CONST_INT
3889 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))
3890 || (GET_MODE_SIZE (mode
) > 8
3891 && !SPE_CONST_OFFSET_OK (INTVAL (op2
) + 8))))
3892 op2
= force_reg (Pmode
, op2
);
3894 /* We can't always do [reg + reg] for these, because [reg +
3895 reg + offset] is not a legitimate addressing mode. */
3896 y
= gen_rtx_PLUS (Pmode
, op1
, op2
);
3898 if ((GET_MODE_SIZE (mode
) > 8 || mode
== DDmode
) && REG_P (op2
))
3899 return force_reg (Pmode
, y
);
3904 return force_reg (Pmode
, x
);
3910 && GET_CODE (x
) != CONST_INT
3911 && GET_CODE (x
) != CONST_DOUBLE
3913 && GET_MODE_NUNITS (mode
) == 1
3914 && (GET_MODE_BITSIZE (mode
) <= 32
3915 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
3916 && (mode
== DFmode
|| mode
== DDmode
))))
3918 rtx reg
= gen_reg_rtx (Pmode
);
3919 emit_insn (gen_elf_high (reg
, x
));
3920 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
3922 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
3925 && ! MACHO_DYNAMIC_NO_PIC_P
3927 && GET_CODE (x
) != CONST_INT
3928 && GET_CODE (x
) != CONST_DOUBLE
3930 && GET_MODE_NUNITS (mode
) == 1
3931 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
3932 || (mode
!= DFmode
&& mode
!= DDmode
))
3936 rtx reg
= gen_reg_rtx (Pmode
);
3937 emit_insn (gen_macho_high (reg
, x
));
3938 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
3941 && GET_CODE (x
) == SYMBOL_REF
3942 && constant_pool_expr_p (x
)
3943 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
3945 return create_TOC_reference (x
);
3951 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
3952 We need to emit DTP-relative relocations. */
3955 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
3960 fputs ("\t.long\t", file
);
3963 fputs (DOUBLE_INT_ASM_OP
, file
);
3968 output_addr_const (file
, x
);
3969 fputs ("@dtprel+0x8000", file
);
3972 /* Construct the SYMBOL_REF for the tls_get_addr function. */
3974 static GTY(()) rtx rs6000_tls_symbol
;
3976 rs6000_tls_get_addr (void)
3978 if (!rs6000_tls_symbol
)
3979 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
3981 return rs6000_tls_symbol
;
3984 /* Construct the SYMBOL_REF for TLS GOT references. */
3986 static GTY(()) rtx rs6000_got_symbol
;
3988 rs6000_got_sym (void)
3990 if (!rs6000_got_symbol
)
3992 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
3993 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
3994 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
3997 return rs6000_got_symbol
;
4000 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
4001 this (thread-local) address. */
4004 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
4008 dest
= gen_reg_rtx (Pmode
);
4009 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
4015 tlsreg
= gen_rtx_REG (Pmode
, 13);
4016 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
4020 tlsreg
= gen_rtx_REG (Pmode
, 2);
4021 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
4025 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
4029 tmp
= gen_reg_rtx (Pmode
);
4032 tlsreg
= gen_rtx_REG (Pmode
, 13);
4033 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
4037 tlsreg
= gen_rtx_REG (Pmode
, 2);
4038 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
4042 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
4044 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
4049 rtx r3
, got
, tga
, tmp1
, tmp2
, eqv
;
4051 /* We currently use relocations like @got@tlsgd for tls, which
4052 means the linker will handle allocation of tls entries, placing
4053 them in the .got section. So use a pointer to the .got section,
4054 not one to secondary TOC sections used by 64-bit -mminimal-toc,
4055 or to secondary GOT sections used by 32-bit -fPIC. */
4057 got
= gen_rtx_REG (Pmode
, 2);
4061 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
4064 rtx gsym
= rs6000_got_sym ();
4065 got
= gen_reg_rtx (Pmode
);
4067 rs6000_emit_move (got
, gsym
, Pmode
);
4073 tmp1
= gen_reg_rtx (Pmode
);
4074 tmp2
= gen_reg_rtx (Pmode
);
4075 tmp3
= gen_reg_rtx (Pmode
);
4076 mem
= gen_const_mem (Pmode
, tmp1
);
4078 first
= emit_insn (gen_load_toc_v4_PIC_1b (gsym
));
4079 emit_move_insn (tmp1
,
4080 gen_rtx_REG (Pmode
, LR_REGNO
));
4081 emit_move_insn (tmp2
, mem
);
4082 emit_insn (gen_addsi3 (tmp3
, tmp1
, tmp2
));
4083 last
= emit_move_insn (got
, tmp3
);
4084 set_unique_reg_note (last
, REG_EQUAL
, gsym
);
4089 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
4091 r3
= gen_rtx_REG (Pmode
, 3);
4092 tga
= rs6000_tls_get_addr ();
4094 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
4095 insn
= gen_tls_gd_aix64 (r3
, got
, addr
, tga
, const0_rtx
);
4096 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
4097 insn
= gen_tls_gd_aix32 (r3
, got
, addr
, tga
, const0_rtx
);
4098 else if (DEFAULT_ABI
== ABI_V4
)
4099 insn
= gen_tls_gd_sysvsi (r3
, got
, addr
, tga
, const0_rtx
);
4104 insn
= emit_call_insn (insn
);
4105 RTL_CONST_CALL_P (insn
) = 1;
4106 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
4107 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
4108 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
4109 insn
= get_insns ();
4111 emit_libcall_block (insn
, dest
, r3
, addr
);
4113 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
4115 r3
= gen_rtx_REG (Pmode
, 3);
4116 tga
= rs6000_tls_get_addr ();
4118 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
4119 insn
= gen_tls_ld_aix64 (r3
, got
, tga
, const0_rtx
);
4120 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
4121 insn
= gen_tls_ld_aix32 (r3
, got
, tga
, const0_rtx
);
4122 else if (DEFAULT_ABI
== ABI_V4
)
4123 insn
= gen_tls_ld_sysvsi (r3
, got
, tga
, const0_rtx
);
4128 insn
= emit_call_insn (insn
);
4129 RTL_CONST_CALL_P (insn
) = 1;
4130 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
4131 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
4132 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
4133 insn
= get_insns ();
4135 tmp1
= gen_reg_rtx (Pmode
);
4136 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
),
4138 emit_libcall_block (insn
, tmp1
, r3
, eqv
);
4139 if (rs6000_tls_size
== 16)
4142 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
4144 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
4146 else if (rs6000_tls_size
== 32)
4148 tmp2
= gen_reg_rtx (Pmode
);
4150 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
4152 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
4155 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
4157 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
4161 tmp2
= gen_reg_rtx (Pmode
);
4163 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
4165 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
4167 insn
= gen_rtx_SET (Pmode
, dest
,
4168 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
4174 /* IE, or 64-bit offset LE. */
4175 tmp2
= gen_reg_rtx (Pmode
);
4177 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
4179 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
4182 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
4184 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
4192 /* Return 1 if X contains a thread-local symbol. */
4195 rs6000_tls_referenced_p (rtx x
)
4197 if (! TARGET_HAVE_TLS
)
4200 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
4203 /* Return 1 if *X is a thread-local symbol. This is the same as
4204 rs6000_tls_symbol_ref except for the type of the unused argument. */
4207 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
4209 return RS6000_SYMBOL_REF_TLS_P (*x
);
4212 /* The convention appears to be to define this wherever it is used.
4213 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
4214 is now used here. */
4215 #ifndef REG_MODE_OK_FOR_BASE_P
4216 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
4219 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
4220 replace the input X, or the original X if no replacement is called for.
4221 The output parameter *WIN is 1 if the calling macro should goto WIN,
4224 For RS/6000, we wish to handle large displacements off a base
4225 register by splitting the addend across an addiu/addis and the mem insn.
4226 This cuts number of extra insns needed from 3 to 1.
4228 On Darwin, we use this to generate code for floating point constants.
4229 A movsf_low is generated so we wind up with 2 instructions rather than 3.
4230 The Darwin code is inside #if TARGET_MACHO because only then are the
4231 machopic_* functions defined. */
4233 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
4234 int opnum
, int type
,
4235 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
4237 /* We must recognize output that we have already generated ourselves. */
4238 if (GET_CODE (x
) == PLUS
4239 && GET_CODE (XEXP (x
, 0)) == PLUS
4240 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
4241 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
4242 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
4244 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4245 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
4246 opnum
, (enum reload_type
)type
);
4252 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
4253 && GET_CODE (x
) == LO_SUM
4254 && GET_CODE (XEXP (x
, 0)) == PLUS
4255 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
4256 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
4257 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
4258 && machopic_operand_p (XEXP (x
, 1)))
4260 /* Result of previous invocation of this function on Darwin
4261 floating point constant. */
4262 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4263 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
4264 opnum
, (enum reload_type
)type
);
4270 /* Force ld/std non-word aligned offset into base register by wrapping
4272 if (GET_CODE (x
) == PLUS
4273 && GET_CODE (XEXP (x
, 0)) == REG
4274 && REGNO (XEXP (x
, 0)) < 32
4275 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
4276 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4277 && (INTVAL (XEXP (x
, 1)) & 3) != 0
4278 && !ALTIVEC_VECTOR_MODE (mode
)
4279 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
4280 && TARGET_POWERPC64
)
4282 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
4283 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4284 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
4285 opnum
, (enum reload_type
) type
);
4290 if (GET_CODE (x
) == PLUS
4291 && GET_CODE (XEXP (x
, 0)) == REG
4292 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
4293 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
4294 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4295 && !SPE_VECTOR_MODE (mode
)
4296 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
4297 || mode
== DDmode
|| mode
== TDmode
4299 && !ALTIVEC_VECTOR_MODE (mode
))
4301 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
4302 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
4304 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
4306 /* Check for 32-bit overflow. */
4307 if (high
+ low
!= val
)
4313 /* Reload the high part into a base reg; leave the low part
4314 in the mem directly. */
4316 x
= gen_rtx_PLUS (GET_MODE (x
),
4317 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
4321 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4322 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
4323 opnum
, (enum reload_type
)type
);
4328 if (GET_CODE (x
) == SYMBOL_REF
4329 && !ALTIVEC_VECTOR_MODE (mode
)
4330 && !SPE_VECTOR_MODE (mode
)
4332 && DEFAULT_ABI
== ABI_DARWIN
4333 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
4335 && DEFAULT_ABI
== ABI_V4
4338 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
4339 The same goes for DImode without 64-bit gprs and DFmode and DDmode
4343 && (mode
!= DImode
|| TARGET_POWERPC64
)
4344 && ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_POWERPC64
4345 || (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)))
4350 rtx offset
= machopic_gen_offset (x
);
4351 x
= gen_rtx_LO_SUM (GET_MODE (x
),
4352 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
4353 gen_rtx_HIGH (Pmode
, offset
)), offset
);
4357 x
= gen_rtx_LO_SUM (GET_MODE (x
),
4358 gen_rtx_HIGH (Pmode
, x
), x
);
4360 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4361 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
4362 opnum
, (enum reload_type
)type
);
4367 /* Reload an offset address wrapped by an AND that represents the
4368 masking of the lower bits. Strip the outer AND and let reload
4369 convert the offset address into an indirect address. */
4371 && ALTIVEC_VECTOR_MODE (mode
)
4372 && GET_CODE (x
) == AND
4373 && GET_CODE (XEXP (x
, 0)) == PLUS
4374 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
4375 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
4376 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4377 && INTVAL (XEXP (x
, 1)) == -16)
4385 && GET_CODE (x
) == SYMBOL_REF
4386 && constant_pool_expr_p (x
)
4387 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
4389 x
= create_TOC_reference (x
);
4397 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
4398 that is a valid memory address for an instruction.
4399 The MODE argument is the machine mode for the MEM expression
4400 that wants to use this address.
4402 On the RS/6000, there are four valid address: a SYMBOL_REF that
4403 refers to a constant pool entry of an address (or the sum of it
4404 plus a constant), a short (16-bit signed) constant plus a register,
4405 the sum of two registers, or a register indirect, possibly with an
4406 auto-increment. For DFmode, DDmode and DImode with a constant plus
4407 register, we must ensure that both words are addressable or PowerPC64
4408 with offset word aligned.
4410 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
4411 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
4412 because adjacent memory cells are accessed by adding word-sized offsets
4413 during assembly output. */
4415 rs6000_legitimate_address (enum machine_mode mode
, rtx x
, int reg_ok_strict
)
4417 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
4419 && ALTIVEC_VECTOR_MODE (mode
)
4420 && GET_CODE (x
) == AND
4421 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4422 && INTVAL (XEXP (x
, 1)) == -16)
4425 if (RS6000_SYMBOL_REF_TLS_P (x
))
4427 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
4429 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
4430 && !ALTIVEC_VECTOR_MODE (mode
)
4431 && !SPE_VECTOR_MODE (mode
)
4434 /* Restrict addressing for DI because of our SUBREG hackery. */
4435 && !(TARGET_E500_DOUBLE
4436 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
4438 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
4440 if (legitimate_small_data_p (mode
, x
))
4442 if (legitimate_constant_pool_address_p (x
))
4444 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
4446 && GET_CODE (x
) == PLUS
4447 && GET_CODE (XEXP (x
, 0)) == REG
4448 && (XEXP (x
, 0) == virtual_stack_vars_rtx
4449 || XEXP (x
, 0) == arg_pointer_rtx
)
4450 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
4452 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
4457 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
4459 || (mode
!= DFmode
&& mode
!= DDmode
)
4460 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
))
4461 && (TARGET_POWERPC64
|| mode
!= DImode
)
4462 && !avoiding_indexed_address_p (mode
)
4463 && legitimate_indexed_address_p (x
, reg_ok_strict
))
4465 if (GET_CODE (x
) == PRE_MODIFY
4469 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
4471 || ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_E500_DOUBLE
))
4472 && (TARGET_POWERPC64
|| mode
!= DImode
)
4473 && !ALTIVEC_VECTOR_MODE (mode
)
4474 && !SPE_VECTOR_MODE (mode
)
4475 /* Restrict addressing for DI because of our SUBREG hackery. */
4476 && !(TARGET_E500_DOUBLE
4477 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
4479 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
)
4480 && (rs6000_legitimate_offset_address_p (mode
, XEXP (x
, 1), reg_ok_strict
)
4481 || (!avoiding_indexed_address_p (mode
)
4482 && legitimate_indexed_address_p (XEXP (x
, 1), reg_ok_strict
)))
4483 && rtx_equal_p (XEXP (XEXP (x
, 1), 0), XEXP (x
, 0)))
4485 if (legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
4490 /* Go to LABEL if ADDR (a legitimate address expression)
4491 has an effect that depends on the machine mode it is used for.
4493 On the RS/6000 this is true of all integral offsets (since AltiVec
4494 modes don't allow them) or is a pre-increment or decrement.
4496 ??? Except that due to conceptual problems in offsettable_address_p
4497 we can't really report the problems of integral offsets. So leave
4498 this assuming that the adjustable offset must be valid for the
4499 sub-words of a TFmode operand, which is what we had before. */
4502 rs6000_mode_dependent_address (rtx addr
)
4504 switch (GET_CODE (addr
))
4507 if (GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
4509 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
4510 return val
+ 12 + 0x8000 >= 0x10000;
4517 /* Auto-increment cases are now treated generically in recog.c. */
4519 return TARGET_UPDATE
;
4528 /* Implement FIND_BASE_TERM. */
4531 rs6000_find_base_term (rtx op
)
4535 split_const (op
, &base
, &offset
);
4536 if (GET_CODE (base
) == UNSPEC
)
4537 switch (XINT (base
, 1))
4540 case UNSPEC_MACHOPIC_OFFSET
:
4541 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
4542 for aliasing purposes. */
4543 return XVECEXP (base
, 0, 0);
4549 /* More elaborate version of recog's offsettable_memref_p predicate
4550 that works around the ??? note of rs6000_mode_dependent_address.
4551 In particular it accepts
4553 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
4555 in 32-bit mode, that the recog predicate rejects. */
4558 rs6000_offsettable_memref_p (rtx op
)
4563 /* First mimic offsettable_memref_p. */
4564 if (offsettable_address_p (1, GET_MODE (op
), XEXP (op
, 0)))
4567 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
4568 the latter predicate knows nothing about the mode of the memory
4569 reference and, therefore, assumes that it is the largest supported
4570 mode (TFmode). As a consequence, legitimate offsettable memory
4571 references are rejected. rs6000_legitimate_offset_address_p contains
4572 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
4573 return rs6000_legitimate_offset_address_p (GET_MODE (op
), XEXP (op
, 0), 1);
4576 /* Return number of consecutive hard regs needed starting at reg REGNO
4577 to hold something of mode MODE.
4578 This is ordinarily the length in words of a value of mode MODE
4579 but can be less for certain modes in special long registers.
4581 For the SPE, GPRs are 64 bits but only 32 bits are visible in
4582 scalar instructions. The upper 32 bits are only available to the
4585 POWER and PowerPC GPRs hold 32 bits worth;
4586 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
4589 rs6000_hard_regno_nregs (int regno
, enum machine_mode mode
)
4591 if (FP_REGNO_P (regno
))
4592 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
4594 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
4595 return (GET_MODE_SIZE (mode
) + UNITS_PER_SPE_WORD
- 1) / UNITS_PER_SPE_WORD
;
4597 if (ALTIVEC_REGNO_P (regno
))
4599 (GET_MODE_SIZE (mode
) + UNITS_PER_ALTIVEC_WORD
- 1) / UNITS_PER_ALTIVEC_WORD
;
4601 /* The value returned for SCmode in the E500 double case is 2 for
4602 ABI compatibility; storing an SCmode value in a single register
4603 would require function_arg and rs6000_spe_function_arg to handle
4604 SCmode so as to pass the value correctly in a pair of
4606 if (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
) && mode
!= SCmode
4607 && !DECIMAL_FLOAT_MODE_P (mode
))
4608 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
4610 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
4613 /* Change register usage conditional on target flags. */
4615 rs6000_conditional_register_usage (void)
4619 /* Set MQ register fixed (already call_used) if not POWER
4620 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
4625 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
4627 fixed_regs
[13] = call_used_regs
[13]
4628 = call_really_used_regs
[13] = 1;
4630 /* Conditionally disable FPRs. */
4631 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
4632 for (i
= 32; i
< 64; i
++)
4633 fixed_regs
[i
] = call_used_regs
[i
]
4634 = call_really_used_regs
[i
] = 1;
4636 /* The TOC register is not killed across calls in a way that is
4637 visible to the compiler. */
4638 if (DEFAULT_ABI
== ABI_AIX
)
4639 call_really_used_regs
[2] = 0;
4641 if (DEFAULT_ABI
== ABI_V4
4642 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
4644 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4646 if (DEFAULT_ABI
== ABI_V4
4647 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
4649 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4650 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4651 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4653 if (DEFAULT_ABI
== ABI_DARWIN
4654 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
4655 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4656 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4657 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4659 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
4660 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4661 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4665 global_regs
[SPEFSCR_REGNO
] = 1;
4666 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
4667 registers in prologues and epilogues. We no longer use r14
4668 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
4669 pool for link-compatibility with older versions of GCC. Once
4670 "old" code has died out, we can return r14 to the allocation
4673 = call_used_regs
[14]
4674 = call_really_used_regs
[14] = 1;
4677 if (!TARGET_ALTIVEC
)
4679 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
4680 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4681 call_really_used_regs
[VRSAVE_REGNO
] = 1;
4685 global_regs
[VSCR_REGNO
] = 1;
4687 if (TARGET_ALTIVEC_ABI
)
4689 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
4690 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4692 /* AIX reserves VR20:31 in non-extended ABI mode. */
4694 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
< FIRST_ALTIVEC_REGNO
+ 32; ++i
)
4695 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4699 /* Try to output insns to set TARGET equal to the constant C if it can
4700 be done in less than N insns. Do all computations in MODE.
4701 Returns the place where the output has been placed if it can be
4702 done and the insns have been emitted. If it would take more than N
4703 insns, zero is returned and no insns and emitted. */
4706 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
4707 rtx source
, int n ATTRIBUTE_UNUSED
)
4709 rtx result
, insn
, set
;
4710 HOST_WIDE_INT c0
, c1
;
4717 dest
= gen_reg_rtx (mode
);
4718 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
4722 result
= !can_create_pseudo_p () ? dest
: gen_reg_rtx (SImode
);
4724 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (result
),
4725 GEN_INT (INTVAL (source
)
4726 & (~ (HOST_WIDE_INT
) 0xffff))));
4727 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
4728 gen_rtx_IOR (SImode
, copy_rtx (result
),
4729 GEN_INT (INTVAL (source
) & 0xffff))));
4734 switch (GET_CODE (source
))
4737 c0
= INTVAL (source
);
4742 #if HOST_BITS_PER_WIDE_INT >= 64
4743 c0
= CONST_DOUBLE_LOW (source
);
4746 c0
= CONST_DOUBLE_LOW (source
);
4747 c1
= CONST_DOUBLE_HIGH (source
);
4755 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
4762 insn
= get_last_insn ();
4763 set
= single_set (insn
);
4764 if (! CONSTANT_P (SET_SRC (set
)))
4765 set_unique_reg_note (insn
, REG_EQUAL
, source
);
4770 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
4771 fall back to a straight forward decomposition. We do this to avoid
4772 exponential run times encountered when looking for longer sequences
4773 with rs6000_emit_set_const. */
4775 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
4777 if (!TARGET_POWERPC64
)
4779 rtx operand1
, operand2
;
4781 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
4783 operand2
= operand_subword_force (copy_rtx (dest
), WORDS_BIG_ENDIAN
!= 0,
4785 emit_move_insn (operand1
, GEN_INT (c1
));
4786 emit_move_insn (operand2
, GEN_INT (c2
));
4790 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
4793 ud2
= (c1
& 0xffff0000) >> 16;
4794 #if HOST_BITS_PER_WIDE_INT >= 64
4798 ud4
= (c2
& 0xffff0000) >> 16;
4800 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
4801 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
4804 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
4806 emit_move_insn (dest
, GEN_INT (ud1
));
4809 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
4810 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
4813 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
4816 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
4818 emit_move_insn (copy_rtx (dest
),
4819 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4822 else if ((ud4
== 0xffff && (ud3
& 0x8000))
4823 || (ud4
== 0 && ! (ud3
& 0x8000)))
4826 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
4829 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
4832 emit_move_insn (copy_rtx (dest
),
4833 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4835 emit_move_insn (copy_rtx (dest
),
4836 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
4839 emit_move_insn (copy_rtx (dest
),
4840 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4846 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
4849 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
4852 emit_move_insn (copy_rtx (dest
),
4853 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4856 emit_move_insn (copy_rtx (dest
),
4857 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
4860 emit_move_insn (copy_rtx (dest
),
4861 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4862 GEN_INT (ud2
<< 16)));
4864 emit_move_insn (copy_rtx (dest
),
4865 gen_rtx_IOR (DImode
, copy_rtx (dest
), GEN_INT (ud1
)));
4871 /* Helper for the following. Get rid of [r+r] memory refs
4872 in cases where it won't work (TImode, TFmode, TDmode). */
4875 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
4877 if (GET_CODE (operands
[0]) == MEM
4878 && GET_CODE (XEXP (operands
[0], 0)) != REG
4879 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0))
4880 && ! reload_in_progress
)
4882 = replace_equiv_address (operands
[0],
4883 copy_addr_to_reg (XEXP (operands
[0], 0)));
4885 if (GET_CODE (operands
[1]) == MEM
4886 && GET_CODE (XEXP (operands
[1], 0)) != REG
4887 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0))
4888 && ! reload_in_progress
)
4890 = replace_equiv_address (operands
[1],
4891 copy_addr_to_reg (XEXP (operands
[1], 0)));
4894 /* Emit a move from SOURCE to DEST in mode MODE. */
4896 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
4900 operands
[1] = source
;
4902 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
4903 if (GET_CODE (operands
[1]) == CONST_DOUBLE
4904 && ! FLOAT_MODE_P (mode
)
4905 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
4907 /* FIXME. This should never happen. */
4908 /* Since it seems that it does, do the safe thing and convert
4910 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
4912 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
4913 || FLOAT_MODE_P (mode
)
4914 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
4915 || CONST_DOUBLE_LOW (operands
[1]) < 0)
4916 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
4917 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
4919 /* Check if GCC is setting up a block move that will end up using FP
4920 registers as temporaries. We must make sure this is acceptable. */
4921 if (GET_CODE (operands
[0]) == MEM
4922 && GET_CODE (operands
[1]) == MEM
4924 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
4925 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
4926 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
4927 ? 32 : MEM_ALIGN (operands
[0])))
4928 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
4930 : MEM_ALIGN (operands
[1]))))
4931 && ! MEM_VOLATILE_P (operands
[0])
4932 && ! MEM_VOLATILE_P (operands
[1]))
4934 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
4935 adjust_address (operands
[1], SImode
, 0));
4936 emit_move_insn (adjust_address (copy_rtx (operands
[0]), SImode
, 4),
4937 adjust_address (copy_rtx (operands
[1]), SImode
, 4));
4941 if (can_create_pseudo_p () && GET_CODE (operands
[0]) == MEM
4942 && !gpc_reg_operand (operands
[1], mode
))
4943 operands
[1] = force_reg (mode
, operands
[1]);
4945 if (mode
== SFmode
&& ! TARGET_POWERPC
4946 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
4947 && GET_CODE (operands
[0]) == MEM
)
4951 if (reload_in_progress
|| reload_completed
)
4952 regnum
= true_regnum (operands
[1]);
4953 else if (GET_CODE (operands
[1]) == REG
)
4954 regnum
= REGNO (operands
[1]);
4958 /* If operands[1] is a register, on POWER it may have
4959 double-precision data in it, so truncate it to single
4961 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
4964 newreg
= (!can_create_pseudo_p () ? copy_rtx (operands
[1])
4965 : gen_reg_rtx (mode
));
4966 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
4967 operands
[1] = newreg
;
4971 /* Recognize the case where operand[1] is a reference to thread-local
4972 data and load its address to a register. */
4973 if (rs6000_tls_referenced_p (operands
[1]))
4975 enum tls_model model
;
4976 rtx tmp
= operands
[1];
4979 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
4981 addend
= XEXP (XEXP (tmp
, 0), 1);
4982 tmp
= XEXP (XEXP (tmp
, 0), 0);
4985 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
4986 model
= SYMBOL_REF_TLS_MODEL (tmp
);
4987 gcc_assert (model
!= 0);
4989 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
4992 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
4993 tmp
= force_operand (tmp
, operands
[0]);
4998 /* Handle the case where reload calls us with an invalid address. */
4999 if (reload_in_progress
&& mode
== Pmode
5000 && (! general_operand (operands
[1], mode
)
5001 || ! nonimmediate_operand (operands
[0], mode
)))
5004 /* 128-bit constant floating-point values on Darwin should really be
5005 loaded as two parts. */
5006 if (!TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
5007 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
5009 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
5010 know how to get a DFmode SUBREG of a TFmode. */
5011 enum machine_mode imode
= (TARGET_E500_DOUBLE
? DFmode
: DImode
);
5012 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
, 0),
5013 simplify_gen_subreg (imode
, operands
[1], mode
, 0),
5015 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
,
5016 GET_MODE_SIZE (imode
)),
5017 simplify_gen_subreg (imode
, operands
[1], mode
,
5018 GET_MODE_SIZE (imode
)),
5023 if (reload_in_progress
&& cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
5024 cfun
->machine
->sdmode_stack_slot
=
5025 eliminate_regs (cfun
->machine
->sdmode_stack_slot
, VOIDmode
, NULL_RTX
);
5027 if (reload_in_progress
5029 && MEM_P (operands
[0])
5030 && rtx_equal_p (operands
[0], cfun
->machine
->sdmode_stack_slot
)
5031 && REG_P (operands
[1]))
5033 if (FP_REGNO_P (REGNO (operands
[1])))
5035 rtx mem
= adjust_address_nv (operands
[0], DDmode
, 0);
5036 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
5037 emit_insn (gen_movsd_store (mem
, operands
[1]));
5039 else if (INT_REGNO_P (REGNO (operands
[1])))
5041 rtx mem
= adjust_address_nv (operands
[0], mode
, 4);
5042 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
5043 emit_insn (gen_movsd_hardfloat (mem
, operands
[1]));
5049 if (reload_in_progress
5051 && REG_P (operands
[0])
5052 && MEM_P (operands
[1])
5053 && rtx_equal_p (operands
[1], cfun
->machine
->sdmode_stack_slot
))
5055 if (FP_REGNO_P (REGNO (operands
[0])))
5057 rtx mem
= adjust_address_nv (operands
[1], DDmode
, 0);
5058 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
5059 emit_insn (gen_movsd_load (operands
[0], mem
));
5061 else if (INT_REGNO_P (REGNO (operands
[0])))
5063 rtx mem
= adjust_address_nv (operands
[1], mode
, 4);
5064 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
5065 emit_insn (gen_movsd_hardfloat (operands
[0], mem
));
5072 /* FIXME: In the long term, this switch statement should go away
5073 and be replaced by a sequence of tests based on things like
5079 if (CONSTANT_P (operands
[1])
5080 && GET_CODE (operands
[1]) != CONST_INT
)
5081 operands
[1] = force_const_mem (mode
, operands
[1]);
5086 rs6000_eliminate_indexed_memrefs (operands
);
5093 if (CONSTANT_P (operands
[1])
5094 && ! easy_fp_constant (operands
[1], mode
))
5095 operands
[1] = force_const_mem (mode
, operands
[1]);
5106 if (CONSTANT_P (operands
[1])
5107 && !easy_vector_constant (operands
[1], mode
))
5108 operands
[1] = force_const_mem (mode
, operands
[1]);
5113 /* Use default pattern for address of ELF small data */
5116 && DEFAULT_ABI
== ABI_V4
5117 && (GET_CODE (operands
[1]) == SYMBOL_REF
5118 || GET_CODE (operands
[1]) == CONST
)
5119 && small_data_operand (operands
[1], mode
))
5121 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
5125 if (DEFAULT_ABI
== ABI_V4
5126 && mode
== Pmode
&& mode
== SImode
5127 && flag_pic
== 1 && got_operand (operands
[1], mode
))
5129 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
5133 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
5137 && CONSTANT_P (operands
[1])
5138 && GET_CODE (operands
[1]) != HIGH
5139 && GET_CODE (operands
[1]) != CONST_INT
)
5141 rtx target
= (!can_create_pseudo_p ()
5143 : gen_reg_rtx (mode
));
5145 /* If this is a function address on -mcall-aixdesc,
5146 convert it to the address of the descriptor. */
5147 if (DEFAULT_ABI
== ABI_AIX
5148 && GET_CODE (operands
[1]) == SYMBOL_REF
5149 && XSTR (operands
[1], 0)[0] == '.')
5151 const char *name
= XSTR (operands
[1], 0);
5153 while (*name
== '.')
5155 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
5156 CONSTANT_POOL_ADDRESS_P (new_ref
)
5157 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
5158 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
5159 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
5160 SYMBOL_REF_DATA (new_ref
) = SYMBOL_REF_DATA (operands
[1]);
5161 operands
[1] = new_ref
;
5164 if (DEFAULT_ABI
== ABI_DARWIN
)
5167 if (MACHO_DYNAMIC_NO_PIC_P
)
5169 /* Take care of any required data indirection. */
5170 operands
[1] = rs6000_machopic_legitimize_pic_address (
5171 operands
[1], mode
, operands
[0]);
5172 if (operands
[0] != operands
[1])
5173 emit_insn (gen_rtx_SET (VOIDmode
,
5174 operands
[0], operands
[1]));
5178 emit_insn (gen_macho_high (target
, operands
[1]));
5179 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
5183 emit_insn (gen_elf_high (target
, operands
[1]));
5184 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
5188 /* If this is a SYMBOL_REF that refers to a constant pool entry,
5189 and we have put it in the TOC, we just need to make a TOC-relative
5192 && GET_CODE (operands
[1]) == SYMBOL_REF
5193 && constant_pool_expr_p (operands
[1])
5194 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
5195 get_pool_mode (operands
[1])))
5197 operands
[1] = create_TOC_reference (operands
[1]);
5199 else if (mode
== Pmode
5200 && CONSTANT_P (operands
[1])
5201 && ((GET_CODE (operands
[1]) != CONST_INT
5202 && ! easy_fp_constant (operands
[1], mode
))
5203 || (GET_CODE (operands
[1]) == CONST_INT
5204 && num_insns_constant (operands
[1], mode
) > 2)
5205 || (GET_CODE (operands
[0]) == REG
5206 && FP_REGNO_P (REGNO (operands
[0]))))
5207 && GET_CODE (operands
[1]) != HIGH
5208 && ! legitimate_constant_pool_address_p (operands
[1])
5209 && ! toc_relative_expr_p (operands
[1]))
5211 /* Emit a USE operation so that the constant isn't deleted if
5212 expensive optimizations are turned on because nobody
5213 references it. This should only be done for operands that
5214 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
5215 This should not be done for operands that contain LABEL_REFs.
5216 For now, we just handle the obvious case. */
5217 if (GET_CODE (operands
[1]) != LABEL_REF
)
5218 emit_use (operands
[1]);
5221 /* Darwin uses a special PIC legitimizer. */
5222 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
5225 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
5227 if (operands
[0] != operands
[1])
5228 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
5233 /* If we are to limit the number of things we put in the TOC and
5234 this is a symbol plus a constant we can add in one insn,
5235 just put the symbol in the TOC and add the constant. Don't do
5236 this if reload is in progress. */
5237 if (GET_CODE (operands
[1]) == CONST
5238 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
5239 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
5240 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
5241 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
5242 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
5243 && ! side_effects_p (operands
[0]))
5246 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
5247 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
5249 sym
= force_reg (mode
, sym
);
5251 emit_insn (gen_addsi3 (operands
[0], sym
, other
));
5253 emit_insn (gen_adddi3 (operands
[0], sym
, other
));
5257 operands
[1] = force_const_mem (mode
, operands
[1]);
5260 && GET_CODE (XEXP (operands
[1], 0)) == SYMBOL_REF
5261 && constant_pool_expr_p (XEXP (operands
[1], 0))
5262 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
5263 get_pool_constant (XEXP (operands
[1], 0)),
5264 get_pool_mode (XEXP (operands
[1], 0))))
5267 = gen_const_mem (mode
,
5268 create_TOC_reference (XEXP (operands
[1], 0)));
5269 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
5275 rs6000_eliminate_indexed_memrefs (operands
);
5279 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
5281 gen_rtx_SET (VOIDmode
,
5282 operands
[0], operands
[1]),
5283 gen_rtx_CLOBBER (VOIDmode
,
5284 gen_rtx_SCRATCH (SImode
)))));
5293 /* Above, we may have called force_const_mem which may have returned
5294 an invalid address. If we can, fix this up; otherwise, reload will
5295 have to deal with it. */
5296 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
5297 operands
[1] = validize_mem (operands
[1]);
5300 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
5303 /* Nonzero if we can use a floating-point register to pass this arg. */
5304 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
5305 (SCALAR_FLOAT_MODE_P (MODE) \
5306 && (CUM)->fregno <= FP_ARG_MAX_REG \
5307 && TARGET_HARD_FLOAT && TARGET_FPRS)
5309 /* Nonzero if we can use an AltiVec register to pass this arg. */
5310 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
5311 (ALTIVEC_VECTOR_MODE (MODE) \
5312 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
5313 && TARGET_ALTIVEC_ABI \
5316 /* Return a nonzero value to say to return the function value in
5317 memory, just as large structures are always returned. TYPE will be
5318 the data type of the value, and FNTYPE will be the type of the
5319 function doing the returning, or @code{NULL} for libcalls.
5321 The AIX ABI for the RS/6000 specifies that all structures are
5322 returned in memory. The Darwin ABI does the same. The SVR4 ABI
5323 specifies that structures <= 8 bytes are returned in r3/r4, but a
5324 draft put them in memory, and GCC used to implement the draft
5325 instead of the final standard. Therefore, aix_struct_return
5326 controls this instead of DEFAULT_ABI; V.4 targets needing backward
5327 compatibility can change DRAFT_V4_STRUCT_RET to override the
5328 default, and -m switches get the final word. See
5329 rs6000_override_options for more details.
5331 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
5332 long double support is enabled. These values are returned in memory.
5334 int_size_in_bytes returns -1 for variable size objects, which go in
5335 memory always. The cast to unsigned makes -1 > 8. */
5338 rs6000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
5340 /* In the darwin64 abi, try to use registers for larger structs
5342 if (rs6000_darwin64_abi
5343 && TREE_CODE (type
) == RECORD_TYPE
5344 && int_size_in_bytes (type
) > 0)
5346 CUMULATIVE_ARGS valcum
;
5350 valcum
.fregno
= FP_ARG_MIN_REG
;
5351 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
5352 /* Do a trial code generation as if this were going to be passed
5353 as an argument; if any part goes in memory, we return NULL. */
5354 valret
= rs6000_darwin64_record_arg (&valcum
, type
, 1, true);
5357 /* Otherwise fall through to more conventional ABI rules. */
5360 if (AGGREGATE_TYPE_P (type
)
5361 && (aix_struct_return
5362 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
5365 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5366 modes only exist for GCC vector types if -maltivec. */
5367 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
5368 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
5371 /* Return synthetic vectors in memory. */
5372 if (TREE_CODE (type
) == VECTOR_TYPE
5373 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
5375 static bool warned_for_return_big_vectors
= false;
5376 if (!warned_for_return_big_vectors
)
5378 warning (0, "GCC vector returned by reference: "
5379 "non-standard ABI extension with no compatibility guarantee");
5380 warned_for_return_big_vectors
= true;
5385 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& TYPE_MODE (type
) == TFmode
)
5391 /* Initialize a variable CUM of type CUMULATIVE_ARGS
5392 for a call to a function whose data type is FNTYPE.
5393 For a library call, FNTYPE is 0.
5395 For incoming args we set the number of arguments in the prototype large
5396 so we never return a PARALLEL. */
5399 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
5400 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
5401 int libcall
, int n_named_args
)
5403 static CUMULATIVE_ARGS zero_cumulative
;
5405 *cum
= zero_cumulative
;
5407 cum
->fregno
= FP_ARG_MIN_REG
;
5408 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
5409 cum
->prototype
= (fntype
&& TYPE_ARG_TYPES (fntype
));
5410 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
5411 ? CALL_LIBCALL
: CALL_NORMAL
);
5412 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
5413 cum
->stdarg
= fntype
5414 && (TYPE_ARG_TYPES (fntype
) != 0
5415 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
5416 != void_type_node
));
5418 cum
->nargs_prototype
= 0;
5419 if (incoming
|| cum
->prototype
)
5420 cum
->nargs_prototype
= n_named_args
;
5422 /* Check for a longcall attribute. */
5423 if ((!fntype
&& rs6000_default_long_calls
)
5425 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
5426 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
5427 cum
->call_cookie
|= CALL_LONG
;
5429 if (TARGET_DEBUG_ARG
)
5431 fprintf (stderr
, "\ninit_cumulative_args:");
5434 tree ret_type
= TREE_TYPE (fntype
);
5435 fprintf (stderr
, " ret code = %s,",
5436 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
5439 if (cum
->call_cookie
& CALL_LONG
)
5440 fprintf (stderr
, " longcall,");
5442 fprintf (stderr
, " proto = %d, nargs = %d\n",
5443 cum
->prototype
, cum
->nargs_prototype
);
5448 && TARGET_ALTIVEC_ABI
5449 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
5451 error ("cannot return value in vector register because"
5452 " altivec instructions are disabled, use -maltivec"
5457 /* Return true if TYPE must be passed on the stack and not in registers. */
5460 rs6000_must_pass_in_stack (enum machine_mode mode
, const_tree type
)
5462 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
5463 return must_pass_in_stack_var_size (mode
, type
);
5465 return must_pass_in_stack_var_size_or_pad (mode
, type
);
5468 /* If defined, a C expression which determines whether, and in which
5469 direction, to pad out an argument with extra space. The value
5470 should be of type `enum direction': either `upward' to pad above
5471 the argument, `downward' to pad below, or `none' to inhibit
5474 For the AIX ABI structs are always stored left shifted in their
5478 function_arg_padding (enum machine_mode mode
, const_tree type
)
5480 #ifndef AGGREGATE_PADDING_FIXED
5481 #define AGGREGATE_PADDING_FIXED 0
5483 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
5484 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
5487 if (!AGGREGATE_PADDING_FIXED
)
5489 /* GCC used to pass structures of the same size as integer types as
5490 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
5491 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
5492 passed padded downward, except that -mstrict-align further
5493 muddied the water in that multi-component structures of 2 and 4
5494 bytes in size were passed padded upward.
5496 The following arranges for best compatibility with previous
5497 versions of gcc, but removes the -mstrict-align dependency. */
5498 if (BYTES_BIG_ENDIAN
)
5500 HOST_WIDE_INT size
= 0;
5502 if (mode
== BLKmode
)
5504 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
5505 size
= int_size_in_bytes (type
);
5508 size
= GET_MODE_SIZE (mode
);
5510 if (size
== 1 || size
== 2 || size
== 4)
5516 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
5518 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
5522 /* Fall back to the default. */
5523 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
5526 /* If defined, a C expression that gives the alignment boundary, in bits,
5527 of an argument with the specified mode and type. If it is not defined,
5528 PARM_BOUNDARY is used for all arguments.
5530 V.4 wants long longs and doubles to be double word aligned. Just
5531 testing the mode size is a boneheaded way to do this as it means
5532 that other types such as complex int are also double word aligned.
5533 However, we're stuck with this because changing the ABI might break
5534 existing library interfaces.
5536 Doubleword align SPE vectors.
5537 Quadword align Altivec vectors.
5538 Quadword align large synthetic vector types. */
5541 function_arg_boundary (enum machine_mode mode
, tree type
)
5543 if (DEFAULT_ABI
== ABI_V4
5544 && (GET_MODE_SIZE (mode
) == 8
5545 || (TARGET_HARD_FLOAT
5547 && (mode
== TFmode
|| mode
== TDmode
))))
5549 else if (SPE_VECTOR_MODE (mode
)
5550 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5551 && int_size_in_bytes (type
) >= 8
5552 && int_size_in_bytes (type
) < 16))
5554 else if (ALTIVEC_VECTOR_MODE (mode
)
5555 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5556 && int_size_in_bytes (type
) >= 16))
5558 else if (rs6000_darwin64_abi
&& mode
== BLKmode
5559 && type
&& TYPE_ALIGN (type
) > 64)
5562 return PARM_BOUNDARY
;
5565 /* For a function parm of MODE and TYPE, return the starting word in
5566 the parameter area. NWORDS of the parameter area are already used. */
5569 rs6000_parm_start (enum machine_mode mode
, tree type
, unsigned int nwords
)
5572 unsigned int parm_offset
;
5574 align
= function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
5575 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
5576 return nwords
+ (-(parm_offset
+ nwords
) & align
);
5579 /* Compute the size (in words) of a function argument. */
5581 static unsigned long
5582 rs6000_arg_size (enum machine_mode mode
, tree type
)
5586 if (mode
!= BLKmode
)
5587 size
= GET_MODE_SIZE (mode
);
5589 size
= int_size_in_bytes (type
);
5592 return (size
+ 3) >> 2;
5594 return (size
+ 7) >> 3;
5597 /* Use this to flush pending int fields. */
5600 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
5601 HOST_WIDE_INT bitpos
)
5603 unsigned int startbit
, endbit
;
5604 int intregs
, intoffset
;
5605 enum machine_mode mode
;
5607 if (cum
->intoffset
== -1)
5610 intoffset
= cum
->intoffset
;
5611 cum
->intoffset
= -1;
5613 if (intoffset
% BITS_PER_WORD
!= 0)
5615 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
5617 if (mode
== BLKmode
)
5619 /* We couldn't find an appropriate mode, which happens,
5620 e.g., in packed structs when there are 3 bytes to load.
5621 Back intoffset back to the beginning of the word in this
5623 intoffset
= intoffset
& -BITS_PER_WORD
;
5627 startbit
= intoffset
& -BITS_PER_WORD
;
5628 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
5629 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
5630 cum
->words
+= intregs
;
5633 /* The darwin64 ABI calls for us to recurse down through structs,
5634 looking for elements passed in registers. Unfortunately, we have
5635 to track int register count here also because of misalignments
5636 in powerpc alignment mode. */
5639 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
5641 HOST_WIDE_INT startbitpos
)
5645 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
5646 if (TREE_CODE (f
) == FIELD_DECL
)
5648 HOST_WIDE_INT bitpos
= startbitpos
;
5649 tree ftype
= TREE_TYPE (f
);
5650 enum machine_mode mode
;
5651 if (ftype
== error_mark_node
)
5653 mode
= TYPE_MODE (ftype
);
5655 if (DECL_SIZE (f
) != 0
5656 && host_integerp (bit_position (f
), 1))
5657 bitpos
+= int_bit_position (f
);
5659 /* ??? FIXME: else assume zero offset. */
5661 if (TREE_CODE (ftype
) == RECORD_TYPE
)
5662 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
5663 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
5665 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
5666 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5667 cum
->words
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5669 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
5671 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
5675 else if (cum
->intoffset
== -1)
5676 cum
->intoffset
= bitpos
;
5680 /* Update the data in CUM to advance over an argument
5681 of mode MODE and data type TYPE.
5682 (TYPE is null for libcalls where that information may not be available.)
5684 Note that for args passed by reference, function_arg will be called
5685 with MODE and TYPE set to that of the pointer to the arg, not the arg
5689 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5690 tree type
, int named
, int depth
)
5694 /* Only tick off an argument if we're not recursing. */
5696 cum
->nargs_prototype
--;
5698 if (TARGET_ALTIVEC_ABI
5699 && (ALTIVEC_VECTOR_MODE (mode
)
5700 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5701 && int_size_in_bytes (type
) == 16)))
5705 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
5708 if (!TARGET_ALTIVEC
)
5709 error ("cannot pass argument in vector register because"
5710 " altivec instructions are disabled, use -maltivec"
5713 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
5714 even if it is going to be passed in a vector register.
5715 Darwin does the same for variable-argument functions. */
5716 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
5717 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
5727 /* Vector parameters must be 16-byte aligned. This places
5728 them at 2 mod 4 in terms of words in 32-bit mode, since
5729 the parameter save area starts at offset 24 from the
5730 stack. In 64-bit mode, they just have to start on an
5731 even word, since the parameter save area is 16-byte
5732 aligned. Space for GPRs is reserved even if the argument
5733 will be passed in memory. */
5735 align
= (2 - cum
->words
) & 3;
5737 align
= cum
->words
& 1;
5738 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
5740 if (TARGET_DEBUG_ARG
)
5742 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
5744 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
5745 cum
->nargs_prototype
, cum
->prototype
,
5746 GET_MODE_NAME (mode
));
5750 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
5752 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
5755 else if (rs6000_darwin64_abi
5757 && TREE_CODE (type
) == RECORD_TYPE
5758 && (size
= int_size_in_bytes (type
)) > 0)
5760 /* Variable sized types have size == -1 and are
5761 treated as if consisting entirely of ints.
5762 Pad to 16 byte boundary if needed. */
5763 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
5764 && (cum
->words
% 2) != 0)
5766 /* For varargs, we can just go up by the size of the struct. */
5768 cum
->words
+= (size
+ 7) / 8;
5771 /* It is tempting to say int register count just goes up by
5772 sizeof(type)/8, but this is wrong in a case such as
5773 { int; double; int; } [powerpc alignment]. We have to
5774 grovel through the fields for these too. */
5776 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
5777 rs6000_darwin64_record_arg_advance_flush (cum
,
5778 size
* BITS_PER_UNIT
);
5781 else if (DEFAULT_ABI
== ABI_V4
)
5783 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5784 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
5785 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
5786 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
5787 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
5789 /* _Decimal128 must use an even/odd register pair. This assumes
5790 that the register number is odd when fregno is odd. */
5791 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
5794 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
5795 <= FP_ARG_V4_MAX_REG
)
5796 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5799 cum
->fregno
= FP_ARG_V4_MAX_REG
+ 1;
5800 if (mode
== DFmode
|| mode
== TFmode
5801 || mode
== DDmode
|| mode
== TDmode
)
5802 cum
->words
+= cum
->words
& 1;
5803 cum
->words
+= rs6000_arg_size (mode
, type
);
5808 int n_words
= rs6000_arg_size (mode
, type
);
5809 int gregno
= cum
->sysv_gregno
;
5811 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5812 (r7,r8) or (r9,r10). As does any other 2 word item such
5813 as complex int due to a historical mistake. */
5815 gregno
+= (1 - gregno
) & 1;
5817 /* Multi-reg args are not split between registers and stack. */
5818 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5820 /* Long long and SPE vectors are aligned on the stack.
5821 So are other 2 word items such as complex int due to
5822 a historical mistake. */
5824 cum
->words
+= cum
->words
& 1;
5825 cum
->words
+= n_words
;
5828 /* Note: continuing to accumulate gregno past when we've started
5829 spilling to the stack indicates the fact that we've started
5830 spilling to the stack to expand_builtin_saveregs. */
5831 cum
->sysv_gregno
= gregno
+ n_words
;
5834 if (TARGET_DEBUG_ARG
)
5836 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
5837 cum
->words
, cum
->fregno
);
5838 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
5839 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
5840 fprintf (stderr
, "mode = %4s, named = %d\n",
5841 GET_MODE_NAME (mode
), named
);
5846 int n_words
= rs6000_arg_size (mode
, type
);
5847 int start_words
= cum
->words
;
5848 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
5850 cum
->words
= align_words
+ n_words
;
5852 if (SCALAR_FLOAT_MODE_P (mode
)
5853 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
5855 /* _Decimal128 must be passed in an even/odd float register pair.
5856 This assumes that the register number is odd when fregno is
5858 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
5860 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5863 if (TARGET_DEBUG_ARG
)
5865 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
5866 cum
->words
, cum
->fregno
);
5867 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
5868 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
5869 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
5870 named
, align_words
- start_words
, depth
);
5876 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
5883 r1
= gen_rtx_REG (DImode
, gregno
);
5884 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5885 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
5889 r1
= gen_rtx_REG (DImode
, gregno
);
5890 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5891 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
5892 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
5893 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
5896 r1
= gen_rtx_REG (DImode
, gregno
);
5897 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5898 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
5899 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
5900 r5
= gen_rtx_REG (DImode
, gregno
+ 4);
5901 r5
= gen_rtx_EXPR_LIST (VOIDmode
, r5
, GEN_INT (16));
5902 r7
= gen_rtx_REG (DImode
, gregno
+ 6);
5903 r7
= gen_rtx_EXPR_LIST (VOIDmode
, r7
, GEN_INT (24));
5904 return gen_rtx_PARALLEL (mode
, gen_rtvec (4, r1
, r3
, r5
, r7
));
5911 /* Determine where to put a SIMD argument on the SPE. */
5913 rs6000_spe_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5916 int gregno
= cum
->sysv_gregno
;
5918 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
5919 are passed and returned in a pair of GPRs for ABI compatibility. */
5920 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5921 || mode
== DCmode
|| mode
== TCmode
))
5923 int n_words
= rs6000_arg_size (mode
, type
);
5925 /* Doubles go in an odd/even register pair (r5/r6, etc). */
5927 gregno
+= (1 - gregno
) & 1;
5929 /* Multi-reg args are not split between registers and stack. */
5930 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5933 return spe_build_register_parallel (mode
, gregno
);
5937 int n_words
= rs6000_arg_size (mode
, type
);
5939 /* SPE vectors are put in odd registers. */
5940 if (n_words
== 2 && (gregno
& 1) == 0)
5943 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
5946 enum machine_mode m
= SImode
;
5948 r1
= gen_rtx_REG (m
, gregno
);
5949 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
5950 r2
= gen_rtx_REG (m
, gregno
+ 1);
5951 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
5952 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
5959 if (gregno
<= GP_ARG_MAX_REG
)
5960 return gen_rtx_REG (mode
, gregno
);
5966 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
5967 structure between cum->intoffset and bitpos to integer registers. */
5970 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
5971 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
5973 enum machine_mode mode
;
5975 unsigned int startbit
, endbit
;
5976 int this_regno
, intregs
, intoffset
;
5979 if (cum
->intoffset
== -1)
5982 intoffset
= cum
->intoffset
;
5983 cum
->intoffset
= -1;
5985 /* If this is the trailing part of a word, try to only load that
5986 much into the register. Otherwise load the whole register. Note
5987 that in the latter case we may pick up unwanted bits. It's not a
5988 problem at the moment but may wish to revisit. */
5990 if (intoffset
% BITS_PER_WORD
!= 0)
5992 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
5994 if (mode
== BLKmode
)
5996 /* We couldn't find an appropriate mode, which happens,
5997 e.g., in packed structs when there are 3 bytes to load.
5998 Back intoffset back to the beginning of the word in this
6000 intoffset
= intoffset
& -BITS_PER_WORD
;
6007 startbit
= intoffset
& -BITS_PER_WORD
;
6008 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
6009 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
6010 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
6012 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
6015 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
6019 intoffset
/= BITS_PER_UNIT
;
6022 regno
= GP_ARG_MIN_REG
+ this_regno
;
6023 reg
= gen_rtx_REG (mode
, regno
);
6025 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
6028 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
6032 while (intregs
> 0);
6035 /* Recursive workhorse for the following. */
6038 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, const_tree type
,
6039 HOST_WIDE_INT startbitpos
, rtx rvec
[],
6044 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
6045 if (TREE_CODE (f
) == FIELD_DECL
)
6047 HOST_WIDE_INT bitpos
= startbitpos
;
6048 tree ftype
= TREE_TYPE (f
);
6049 enum machine_mode mode
;
6050 if (ftype
== error_mark_node
)
6052 mode
= TYPE_MODE (ftype
);
6054 if (DECL_SIZE (f
) != 0
6055 && host_integerp (bit_position (f
), 1))
6056 bitpos
+= int_bit_position (f
);
6058 /* ??? FIXME: else assume zero offset. */
6060 if (TREE_CODE (ftype
) == RECORD_TYPE
)
6061 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
6062 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
6067 case SCmode
: mode
= SFmode
; break;
6068 case DCmode
: mode
= DFmode
; break;
6069 case TCmode
: mode
= TFmode
; break;
6073 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
6075 = gen_rtx_EXPR_LIST (VOIDmode
,
6076 gen_rtx_REG (mode
, cum
->fregno
++),
6077 GEN_INT (bitpos
/ BITS_PER_UNIT
));
6078 if (mode
== TFmode
|| mode
== TDmode
)
6081 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
6083 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
6085 = gen_rtx_EXPR_LIST (VOIDmode
,
6086 gen_rtx_REG (mode
, cum
->vregno
++),
6087 GEN_INT (bitpos
/ BITS_PER_UNIT
));
6089 else if (cum
->intoffset
== -1)
6090 cum
->intoffset
= bitpos
;
6094 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
6095 the register(s) to be used for each field and subfield of a struct
6096 being passed by value, along with the offset of where the
6097 register's value may be found in the block. FP fields go in FP
6098 register, vector fields go in vector registers, and everything
6099 else goes in int registers, packed as in memory.
6101 This code is also used for function return values. RETVAL indicates
6102 whether this is the case.
6104 Much of this is taken from the SPARC V9 port, which has a similar
6105 calling convention. */
6108 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, const_tree type
,
6109 int named
, bool retval
)
6111 rtx rvec
[FIRST_PSEUDO_REGISTER
];
6112 int k
= 1, kbase
= 1;
6113 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
6114 /* This is a copy; modifications are not visible to our caller. */
6115 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
6116 CUMULATIVE_ARGS
*cum
= ©_cum
;
6118 /* Pad to 16 byte boundary if needed. */
6119 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
6120 && (cum
->words
% 2) != 0)
6127 /* Put entries into rvec[] for individual FP and vector fields, and
6128 for the chunks of memory that go in int regs. Note we start at
6129 element 1; 0 is reserved for an indication of using memory, and
6130 may or may not be filled in below. */
6131 rs6000_darwin64_record_arg_recurse (cum
, type
, 0, rvec
, &k
);
6132 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
6134 /* If any part of the struct went on the stack put all of it there.
6135 This hack is because the generic code for
6136 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
6137 parts of the struct are not at the beginning. */
6141 return NULL_RTX
; /* doesn't go in registers at all */
6143 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
6145 if (k
> 1 || cum
->use_stack
)
6146 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
6151 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
6154 rs6000_mixed_function_arg (enum machine_mode mode
, tree type
, int align_words
)
6158 rtx rvec
[GP_ARG_NUM_REG
+ 1];
6160 if (align_words
>= GP_ARG_NUM_REG
)
6163 n_units
= rs6000_arg_size (mode
, type
);
6165 /* Optimize the simple case where the arg fits in one gpr, except in
6166 the case of BLKmode due to assign_parms assuming that registers are
6167 BITS_PER_WORD wide. */
6169 || (n_units
== 1 && mode
!= BLKmode
))
6170 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6173 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
6174 /* Not all of the arg fits in gprs. Say that it goes in memory too,
6175 using a magic NULL_RTX component.
6176 This is not strictly correct. Only some of the arg belongs in
6177 memory, not all of it. However, the normal scheme using
6178 function_arg_partial_nregs can result in unusual subregs, eg.
6179 (subreg:SI (reg:DF) 4), which are not handled well. The code to
6180 store the whole arg to memory is often more efficient than code
6181 to store pieces, and we know that space is available in the right
6182 place for the whole arg. */
6183 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
6188 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
6189 rtx off
= GEN_INT (i
++ * 4);
6190 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
6192 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
6194 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
6197 /* Determine where to put an argument to a function.
6198 Value is zero to push the argument on the stack,
6199 or a hard register in which to store the argument.
6201 MODE is the argument's machine mode.
6202 TYPE is the data type of the argument (as a tree).
6203 This is null for libcalls where that information may
6205 CUM is a variable of type CUMULATIVE_ARGS which gives info about
6206 the preceding args and about the function being called. It is
6207 not modified in this routine.
6208 NAMED is nonzero if this argument is a named parameter
6209 (otherwise it is an extra parameter matching an ellipsis).
6211 On RS/6000 the first eight words of non-FP are normally in registers
6212 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
6213 Under V.4, the first 8 FP args are in registers.
6215 If this is floating-point and no prototype is specified, we use
6216 both an FP and integer register (or possibly FP reg and stack). Library
6217 functions (when CALL_LIBCALL is set) always have the proper types for args,
6218 so we can pass the FP value just in one register. emit_library_function
6219 doesn't support PARALLEL anyway.
6221 Note that for args passed by reference, function_arg will be called
6222 with MODE and TYPE set to that of the pointer to the arg, not the arg
6226 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6227 tree type
, int named
)
6229 enum rs6000_abi abi
= DEFAULT_ABI
;
6231 /* Return a marker to indicate whether CR1 needs to set or clear the
6232 bit that V.4 uses to say fp args were passed in registers.
6233 Assume that we don't need the marker for software floating point,
6234 or compiler generated library calls. */
6235 if (mode
== VOIDmode
)
6238 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
6240 || (cum
->nargs_prototype
< 0
6241 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))))
6243 /* For the SPE, we need to crxor CR6 always. */
6245 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
6246 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
6247 return GEN_INT (cum
->call_cookie
6248 | ((cum
->fregno
== FP_ARG_MIN_REG
)
6249 ? CALL_V4_SET_FP_ARGS
6250 : CALL_V4_CLEAR_FP_ARGS
));
6253 return GEN_INT (cum
->call_cookie
);
6256 if (rs6000_darwin64_abi
&& mode
== BLKmode
6257 && TREE_CODE (type
) == RECORD_TYPE
)
6259 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, false);
6260 if (rslt
!= NULL_RTX
)
6262 /* Else fall through to usual handling. */
6265 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
6266 if (TARGET_64BIT
&& ! cum
->prototype
)
6268 /* Vector parameters get passed in vector register
6269 and also in GPRs or memory, in absence of prototype. */
6272 align_words
= (cum
->words
+ 1) & ~1;
6274 if (align_words
>= GP_ARG_NUM_REG
)
6280 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6282 return gen_rtx_PARALLEL (mode
,
6284 gen_rtx_EXPR_LIST (VOIDmode
,
6286 gen_rtx_EXPR_LIST (VOIDmode
,
6287 gen_rtx_REG (mode
, cum
->vregno
),
6291 return gen_rtx_REG (mode
, cum
->vregno
);
6292 else if (TARGET_ALTIVEC_ABI
6293 && (ALTIVEC_VECTOR_MODE (mode
)
6294 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
6295 && int_size_in_bytes (type
) == 16)))
6297 if (named
|| abi
== ABI_V4
)
6301 /* Vector parameters to varargs functions under AIX or Darwin
6302 get passed in memory and possibly also in GPRs. */
6303 int align
, align_words
, n_words
;
6304 enum machine_mode part_mode
;
6306 /* Vector parameters must be 16-byte aligned. This places them at
6307 2 mod 4 in terms of words in 32-bit mode, since the parameter
6308 save area starts at offset 24 from the stack. In 64-bit mode,
6309 they just have to start on an even word, since the parameter
6310 save area is 16-byte aligned. */
6312 align
= (2 - cum
->words
) & 3;
6314 align
= cum
->words
& 1;
6315 align_words
= cum
->words
+ align
;
6317 /* Out of registers? Memory, then. */
6318 if (align_words
>= GP_ARG_NUM_REG
)
6321 if (TARGET_32BIT
&& TARGET_POWERPC64
)
6322 return rs6000_mixed_function_arg (mode
, type
, align_words
);
6324 /* The vector value goes in GPRs. Only the part of the
6325 value in GPRs is reported here. */
6327 n_words
= rs6000_arg_size (mode
, type
);
6328 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
6329 /* Fortunately, there are only two possibilities, the value
6330 is either wholly in GPRs or half in GPRs and half not. */
6333 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
6336 else if (TARGET_SPE_ABI
&& TARGET_SPE
6337 && (SPE_VECTOR_MODE (mode
)
6338 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
6341 || mode
== TCmode
))))
6342 return rs6000_spe_function_arg (cum
, mode
, type
);
6344 else if (abi
== ABI_V4
)
6346 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
6347 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
6348 || (TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
6349 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
6350 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
6352 /* _Decimal128 must use an even/odd register pair. This assumes
6353 that the register number is odd when fregno is odd. */
6354 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
6357 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
6358 <= FP_ARG_V4_MAX_REG
)
6359 return gen_rtx_REG (mode
, cum
->fregno
);
6365 int n_words
= rs6000_arg_size (mode
, type
);
6366 int gregno
= cum
->sysv_gregno
;
6368 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
6369 (r7,r8) or (r9,r10). As does any other 2 word item such
6370 as complex int due to a historical mistake. */
6372 gregno
+= (1 - gregno
) & 1;
6374 /* Multi-reg args are not split between registers and stack. */
6375 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
6378 if (TARGET_32BIT
&& TARGET_POWERPC64
)
6379 return rs6000_mixed_function_arg (mode
, type
,
6380 gregno
- GP_ARG_MIN_REG
);
6381 return gen_rtx_REG (mode
, gregno
);
6386 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
6388 /* _Decimal128 must be passed in an even/odd float register pair.
6389 This assumes that the register number is odd when fregno is odd. */
6390 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
6393 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
6395 rtx rvec
[GP_ARG_NUM_REG
+ 1];
6399 enum machine_mode fmode
= mode
;
6400 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
6402 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
6404 /* Currently, we only ever need one reg here because complex
6405 doubles are split. */
6406 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
6407 && (fmode
== TFmode
|| fmode
== TDmode
));
6409 /* Long double or _Decimal128 split over regs and memory. */
6410 fmode
= DECIMAL_FLOAT_MODE_P (fmode
) ? DDmode
: DFmode
;
6413 /* Do we also need to pass this arg in the parameter save
6416 && (cum
->nargs_prototype
<= 0
6417 || (DEFAULT_ABI
== ABI_AIX
6419 && align_words
>= GP_ARG_NUM_REG
)));
6421 if (!needs_psave
&& mode
== fmode
)
6422 return gen_rtx_REG (fmode
, cum
->fregno
);
6427 /* Describe the part that goes in gprs or the stack.
6428 This piece must come first, before the fprs. */
6429 if (align_words
< GP_ARG_NUM_REG
)
6431 unsigned long n_words
= rs6000_arg_size (mode
, type
);
6433 if (align_words
+ n_words
> GP_ARG_NUM_REG
6434 || (TARGET_32BIT
&& TARGET_POWERPC64
))
6436 /* If this is partially on the stack, then we only
6437 include the portion actually in registers here. */
6438 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
6441 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
6442 /* Not all of the arg fits in gprs. Say that it
6443 goes in memory too, using a magic NULL_RTX
6444 component. Also see comment in
6445 rs6000_mixed_function_arg for why the normal
6446 function_arg_partial_nregs scheme doesn't work
6448 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
6452 r
= gen_rtx_REG (rmode
,
6453 GP_ARG_MIN_REG
+ align_words
);
6454 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
6455 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
6457 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
6461 /* The whole arg fits in gprs. */
6462 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6463 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
6467 /* It's entirely in memory. */
6468 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
6471 /* Describe where this piece goes in the fprs. */
6472 r
= gen_rtx_REG (fmode
, cum
->fregno
);
6473 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
6475 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
6477 else if (align_words
< GP_ARG_NUM_REG
)
6479 if (TARGET_32BIT
&& TARGET_POWERPC64
)
6480 return rs6000_mixed_function_arg (mode
, type
, align_words
);
6482 if (mode
== BLKmode
)
6485 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6492 /* For an arg passed partly in registers and partly in memory, this is
6493 the number of bytes passed in registers. For args passed entirely in
6494 registers or entirely in memory, zero. When an arg is described by a
6495 PARALLEL, perhaps using more than one register type, this function
6496 returns the number of bytes used by the first element of the PARALLEL. */
6499 rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6500 tree type
, bool named
)
6505 if (DEFAULT_ABI
== ABI_V4
)
6508 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
6509 && cum
->nargs_prototype
>= 0)
6512 /* In this complicated case we just disable the partial_nregs code. */
6513 if (rs6000_darwin64_abi
&& mode
== BLKmode
6514 && TREE_CODE (type
) == RECORD_TYPE
6515 && int_size_in_bytes (type
) > 0)
6518 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
6520 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
6522 /* If we are passing this arg in the fixed parameter save area
6523 (gprs or memory) as well as fprs, then this function should
6524 return the number of partial bytes passed in the parameter
6525 save area rather than partial bytes passed in fprs. */
6527 && (cum
->nargs_prototype
<= 0
6528 || (DEFAULT_ABI
== ABI_AIX
6530 && align_words
>= GP_ARG_NUM_REG
)))
6532 else if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3)
6533 > FP_ARG_MAX_REG
+ 1)
6534 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
6535 else if (cum
->nargs_prototype
>= 0)
6539 if (align_words
< GP_ARG_NUM_REG
6540 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
6541 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
6543 if (ret
!= 0 && TARGET_DEBUG_ARG
)
6544 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
6549 /* A C expression that indicates when an argument must be passed by
6550 reference. If nonzero for an argument, a copy of that argument is
6551 made in memory and a pointer to the argument is passed instead of
6552 the argument itself. The pointer is passed in whatever way is
6553 appropriate for passing a pointer to that type.
6555 Under V.4, aggregates and long double are passed by reference.
6557 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
6558 reference unless the AltiVec vector extension ABI is in force.
6560 As an extension to all ABIs, variable sized types are passed by
6564 rs6000_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
6565 enum machine_mode mode
, const_tree type
,
6566 bool named ATTRIBUTE_UNUSED
)
6568 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& mode
== TFmode
)
6570 if (TARGET_DEBUG_ARG
)
6571 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
6578 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
6580 if (TARGET_DEBUG_ARG
)
6581 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
6585 if (int_size_in_bytes (type
) < 0)
6587 if (TARGET_DEBUG_ARG
)
6588 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
6592 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6593 modes only exist for GCC vector types if -maltivec. */
6594 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
6596 if (TARGET_DEBUG_ARG
)
6597 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
6601 /* Pass synthetic vectors in memory. */
6602 if (TREE_CODE (type
) == VECTOR_TYPE
6603 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
6605 static bool warned_for_pass_big_vectors
= false;
6606 if (TARGET_DEBUG_ARG
)
6607 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
6608 if (!warned_for_pass_big_vectors
)
6610 warning (0, "GCC vector passed by reference: "
6611 "non-standard ABI extension with no compatibility guarantee");
6612 warned_for_pass_big_vectors
= true;
6621 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
6624 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
6629 for (i
= 0; i
< nregs
; i
++)
6631 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
6632 if (reload_completed
)
6634 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
6637 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
6638 i
* GET_MODE_SIZE (reg_mode
));
6641 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
6645 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
6649 /* Perform any needed actions needed for a function that is receiving a
6650 variable number of arguments.
6654 MODE and TYPE are the mode and type of the current parameter.
6656 PRETEND_SIZE is a variable that should be set to the amount of stack
6657 that must be pushed by the prolog to pretend that our caller pushed
6660 Normally, this macro will push all remaining incoming registers on the
6661 stack and set PRETEND_SIZE to the length of the registers pushed. */
6664 setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6665 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
6668 CUMULATIVE_ARGS next_cum
;
6669 int reg_size
= TARGET_32BIT
? 4 : 8;
6670 rtx save_area
= NULL_RTX
, mem
;
6671 int first_reg_offset
;
6674 /* Skip the last named argument. */
6676 function_arg_advance (&next_cum
, mode
, type
, 1, 0);
6678 if (DEFAULT_ABI
== ABI_V4
)
6680 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
6684 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
6685 HOST_WIDE_INT offset
= 0;
6687 /* Try to optimize the size of the varargs save area.
6688 The ABI requires that ap.reg_save_area is doubleword
6689 aligned, but we don't need to allocate space for all
6690 the bytes, only those to which we actually will save
6692 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
6693 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
6694 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
6695 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
6696 && cfun
->va_list_fpr_size
)
6699 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
6700 * UNITS_PER_FP_WORD
;
6701 if (cfun
->va_list_fpr_size
6702 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
6703 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
6705 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
6706 * UNITS_PER_FP_WORD
;
6710 offset
= -((first_reg_offset
* reg_size
) & ~7);
6711 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
6713 gpr_reg_num
= cfun
->va_list_gpr_size
;
6714 if (reg_size
== 4 && (first_reg_offset
& 1))
6717 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
6720 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
6722 - (int) (GP_ARG_NUM_REG
* reg_size
);
6724 if (gpr_size
+ fpr_size
)
6727 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
6728 gcc_assert (GET_CODE (reg_save_area
) == MEM
);
6729 reg_save_area
= XEXP (reg_save_area
, 0);
6730 if (GET_CODE (reg_save_area
) == PLUS
)
6732 gcc_assert (XEXP (reg_save_area
, 0)
6733 == virtual_stack_vars_rtx
);
6734 gcc_assert (GET_CODE (XEXP (reg_save_area
, 1)) == CONST_INT
);
6735 offset
+= INTVAL (XEXP (reg_save_area
, 1));
6738 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
6741 cfun
->machine
->varargs_save_offset
= offset
;
6742 save_area
= plus_constant (virtual_stack_vars_rtx
, offset
);
6747 first_reg_offset
= next_cum
.words
;
6748 save_area
= virtual_incoming_args_rtx
;
6750 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
6751 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
6754 set
= get_varargs_alias_set ();
6755 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
6756 && cfun
->va_list_gpr_size
)
6758 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
6760 if (va_list_gpr_counter_field
)
6762 /* V4 va_list_gpr_size counts number of registers needed. */
6763 if (nregs
> cfun
->va_list_gpr_size
)
6764 nregs
= cfun
->va_list_gpr_size
;
6768 /* char * va_list instead counts number of bytes needed. */
6769 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
6770 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
6773 mem
= gen_rtx_MEM (BLKmode
,
6774 plus_constant (save_area
,
6775 first_reg_offset
* reg_size
));
6776 MEM_NOTRAP_P (mem
) = 1;
6777 set_mem_alias_set (mem
, set
);
6778 set_mem_align (mem
, BITS_PER_WORD
);
6780 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
6784 /* Save FP registers if needed. */
6785 if (DEFAULT_ABI
== ABI_V4
6786 && TARGET_HARD_FLOAT
&& TARGET_FPRS
6788 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
6789 && cfun
->va_list_fpr_size
)
6791 int fregno
= next_cum
.fregno
, nregs
;
6792 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
6793 rtx lab
= gen_label_rtx ();
6794 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
6795 * UNITS_PER_FP_WORD
);
6798 (gen_rtx_SET (VOIDmode
,
6800 gen_rtx_IF_THEN_ELSE (VOIDmode
,
6801 gen_rtx_NE (VOIDmode
, cr1
,
6803 gen_rtx_LABEL_REF (VOIDmode
, lab
),
6807 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
6808 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
6810 mem
= gen_rtx_MEM ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
6812 plus_constant (save_area
, off
));
6813 MEM_NOTRAP_P (mem
) = 1;
6814 set_mem_alias_set (mem
, set
);
6815 set_mem_align (mem
, GET_MODE_ALIGNMENT (
6816 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
6817 ? DFmode
: SFmode
));
6818 emit_move_insn (mem
, gen_rtx_REG (
6819 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
6820 ? DFmode
: SFmode
, fregno
));
6827 /* Create the va_list data type. */
6830 rs6000_build_builtin_va_list (void)
6832 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
6834 /* For AIX, prefer 'char *' because that's what the system
6835 header files like. */
6836 if (DEFAULT_ABI
!= ABI_V4
)
6837 return build_pointer_type (char_type_node
);
6839 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
6840 type_decl
= build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
6842 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("gpr"),
6843 unsigned_char_type_node
);
6844 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("fpr"),
6845 unsigned_char_type_node
);
6846 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
6848 f_res
= build_decl (FIELD_DECL
, get_identifier ("reserved"),
6849 short_unsigned_type_node
);
6850 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("overflow_arg_area"),
6852 f_sav
= build_decl (FIELD_DECL
, get_identifier ("reg_save_area"),
6855 va_list_gpr_counter_field
= f_gpr
;
6856 va_list_fpr_counter_field
= f_fpr
;
6858 DECL_FIELD_CONTEXT (f_gpr
) = record
;
6859 DECL_FIELD_CONTEXT (f_fpr
) = record
;
6860 DECL_FIELD_CONTEXT (f_res
) = record
;
6861 DECL_FIELD_CONTEXT (f_ovf
) = record
;
6862 DECL_FIELD_CONTEXT (f_sav
) = record
;
6864 TREE_CHAIN (record
) = type_decl
;
6865 TYPE_NAME (record
) = type_decl
;
6866 TYPE_FIELDS (record
) = f_gpr
;
6867 TREE_CHAIN (f_gpr
) = f_fpr
;
6868 TREE_CHAIN (f_fpr
) = f_res
;
6869 TREE_CHAIN (f_res
) = f_ovf
;
6870 TREE_CHAIN (f_ovf
) = f_sav
;
6872 layout_type (record
);
6874 /* The correct type is an array type of one element. */
6875 return build_array_type (record
, build_index_type (size_zero_node
));
6878 /* Implement va_start. */
6881 rs6000_va_start (tree valist
, rtx nextarg
)
6883 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
6884 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
6885 tree gpr
, fpr
, ovf
, sav
, t
;
6887 /* Only SVR4 needs something special. */
6888 if (DEFAULT_ABI
!= ABI_V4
)
6890 std_expand_builtin_va_start (valist
, nextarg
);
6894 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6895 f_fpr
= TREE_CHAIN (f_gpr
);
6896 f_res
= TREE_CHAIN (f_fpr
);
6897 f_ovf
= TREE_CHAIN (f_res
);
6898 f_sav
= TREE_CHAIN (f_ovf
);
6900 valist
= build_va_arg_indirect_ref (valist
);
6901 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6902 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
6904 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
6906 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
6909 /* Count number of gp and fp argument registers used. */
6910 words
= crtl
->args
.info
.words
;
6911 n_gpr
= MIN (crtl
->args
.info
.sysv_gregno
- GP_ARG_MIN_REG
,
6913 n_fpr
= MIN (crtl
->args
.info
.fregno
- FP_ARG_MIN_REG
,
6916 if (TARGET_DEBUG_ARG
)
6917 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
6918 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
6919 words
, n_gpr
, n_fpr
);
6921 if (cfun
->va_list_gpr_size
)
6923 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
6924 build_int_cst (NULL_TREE
, n_gpr
));
6925 TREE_SIDE_EFFECTS (t
) = 1;
6926 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6929 if (cfun
->va_list_fpr_size
)
6931 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
6932 build_int_cst (NULL_TREE
, n_fpr
));
6933 TREE_SIDE_EFFECTS (t
) = 1;
6934 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6937 /* Find the overflow area. */
6938 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
6940 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ovf
), t
,
6941 size_int (words
* UNITS_PER_WORD
));
6942 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
6943 TREE_SIDE_EFFECTS (t
) = 1;
6944 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6946 /* If there were no va_arg invocations, don't set up the register
6948 if (!cfun
->va_list_gpr_size
6949 && !cfun
->va_list_fpr_size
6950 && n_gpr
< GP_ARG_NUM_REG
6951 && n_fpr
< FP_ARG_V4_MAX_REG
)
6954 /* Find the register save area. */
6955 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
6956 if (cfun
->machine
->varargs_save_offset
)
6957 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (sav
), t
,
6958 size_int (cfun
->machine
->varargs_save_offset
));
6959 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
6960 TREE_SIDE_EFFECTS (t
) = 1;
6961 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6964 /* Implement va_arg. */
6967 rs6000_gimplify_va_arg (tree valist
, tree type
, gimple_seq
*pre_p
,
6970 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
6971 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
6972 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
6973 tree lab_false
, lab_over
, addr
;
6975 tree ptrtype
= build_pointer_type (type
);
6979 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
6981 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
6982 return build_va_arg_indirect_ref (t
);
6985 if (DEFAULT_ABI
!= ABI_V4
)
6987 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
6989 tree elem_type
= TREE_TYPE (type
);
6990 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
6991 int elem_size
= GET_MODE_SIZE (elem_mode
);
6993 if (elem_size
< UNITS_PER_WORD
)
6995 tree real_part
, imag_part
;
6996 gimple_seq post
= NULL
;
6998 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
7000 /* Copy the value into a temporary, lest the formal temporary
7001 be reused out from under us. */
7002 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
7003 gimple_seq_add_seq (pre_p
, post
);
7005 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
7008 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
7012 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
7015 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
7016 f_fpr
= TREE_CHAIN (f_gpr
);
7017 f_res
= TREE_CHAIN (f_fpr
);
7018 f_ovf
= TREE_CHAIN (f_res
);
7019 f_sav
= TREE_CHAIN (f_ovf
);
7021 valist
= build_va_arg_indirect_ref (valist
);
7022 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
7023 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
7025 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
7027 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
7030 size
= int_size_in_bytes (type
);
7031 rsize
= (size
+ 3) / 4;
7034 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
7035 && ((TARGET_SINGLE_FLOAT
&& TYPE_MODE (type
) == SFmode
)
7036 || (TARGET_DOUBLE_FLOAT
7037 && (TYPE_MODE (type
) == DFmode
7038 || TYPE_MODE (type
) == TFmode
7039 || TYPE_MODE (type
) == SDmode
7040 || TYPE_MODE (type
) == DDmode
7041 || TYPE_MODE (type
) == TDmode
))))
7043 /* FP args go in FP registers, if present. */
7045 n_reg
= (size
+ 7) / 8;
7046 sav_ofs
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4) * 4;
7047 sav_scale
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4);
7048 if (TYPE_MODE (type
) != SFmode
&& TYPE_MODE (type
) != SDmode
)
7053 /* Otherwise into GP registers. */
7062 /* Pull the value out of the saved registers.... */
7065 addr
= create_tmp_var (ptr_type_node
, "addr");
7066 DECL_POINTER_ALIAS_SET (addr
) = get_varargs_alias_set ();
7068 /* AltiVec vectors never go in registers when -mabi=altivec. */
7069 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
7073 lab_false
= create_artificial_label ();
7074 lab_over
= create_artificial_label ();
7076 /* Long long and SPE vectors are aligned in the registers.
7077 As are any other 2 gpr item such as complex int due to a
7078 historical mistake. */
7080 if (n_reg
== 2 && reg
== gpr
)
7083 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
7084 build_int_cst (TREE_TYPE (reg
), n_reg
- 1));
7085 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
),
7086 unshare_expr (reg
), u
);
7088 /* _Decimal128 is passed in even/odd fpr pairs; the stored
7089 reg number is 0 for f1, so we want to make it odd. */
7090 else if (reg
== fpr
&& TYPE_MODE (type
) == TDmode
)
7092 t
= build2 (BIT_IOR_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
7093 build_int_cst (TREE_TYPE (reg
), 1));
7094 u
= build2 (MODIFY_EXPR
, void_type_node
, unshare_expr (reg
), t
);
7097 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
7098 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
7099 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
7100 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
7101 gimplify_and_add (t
, pre_p
);
7105 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, sav
, size_int (sav_ofs
));
7107 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
7108 build_int_cst (TREE_TYPE (reg
), n_reg
));
7109 u
= fold_convert (sizetype
, u
);
7110 u
= build2 (MULT_EXPR
, sizetype
, u
, size_int (sav_scale
));
7111 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
, u
);
7113 /* _Decimal32 varargs are located in the second word of the 64-bit
7114 FP register for 32-bit binaries. */
7115 if (!TARGET_POWERPC64
7116 && TARGET_HARD_FLOAT
&& TARGET_FPRS
7117 && TYPE_MODE (type
) == SDmode
)
7118 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
7120 gimplify_assign (addr
, t
, pre_p
);
7122 gimple_seq_add_stmt (pre_p
, gimple_build_goto (lab_over
));
7124 stmt
= gimple_build_label (lab_false
);
7125 gimple_seq_add_stmt (pre_p
, stmt
);
7127 if ((n_reg
== 2 && !regalign
) || n_reg
> 2)
7129 /* Ensure that we don't find any more args in regs.
7130 Alignment has taken care of for special cases. */
7131 gimplify_assign (reg
, build_int_cst (TREE_TYPE (reg
), 8), pre_p
);
7135 /* ... otherwise out of the overflow area. */
7137 /* Care for on-stack alignment if needed. */
7141 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (align
- 1));
7142 t
= fold_convert (sizetype
, t
);
7143 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
7145 t
= fold_convert (TREE_TYPE (ovf
), t
);
7147 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
7149 gimplify_assign (unshare_expr (addr
), t
, pre_p
);
7151 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
7152 gimplify_assign (unshare_expr (ovf
), t
, pre_p
);
7156 stmt
= gimple_build_label (lab_over
);
7157 gimple_seq_add_stmt (pre_p
, stmt
);
7160 if (STRICT_ALIGNMENT
7161 && (TYPE_ALIGN (type
)
7162 > (unsigned) BITS_PER_UNIT
* (align
< 4 ? 4 : align
)))
7164 /* The value (of type complex double, for example) may not be
7165 aligned in memory in the saved registers, so copy via a
7166 temporary. (This is the same code as used for SPARC.) */
7167 tree tmp
= create_tmp_var (type
, "va_arg_tmp");
7168 tree dest_addr
= build_fold_addr_expr (tmp
);
7170 tree copy
= build_call_expr (implicit_built_in_decls
[BUILT_IN_MEMCPY
],
7171 3, dest_addr
, addr
, size_int (rsize
* 4));
7173 gimplify_and_add (copy
, pre_p
);
7177 addr
= fold_convert (ptrtype
, addr
);
7178 return build_va_arg_indirect_ref (addr
);
7184 def_builtin (int mask
, const char *name
, tree type
, int code
)
7186 if ((mask
& target_flags
) || TARGET_PAIRED_FLOAT
)
7188 if (rs6000_builtin_decls
[code
])
7191 rs6000_builtin_decls
[code
] =
7192 add_builtin_function (name
, type
, code
, BUILT_IN_MD
,
7197 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
7199 static const struct builtin_description bdesc_3arg
[] =
7201 { MASK_ALTIVEC
, CODE_FOR_altivec_vmaddfp
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
7202 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
7203 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
7204 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
7205 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
7206 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
7207 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
7208 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
7209 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
7210 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
7211 { MASK_ALTIVEC
, CODE_FOR_altivec_vnmsubfp
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
7212 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
7213 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
7214 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
7215 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
7216 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
7217 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
7218 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
7219 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
7220 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
7221 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
7222 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
7223 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
7225 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
7226 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
7227 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
7228 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
7229 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
7230 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
7231 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
7232 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
7233 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
7234 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
7235 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
7236 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
7237 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
7238 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
7239 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
7241 { 0, CODE_FOR_paired_msub
, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB
},
7242 { 0, CODE_FOR_paired_madd
, "__builtin_paired_madd", PAIRED_BUILTIN_MADD
},
7243 { 0, CODE_FOR_paired_madds0
, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0
},
7244 { 0, CODE_FOR_paired_madds1
, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1
},
7245 { 0, CODE_FOR_paired_nmsub
, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB
},
7246 { 0, CODE_FOR_paired_nmadd
, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD
},
7247 { 0, CODE_FOR_paired_sum0
, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0
},
7248 { 0, CODE_FOR_paired_sum1
, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1
},
7249 { 0, CODE_FOR_selv2sf4
, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4
},
7252 /* DST operations: void foo (void *, const int, const char). */
7254 static const struct builtin_description bdesc_dst
[] =
7256 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
7257 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
7258 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
7259 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
7261 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
7262 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
7263 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
7264 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
7267 /* Simple binary operations: VECc = foo (VECa, VECb). */
7269 static struct builtin_description bdesc_2arg
[] =
7271 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
7272 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
7273 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
7274 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
7275 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
7276 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
7277 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
7278 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
7279 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
7280 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
7281 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
7282 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
7283 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
7284 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
7285 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
7286 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
7287 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
7288 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
7289 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
7290 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
7291 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
7292 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
7293 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequb
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
7294 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequh
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
7295 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequw
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
7296 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpeqfp
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
7297 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgefp
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
7298 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtub
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
7299 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsb
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
7300 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuh
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
7301 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsh
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
7302 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuw
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
7303 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsw
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
7304 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtfp
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
7305 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
7306 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
7307 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
7308 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
7309 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
7310 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
7311 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
7312 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
7313 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
7314 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
7315 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
7316 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
7317 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
7318 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
7319 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
7320 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
7321 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
7322 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
7323 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
7324 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
7325 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
7326 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
7327 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
7328 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
7329 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
7330 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
7331 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
7332 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
7333 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
7334 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
7335 { MASK_ALTIVEC
, CODE_FOR_altivec_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
7336 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
7337 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
7338 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
7339 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
7340 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
7341 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
7342 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
7343 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
7344 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
7345 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
7346 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlb
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
7347 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlh
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
7348 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlw
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
7349 { MASK_ALTIVEC
, CODE_FOR_vashlv16qi3
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
7350 { MASK_ALTIVEC
, CODE_FOR_vashlv8hi3
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
7351 { MASK_ALTIVEC
, CODE_FOR_vashlv4si3
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
7352 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
7353 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
7354 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
7355 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
7356 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
7357 { MASK_ALTIVEC
, CODE_FOR_vlshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
7358 { MASK_ALTIVEC
, CODE_FOR_vlshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
7359 { MASK_ALTIVEC
, CODE_FOR_vlshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
7360 { MASK_ALTIVEC
, CODE_FOR_vashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
7361 { MASK_ALTIVEC
, CODE_FOR_vashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
7362 { MASK_ALTIVEC
, CODE_FOR_vashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
7363 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
7364 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
7365 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
7366 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
7367 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
7368 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
7369 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
7370 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
7371 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
7372 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
7373 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
7374 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
7375 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
7376 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
7377 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
7378 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
7379 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
7380 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
7381 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
7383 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
7384 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
7385 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
7386 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
7387 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
7388 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
7389 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
7390 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
7391 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
7392 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
7393 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
7394 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
7395 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
7396 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
7397 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
7398 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
7399 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
7400 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
7401 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
7402 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
7403 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
7404 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
7405 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
7406 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
7407 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
7408 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
7409 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
7410 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
7411 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
7412 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
7413 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
7414 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
7415 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
7416 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
7417 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
7418 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
7419 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
7420 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
7421 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
7422 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
7423 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
7424 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
7425 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
7426 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
7427 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
7428 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
7429 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
7430 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
7431 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
7432 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
7433 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
7434 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
7435 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
7436 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
7437 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
7438 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
7439 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
7440 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
7441 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
7442 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
7443 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
7444 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
7445 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
7446 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
7447 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
7448 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
7449 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
7450 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
7451 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
7452 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
7453 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
7454 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
7455 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
7456 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
7457 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
7458 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
7459 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
7460 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
7461 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
7462 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
7463 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
7464 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
7465 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
7466 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
7467 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
7468 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
7469 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
7470 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
7471 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
7472 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
7473 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
7474 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
7475 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
7476 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
7477 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
7478 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
7479 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
7480 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
7481 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
7482 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
7483 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
7484 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
7485 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
7486 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
7487 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
7488 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
7489 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
7490 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
7491 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
7492 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
7493 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
7494 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
7495 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
7496 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
7497 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
7498 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
7499 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
7500 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
7501 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
7502 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
7503 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
7504 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
7505 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
7506 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
7507 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
7508 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
7509 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
7511 { 0, CODE_FOR_divv2sf3
, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3
},
7512 { 0, CODE_FOR_addv2sf3
, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3
},
7513 { 0, CODE_FOR_subv2sf3
, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3
},
7514 { 0, CODE_FOR_mulv2sf3
, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3
},
7515 { 0, CODE_FOR_paired_muls0
, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0
},
7516 { 0, CODE_FOR_paired_muls1
, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1
},
7517 { 0, CODE_FOR_paired_merge00
, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00
},
7518 { 0, CODE_FOR_paired_merge01
, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01
},
7519 { 0, CODE_FOR_paired_merge10
, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10
},
7520 { 0, CODE_FOR_paired_merge11
, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11
},
7522 /* Place holder, leave as first spe builtin. */
7523 { 0, CODE_FOR_spe_evaddw
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
7524 { 0, CODE_FOR_spe_evand
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
7525 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
7526 { 0, CODE_FOR_spe_evdivws
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
7527 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
7528 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
7529 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
7530 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
7531 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
7532 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
7533 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
7534 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
7535 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
7536 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
7537 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
7538 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
7539 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
7540 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
7541 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
7542 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
7543 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
7544 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
7545 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
7546 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
7547 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
7548 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
7549 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
7550 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
7551 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
7552 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
7553 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
7554 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
7555 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
7556 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
7557 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
7558 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
7559 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
7560 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
7561 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
7562 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
7563 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
7564 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
7565 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
7566 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
7567 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
7568 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
7569 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
7570 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
7571 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
7572 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
7573 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
7574 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
7575 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
7576 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
7577 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
7578 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
7579 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
7580 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
7581 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
7582 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
7583 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
7584 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
7585 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
7586 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
7587 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
7588 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
7589 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
7590 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
7591 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
7592 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
7593 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
7594 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
7595 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
7596 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
7597 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
7598 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
7599 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
7600 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
7601 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
7602 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
7603 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
7604 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
7605 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
7606 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
7607 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
7608 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
7609 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
7610 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
7611 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
7612 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
7613 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
7614 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
7615 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
7616 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
7617 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
7618 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
7619 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
7620 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
7621 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
7622 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
7623 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
7624 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
7625 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
7626 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
7627 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
7628 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
7629 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
7630 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
7631 { 0, CODE_FOR_spe_evsubfw
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
7633 /* SPE binary operations expecting a 5-bit unsigned literal. */
7634 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
7636 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
7637 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
7638 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
7639 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
7640 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
7641 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
7642 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
7643 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
7644 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
7645 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
7646 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
7647 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
7648 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
7649 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
7650 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
7651 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
7652 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
7653 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
7654 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
7655 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
7656 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
7657 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
7658 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
7659 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
7660 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
7661 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
7663 /* Place-holder. Leave as last binary SPE builtin. */
7664 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
7667 /* AltiVec predicates. */
7669 struct builtin_description_predicates
7671 const unsigned int mask
;
7672 const enum insn_code icode
;
7674 const char *const name
;
7675 const enum rs6000_builtins code
;
7678 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
7680 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P
},
7681 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
7682 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
7683 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
7684 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P
},
7685 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P
},
7686 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P
},
7687 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P
},
7688 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P
},
7689 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P
},
7690 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P
},
7691 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P
},
7692 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P
},
7694 { MASK_ALTIVEC
, CODE_FOR_nothing
, NULL
, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P
},
7695 { MASK_ALTIVEC
, CODE_FOR_nothing
, NULL
, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P
},
7696 { MASK_ALTIVEC
, CODE_FOR_nothing
, NULL
, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P
}
7699 /* SPE predicates. */
7700 static struct builtin_description bdesc_spe_predicates
[] =
7702 /* Place-holder. Leave as first. */
7703 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
7704 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
7705 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
7706 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
7707 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
7708 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
7709 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
7710 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
7711 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
7712 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
7713 /* Place-holder. Leave as last. */
7714 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
7717 /* SPE evsel predicates. */
7718 static struct builtin_description bdesc_spe_evsel
[] =
7720 /* Place-holder. Leave as first. */
7721 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
7722 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
7723 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
7724 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
7725 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
7726 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
7727 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
7728 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
7729 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
7730 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
7731 /* Place-holder. Leave as last. */
7732 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
7735 /* PAIRED predicates. */
7736 static const struct builtin_description bdesc_paired_preds
[] =
7738 /* Place-holder. Leave as first. */
7739 { 0, CODE_FOR_paired_cmpu0
, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0
},
7740 /* Place-holder. Leave as last. */
7741 { 0, CODE_FOR_paired_cmpu1
, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1
},
7744 /* ABS* operations. */
7746 static const struct builtin_description bdesc_abs
[] =
7748 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
7749 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
7750 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
7751 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
7752 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
7753 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
7754 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
}
7757 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
7760 static struct builtin_description bdesc_1arg
[] =
7762 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
7763 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
7764 { MASK_ALTIVEC
, CODE_FOR_altivec_vrefp
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
7765 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfim
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
7766 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
7767 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfip
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
7768 { MASK_ALTIVEC
, CODE_FOR_ftruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
7769 { MASK_ALTIVEC
, CODE_FOR_altivec_vrsqrtefp
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
7770 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
7771 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
7772 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
7773 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
7774 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
7775 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
7776 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
7777 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
7778 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
7780 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
7781 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
7782 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
7783 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
7784 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
7785 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
7786 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
7787 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
7788 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
7789 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
7790 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
7791 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
7792 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
7793 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
7794 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
7795 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
7796 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
7797 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
7798 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
7800 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
7801 end with SPE_BUILTIN_EVSUBFUSIAAW. */
7802 { 0, CODE_FOR_spe_evabs
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
7803 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
7804 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
7805 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
7806 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
7807 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
7808 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
7809 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
7810 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
7811 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
7812 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
7813 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
7814 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
7815 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
7816 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
7817 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
7818 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
7819 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
7820 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
7821 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
7822 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
7823 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
7824 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
7825 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
7826 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
7827 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
7828 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
7829 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
7831 /* Place-holder. Leave as last unary SPE builtin. */
7832 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
},
7834 { 0, CODE_FOR_absv2sf2
, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2
},
7835 { 0, CODE_FOR_nabsv2sf2
, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2
},
7836 { 0, CODE_FOR_negv2sf2
, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2
},
7837 { 0, CODE_FOR_sqrtv2sf2
, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2
},
7838 { 0, CODE_FOR_resv2sf2
, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2
}
7842 rs6000_expand_unop_builtin (enum insn_code icode
, tree exp
, rtx target
)
7845 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7846 rtx op0
= expand_normal (arg0
);
7847 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7848 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7850 if (icode
== CODE_FOR_nothing
)
7851 /* Builtin not supported on this processor. */
7854 /* If we got invalid arguments bail out before generating bad rtl. */
7855 if (arg0
== error_mark_node
)
7858 if (icode
== CODE_FOR_altivec_vspltisb
7859 || icode
== CODE_FOR_altivec_vspltish
7860 || icode
== CODE_FOR_altivec_vspltisw
7861 || icode
== CODE_FOR_spe_evsplatfi
7862 || icode
== CODE_FOR_spe_evsplati
)
7864 /* Only allow 5-bit *signed* literals. */
7865 if (GET_CODE (op0
) != CONST_INT
7866 || INTVAL (op0
) > 15
7867 || INTVAL (op0
) < -16)
7869 error ("argument 1 must be a 5-bit signed literal");
7875 || GET_MODE (target
) != tmode
7876 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7877 target
= gen_reg_rtx (tmode
);
7879 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7880 op0
= copy_to_mode_reg (mode0
, op0
);
7882 pat
= GEN_FCN (icode
) (target
, op0
);
7891 altivec_expand_abs_builtin (enum insn_code icode
, tree exp
, rtx target
)
7893 rtx pat
, scratch1
, scratch2
;
7894 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7895 rtx op0
= expand_normal (arg0
);
7896 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7897 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7899 /* If we have invalid arguments, bail out before generating bad rtl. */
7900 if (arg0
== error_mark_node
)
7904 || GET_MODE (target
) != tmode
7905 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7906 target
= gen_reg_rtx (tmode
);
7908 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7909 op0
= copy_to_mode_reg (mode0
, op0
);
7911 scratch1
= gen_reg_rtx (mode0
);
7912 scratch2
= gen_reg_rtx (mode0
);
7914 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
7923 rs6000_expand_binop_builtin (enum insn_code icode
, tree exp
, rtx target
)
7926 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7927 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7928 rtx op0
= expand_normal (arg0
);
7929 rtx op1
= expand_normal (arg1
);
7930 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7931 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7932 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7934 if (icode
== CODE_FOR_nothing
)
7935 /* Builtin not supported on this processor. */
7938 /* If we got invalid arguments bail out before generating bad rtl. */
7939 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7942 if (icode
== CODE_FOR_altivec_vcfux
7943 || icode
== CODE_FOR_altivec_vcfsx
7944 || icode
== CODE_FOR_altivec_vctsxs
7945 || icode
== CODE_FOR_altivec_vctuxs
7946 || icode
== CODE_FOR_altivec_vspltb
7947 || icode
== CODE_FOR_altivec_vsplth
7948 || icode
== CODE_FOR_altivec_vspltw
7949 || icode
== CODE_FOR_spe_evaddiw
7950 || icode
== CODE_FOR_spe_evldd
7951 || icode
== CODE_FOR_spe_evldh
7952 || icode
== CODE_FOR_spe_evldw
7953 || icode
== CODE_FOR_spe_evlhhesplat
7954 || icode
== CODE_FOR_spe_evlhhossplat
7955 || icode
== CODE_FOR_spe_evlhhousplat
7956 || icode
== CODE_FOR_spe_evlwhe
7957 || icode
== CODE_FOR_spe_evlwhos
7958 || icode
== CODE_FOR_spe_evlwhou
7959 || icode
== CODE_FOR_spe_evlwhsplat
7960 || icode
== CODE_FOR_spe_evlwwsplat
7961 || icode
== CODE_FOR_spe_evrlwi
7962 || icode
== CODE_FOR_spe_evslwi
7963 || icode
== CODE_FOR_spe_evsrwis
7964 || icode
== CODE_FOR_spe_evsubifw
7965 || icode
== CODE_FOR_spe_evsrwiu
)
7967 /* Only allow 5-bit unsigned literals. */
7969 if (TREE_CODE (arg1
) != INTEGER_CST
7970 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
7972 error ("argument 2 must be a 5-bit unsigned literal");
7978 || GET_MODE (target
) != tmode
7979 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7980 target
= gen_reg_rtx (tmode
);
7982 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7983 op0
= copy_to_mode_reg (mode0
, op0
);
7984 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7985 op1
= copy_to_mode_reg (mode1
, op1
);
7987 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
7996 altivec_expand_predicate_builtin (enum insn_code icode
, const char *opcode
,
7997 tree exp
, rtx target
)
8000 tree cr6_form
= CALL_EXPR_ARG (exp
, 0);
8001 tree arg0
= CALL_EXPR_ARG (exp
, 1);
8002 tree arg1
= CALL_EXPR_ARG (exp
, 2);
8003 rtx op0
= expand_normal (arg0
);
8004 rtx op1
= expand_normal (arg1
);
8005 enum machine_mode tmode
= SImode
;
8006 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8007 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8010 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
8012 error ("argument 1 of __builtin_altivec_predicate must be a constant");
8016 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
8018 gcc_assert (mode0
== mode1
);
8020 /* If we have invalid arguments, bail out before generating bad rtl. */
8021 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
8025 || GET_MODE (target
) != tmode
8026 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8027 target
= gen_reg_rtx (tmode
);
8029 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8030 op0
= copy_to_mode_reg (mode0
, op0
);
8031 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
8032 op1
= copy_to_mode_reg (mode1
, op1
);
8034 scratch
= gen_reg_rtx (mode0
);
8036 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
,
8037 gen_rtx_SYMBOL_REF (Pmode
, opcode
));
8042 /* The vec_any* and vec_all* predicates use the same opcodes for two
8043 different operations, but the bits in CR6 will be different
8044 depending on what information we want. So we have to play tricks
8045 with CR6 to get the right bits out.
8047 If you think this is disgusting, look at the specs for the
8048 AltiVec predicates. */
8050 switch (cr6_form_int
)
8053 emit_insn (gen_cr6_test_for_zero (target
));
8056 emit_insn (gen_cr6_test_for_zero_reverse (target
));
8059 emit_insn (gen_cr6_test_for_lt (target
));
8062 emit_insn (gen_cr6_test_for_lt_reverse (target
));
8065 error ("argument 1 of __builtin_altivec_predicate is out of range");
8073 paired_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
)
8076 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8077 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8078 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8079 enum machine_mode mode0
= Pmode
;
8080 enum machine_mode mode1
= Pmode
;
8081 rtx op0
= expand_normal (arg0
);
8082 rtx op1
= expand_normal (arg1
);
8084 if (icode
== CODE_FOR_nothing
)
8085 /* Builtin not supported on this processor. */
8088 /* If we got invalid arguments bail out before generating bad rtl. */
8089 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
8093 || GET_MODE (target
) != tmode
8094 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8095 target
= gen_reg_rtx (tmode
);
8097 op1
= copy_to_mode_reg (mode1
, op1
);
8099 if (op0
== const0_rtx
)
8101 addr
= gen_rtx_MEM (tmode
, op1
);
8105 op0
= copy_to_mode_reg (mode0
, op0
);
8106 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
8109 pat
= GEN_FCN (icode
) (target
, addr
);
8119 altivec_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
, bool blk
)
8122 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8123 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8124 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8125 enum machine_mode mode0
= Pmode
;
8126 enum machine_mode mode1
= Pmode
;
8127 rtx op0
= expand_normal (arg0
);
8128 rtx op1
= expand_normal (arg1
);
8130 if (icode
== CODE_FOR_nothing
)
8131 /* Builtin not supported on this processor. */
8134 /* If we got invalid arguments bail out before generating bad rtl. */
8135 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
8139 || GET_MODE (target
) != tmode
8140 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8141 target
= gen_reg_rtx (tmode
);
8143 op1
= copy_to_mode_reg (mode1
, op1
);
8145 if (op0
== const0_rtx
)
8147 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, op1
);
8151 op0
= copy_to_mode_reg (mode0
, op0
);
8152 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
8155 pat
= GEN_FCN (icode
) (target
, addr
);
8165 spe_expand_stv_builtin (enum insn_code icode
, tree exp
)
8167 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8168 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8169 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8170 rtx op0
= expand_normal (arg0
);
8171 rtx op1
= expand_normal (arg1
);
8172 rtx op2
= expand_normal (arg2
);
8174 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
8175 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
8176 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
8178 /* Invalid arguments. Bail before doing anything stoopid! */
8179 if (arg0
== error_mark_node
8180 || arg1
== error_mark_node
8181 || arg2
== error_mark_node
)
8184 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
8185 op0
= copy_to_mode_reg (mode2
, op0
);
8186 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
8187 op1
= copy_to_mode_reg (mode0
, op1
);
8188 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
8189 op2
= copy_to_mode_reg (mode1
, op2
);
8191 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
8198 paired_expand_stv_builtin (enum insn_code icode
, tree exp
)
8200 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8201 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8202 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8203 rtx op0
= expand_normal (arg0
);
8204 rtx op1
= expand_normal (arg1
);
8205 rtx op2
= expand_normal (arg2
);
8207 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8208 enum machine_mode mode1
= Pmode
;
8209 enum machine_mode mode2
= Pmode
;
8211 /* Invalid arguments. Bail before doing anything stoopid! */
8212 if (arg0
== error_mark_node
8213 || arg1
== error_mark_node
8214 || arg2
== error_mark_node
)
8217 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
8218 op0
= copy_to_mode_reg (tmode
, op0
);
8220 op2
= copy_to_mode_reg (mode2
, op2
);
8222 if (op1
== const0_rtx
)
8224 addr
= gen_rtx_MEM (tmode
, op2
);
8228 op1
= copy_to_mode_reg (mode1
, op1
);
8229 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
8232 pat
= GEN_FCN (icode
) (addr
, op0
);
8239 altivec_expand_stv_builtin (enum insn_code icode
, tree exp
)
8241 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8242 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8243 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8244 rtx op0
= expand_normal (arg0
);
8245 rtx op1
= expand_normal (arg1
);
8246 rtx op2
= expand_normal (arg2
);
8248 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8249 enum machine_mode mode1
= Pmode
;
8250 enum machine_mode mode2
= Pmode
;
8252 /* Invalid arguments. Bail before doing anything stoopid! */
8253 if (arg0
== error_mark_node
8254 || arg1
== error_mark_node
8255 || arg2
== error_mark_node
)
8258 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
8259 op0
= copy_to_mode_reg (tmode
, op0
);
8261 op2
= copy_to_mode_reg (mode2
, op2
);
8263 if (op1
== const0_rtx
)
8265 addr
= gen_rtx_MEM (tmode
, op2
);
8269 op1
= copy_to_mode_reg (mode1
, op1
);
8270 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
8273 pat
= GEN_FCN (icode
) (addr
, op0
);
8280 rs6000_expand_ternop_builtin (enum insn_code icode
, tree exp
, rtx target
)
8283 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8284 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8285 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8286 rtx op0
= expand_normal (arg0
);
8287 rtx op1
= expand_normal (arg1
);
8288 rtx op2
= expand_normal (arg2
);
8289 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8290 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8291 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8292 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
8294 if (icode
== CODE_FOR_nothing
)
8295 /* Builtin not supported on this processor. */
8298 /* If we got invalid arguments bail out before generating bad rtl. */
8299 if (arg0
== error_mark_node
8300 || arg1
== error_mark_node
8301 || arg2
== error_mark_node
)
8304 if (icode
== CODE_FOR_altivec_vsldoi_v4sf
8305 || icode
== CODE_FOR_altivec_vsldoi_v4si
8306 || icode
== CODE_FOR_altivec_vsldoi_v8hi
8307 || icode
== CODE_FOR_altivec_vsldoi_v16qi
)
8309 /* Only allow 4-bit unsigned literals. */
8311 if (TREE_CODE (arg2
) != INTEGER_CST
8312 || TREE_INT_CST_LOW (arg2
) & ~0xf)
8314 error ("argument 3 must be a 4-bit unsigned literal");
8320 || GET_MODE (target
) != tmode
8321 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8322 target
= gen_reg_rtx (tmode
);
8324 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8325 op0
= copy_to_mode_reg (mode0
, op0
);
8326 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
8327 op1
= copy_to_mode_reg (mode1
, op1
);
8328 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
8329 op2
= copy_to_mode_reg (mode2
, op2
);
8331 if (TARGET_PAIRED_FLOAT
&& icode
== CODE_FOR_selv2sf4
)
8332 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
, CONST0_RTX (SFmode
));
8334 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
8342 /* Expand the lvx builtins. */
8344 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
8346 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8347 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8349 enum machine_mode tmode
, mode0
;
8351 enum insn_code icode
;
8355 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
8356 icode
= CODE_FOR_altivec_lvx_v16qi
;
8358 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
8359 icode
= CODE_FOR_altivec_lvx_v8hi
;
8361 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
8362 icode
= CODE_FOR_altivec_lvx_v4si
;
8364 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
8365 icode
= CODE_FOR_altivec_lvx_v4sf
;
8374 arg0
= CALL_EXPR_ARG (exp
, 0);
8375 op0
= expand_normal (arg0
);
8376 tmode
= insn_data
[icode
].operand
[0].mode
;
8377 mode0
= insn_data
[icode
].operand
[1].mode
;
8380 || GET_MODE (target
) != tmode
8381 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8382 target
= gen_reg_rtx (tmode
);
8384 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8385 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
8387 pat
= GEN_FCN (icode
) (target
, op0
);
8394 /* Expand the stvx builtins. */
8396 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
8399 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8400 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8402 enum machine_mode mode0
, mode1
;
8404 enum insn_code icode
;
8408 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
8409 icode
= CODE_FOR_altivec_stvx_v16qi
;
8411 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
8412 icode
= CODE_FOR_altivec_stvx_v8hi
;
8414 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
8415 icode
= CODE_FOR_altivec_stvx_v4si
;
8417 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
8418 icode
= CODE_FOR_altivec_stvx_v4sf
;
8425 arg0
= CALL_EXPR_ARG (exp
, 0);
8426 arg1
= CALL_EXPR_ARG (exp
, 1);
8427 op0
= expand_normal (arg0
);
8428 op1
= expand_normal (arg1
);
8429 mode0
= insn_data
[icode
].operand
[0].mode
;
8430 mode1
= insn_data
[icode
].operand
[1].mode
;
8432 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8433 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
8434 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
8435 op1
= copy_to_mode_reg (mode1
, op1
);
8437 pat
= GEN_FCN (icode
) (op0
, op1
);
8445 /* Expand the dst builtins. */
8447 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
8450 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8451 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8452 tree arg0
, arg1
, arg2
;
8453 enum machine_mode mode0
, mode1
, mode2
;
8454 rtx pat
, op0
, op1
, op2
;
8455 const struct builtin_description
*d
;
8460 /* Handle DST variants. */
8462 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
8463 if (d
->code
== fcode
)
8465 arg0
= CALL_EXPR_ARG (exp
, 0);
8466 arg1
= CALL_EXPR_ARG (exp
, 1);
8467 arg2
= CALL_EXPR_ARG (exp
, 2);
8468 op0
= expand_normal (arg0
);
8469 op1
= expand_normal (arg1
);
8470 op2
= expand_normal (arg2
);
8471 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8472 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
8473 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
8475 /* Invalid arguments, bail out before generating bad rtl. */
8476 if (arg0
== error_mark_node
8477 || arg1
== error_mark_node
8478 || arg2
== error_mark_node
)
8483 if (TREE_CODE (arg2
) != INTEGER_CST
8484 || TREE_INT_CST_LOW (arg2
) & ~0x3)
8486 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
8490 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
8491 op0
= copy_to_mode_reg (Pmode
, op0
);
8492 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
8493 op1
= copy_to_mode_reg (mode1
, op1
);
8495 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
8505 /* Expand vec_init builtin. */
8507 altivec_expand_vec_init_builtin (tree type
, tree exp
, rtx target
)
8509 enum machine_mode tmode
= TYPE_MODE (type
);
8510 enum machine_mode inner_mode
= GET_MODE_INNER (tmode
);
8511 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
8512 rtvec v
= rtvec_alloc (n_elt
);
8514 gcc_assert (VECTOR_MODE_P (tmode
));
8515 gcc_assert (n_elt
== call_expr_nargs (exp
));
8517 for (i
= 0; i
< n_elt
; ++i
)
8519 rtx x
= expand_normal (CALL_EXPR_ARG (exp
, i
));
8520 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
8523 if (!target
|| !register_operand (target
, tmode
))
8524 target
= gen_reg_rtx (tmode
);
8526 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
8530 /* Return the integer constant in ARG. Constrain it to be in the range
8531 of the subparts of VEC_TYPE; issue an error if not. */
8534 get_element_number (tree vec_type
, tree arg
)
8536 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
8538 if (!host_integerp (arg
, 1)
8539 || (elt
= tree_low_cst (arg
, 1), elt
> max
))
8541 error ("selector must be an integer constant in the range 0..%wi", max
);
8548 /* Expand vec_set builtin. */
8550 altivec_expand_vec_set_builtin (tree exp
)
8552 enum machine_mode tmode
, mode1
;
8553 tree arg0
, arg1
, arg2
;
8557 arg0
= CALL_EXPR_ARG (exp
, 0);
8558 arg1
= CALL_EXPR_ARG (exp
, 1);
8559 arg2
= CALL_EXPR_ARG (exp
, 2);
8561 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
8562 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
8563 gcc_assert (VECTOR_MODE_P (tmode
));
8565 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, EXPAND_NORMAL
);
8566 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, EXPAND_NORMAL
);
8567 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
8569 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
8570 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
8572 op0
= force_reg (tmode
, op0
);
8573 op1
= force_reg (mode1
, op1
);
8575 rs6000_expand_vector_set (op0
, op1
, elt
);
8580 /* Expand vec_ext builtin. */
8582 altivec_expand_vec_ext_builtin (tree exp
, rtx target
)
8584 enum machine_mode tmode
, mode0
;
8589 arg0
= CALL_EXPR_ARG (exp
, 0);
8590 arg1
= CALL_EXPR_ARG (exp
, 1);
8592 op0
= expand_normal (arg0
);
8593 elt
= get_element_number (TREE_TYPE (arg0
), arg1
);
8595 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
8596 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
8597 gcc_assert (VECTOR_MODE_P (mode0
));
8599 op0
= force_reg (mode0
, op0
);
8601 if (optimize
|| !target
|| !register_operand (target
, tmode
))
8602 target
= gen_reg_rtx (tmode
);
8604 rs6000_expand_vector_extract (target
, op0
, elt
);
8609 /* Expand the builtin in EXP and store the result in TARGET. Store
8610 true in *EXPANDEDP if we found a builtin to expand. */
8612 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
8614 const struct builtin_description
*d
;
8615 const struct builtin_description_predicates
*dp
;
8617 enum insn_code icode
;
8618 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8621 enum machine_mode tmode
, mode0
;
8622 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8624 if (fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8625 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
8628 error ("unresolved overload for Altivec builtin %qF", fndecl
);
8632 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
8636 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
8640 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
8648 case ALTIVEC_BUILTIN_STVX
:
8649 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx
, exp
);
8650 case ALTIVEC_BUILTIN_STVEBX
:
8651 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, exp
);
8652 case ALTIVEC_BUILTIN_STVEHX
:
8653 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, exp
);
8654 case ALTIVEC_BUILTIN_STVEWX
:
8655 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, exp
);
8656 case ALTIVEC_BUILTIN_STVXL
:
8657 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, exp
);
8659 case ALTIVEC_BUILTIN_STVLX
:
8660 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx
, exp
);
8661 case ALTIVEC_BUILTIN_STVLXL
:
8662 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl
, exp
);
8663 case ALTIVEC_BUILTIN_STVRX
:
8664 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx
, exp
);
8665 case ALTIVEC_BUILTIN_STVRXL
:
8666 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl
, exp
);
8668 case ALTIVEC_BUILTIN_MFVSCR
:
8669 icode
= CODE_FOR_altivec_mfvscr
;
8670 tmode
= insn_data
[icode
].operand
[0].mode
;
8673 || GET_MODE (target
) != tmode
8674 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8675 target
= gen_reg_rtx (tmode
);
8677 pat
= GEN_FCN (icode
) (target
);
8683 case ALTIVEC_BUILTIN_MTVSCR
:
8684 icode
= CODE_FOR_altivec_mtvscr
;
8685 arg0
= CALL_EXPR_ARG (exp
, 0);
8686 op0
= expand_normal (arg0
);
8687 mode0
= insn_data
[icode
].operand
[0].mode
;
8689 /* If we got invalid arguments bail out before generating bad rtl. */
8690 if (arg0
== error_mark_node
)
8693 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8694 op0
= copy_to_mode_reg (mode0
, op0
);
8696 pat
= GEN_FCN (icode
) (op0
);
8701 case ALTIVEC_BUILTIN_DSSALL
:
8702 emit_insn (gen_altivec_dssall ());
8705 case ALTIVEC_BUILTIN_DSS
:
8706 icode
= CODE_FOR_altivec_dss
;
8707 arg0
= CALL_EXPR_ARG (exp
, 0);
8709 op0
= expand_normal (arg0
);
8710 mode0
= insn_data
[icode
].operand
[0].mode
;
8712 /* If we got invalid arguments bail out before generating bad rtl. */
8713 if (arg0
== error_mark_node
)
8716 if (TREE_CODE (arg0
) != INTEGER_CST
8717 || TREE_INT_CST_LOW (arg0
) & ~0x3)
8719 error ("argument to dss must be a 2-bit unsigned literal");
8723 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8724 op0
= copy_to_mode_reg (mode0
, op0
);
8726 emit_insn (gen_altivec_dss (op0
));
8729 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
8730 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
8731 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
8732 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
8733 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), exp
, target
);
8735 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
8736 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
8737 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
8738 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
8739 return altivec_expand_vec_set_builtin (exp
);
8741 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
8742 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
8743 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
8744 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
8745 return altivec_expand_vec_ext_builtin (exp
, target
);
8752 /* Expand abs* operations. */
8754 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
8755 if (d
->code
== fcode
)
8756 return altivec_expand_abs_builtin (d
->icode
, exp
, target
);
8758 /* Expand the AltiVec predicates. */
8759 dp
= bdesc_altivec_preds
;
8760 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
8761 if (dp
->code
== fcode
)
8762 return altivec_expand_predicate_builtin (dp
->icode
, dp
->opcode
,
8765 /* LV* are funky. We initialized them differently. */
8768 case ALTIVEC_BUILTIN_LVSL
:
8769 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
8770 exp
, target
, false);
8771 case ALTIVEC_BUILTIN_LVSR
:
8772 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
8773 exp
, target
, false);
8774 case ALTIVEC_BUILTIN_LVEBX
:
8775 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
8776 exp
, target
, false);
8777 case ALTIVEC_BUILTIN_LVEHX
:
8778 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
8779 exp
, target
, false);
8780 case ALTIVEC_BUILTIN_LVEWX
:
8781 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
8782 exp
, target
, false);
8783 case ALTIVEC_BUILTIN_LVXL
:
8784 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
8785 exp
, target
, false);
8786 case ALTIVEC_BUILTIN_LVX
:
8787 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx
,
8788 exp
, target
, false);
8789 case ALTIVEC_BUILTIN_LVLX
:
8790 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx
,
8792 case ALTIVEC_BUILTIN_LVLXL
:
8793 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl
,
8795 case ALTIVEC_BUILTIN_LVRX
:
8796 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx
,
8798 case ALTIVEC_BUILTIN_LVRXL
:
8799 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl
,
8810 /* Expand the builtin in EXP and store the result in TARGET. Store
8811 true in *EXPANDEDP if we found a builtin to expand. */
8813 paired_expand_builtin (tree exp
, rtx target
, bool * expandedp
)
8815 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8816 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8817 const struct builtin_description
*d
;
8824 case PAIRED_BUILTIN_STX
:
8825 return paired_expand_stv_builtin (CODE_FOR_paired_stx
, exp
);
8826 case PAIRED_BUILTIN_LX
:
8827 return paired_expand_lv_builtin (CODE_FOR_paired_lx
, exp
, target
);
8833 /* Expand the paired predicates. */
8834 d
= bdesc_paired_preds
;
8835 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); i
++, d
++)
8836 if (d
->code
== fcode
)
8837 return paired_expand_predicate_builtin (d
->icode
, exp
, target
);
8843 /* Binops that need to be initialized manually, but can be expanded
8844 automagically by rs6000_expand_binop_builtin. */
8845 static struct builtin_description bdesc_2arg_spe
[] =
8847 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
8848 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
8849 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
8850 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
8851 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
8852 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
8853 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
8854 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
8855 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
8856 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
8857 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
8858 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
8859 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
8860 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
8861 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
8862 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
8863 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
8864 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
8865 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
8866 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
8867 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
8868 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
8871 /* Expand the builtin in EXP and store the result in TARGET. Store
8872 true in *EXPANDEDP if we found a builtin to expand.
8874 This expands the SPE builtins that are not simple unary and binary
8877 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
8879 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8881 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8882 enum insn_code icode
;
8883 enum machine_mode tmode
, mode0
;
8885 struct builtin_description
*d
;
8890 /* Syntax check for a 5-bit unsigned immediate. */
8893 case SPE_BUILTIN_EVSTDD
:
8894 case SPE_BUILTIN_EVSTDH
:
8895 case SPE_BUILTIN_EVSTDW
:
8896 case SPE_BUILTIN_EVSTWHE
:
8897 case SPE_BUILTIN_EVSTWHO
:
8898 case SPE_BUILTIN_EVSTWWE
:
8899 case SPE_BUILTIN_EVSTWWO
:
8900 arg1
= CALL_EXPR_ARG (exp
, 2);
8901 if (TREE_CODE (arg1
) != INTEGER_CST
8902 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
8904 error ("argument 2 must be a 5-bit unsigned literal");
8912 /* The evsplat*i instructions are not quite generic. */
8915 case SPE_BUILTIN_EVSPLATFI
:
8916 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
8918 case SPE_BUILTIN_EVSPLATI
:
8919 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
8925 d
= (struct builtin_description
*) bdesc_2arg_spe
;
8926 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
8927 if (d
->code
== fcode
)
8928 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
8930 d
= (struct builtin_description
*) bdesc_spe_predicates
;
8931 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
8932 if (d
->code
== fcode
)
8933 return spe_expand_predicate_builtin (d
->icode
, exp
, target
);
8935 d
= (struct builtin_description
*) bdesc_spe_evsel
;
8936 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
8937 if (d
->code
== fcode
)
8938 return spe_expand_evsel_builtin (d
->icode
, exp
, target
);
8942 case SPE_BUILTIN_EVSTDDX
:
8943 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, exp
);
8944 case SPE_BUILTIN_EVSTDHX
:
8945 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, exp
);
8946 case SPE_BUILTIN_EVSTDWX
:
8947 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, exp
);
8948 case SPE_BUILTIN_EVSTWHEX
:
8949 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, exp
);
8950 case SPE_BUILTIN_EVSTWHOX
:
8951 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, exp
);
8952 case SPE_BUILTIN_EVSTWWEX
:
8953 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, exp
);
8954 case SPE_BUILTIN_EVSTWWOX
:
8955 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, exp
);
8956 case SPE_BUILTIN_EVSTDD
:
8957 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, exp
);
8958 case SPE_BUILTIN_EVSTDH
:
8959 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, exp
);
8960 case SPE_BUILTIN_EVSTDW
:
8961 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, exp
);
8962 case SPE_BUILTIN_EVSTWHE
:
8963 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, exp
);
8964 case SPE_BUILTIN_EVSTWHO
:
8965 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, exp
);
8966 case SPE_BUILTIN_EVSTWWE
:
8967 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, exp
);
8968 case SPE_BUILTIN_EVSTWWO
:
8969 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, exp
);
8970 case SPE_BUILTIN_MFSPEFSCR
:
8971 icode
= CODE_FOR_spe_mfspefscr
;
8972 tmode
= insn_data
[icode
].operand
[0].mode
;
8975 || GET_MODE (target
) != tmode
8976 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8977 target
= gen_reg_rtx (tmode
);
8979 pat
= GEN_FCN (icode
) (target
);
8984 case SPE_BUILTIN_MTSPEFSCR
:
8985 icode
= CODE_FOR_spe_mtspefscr
;
8986 arg0
= CALL_EXPR_ARG (exp
, 0);
8987 op0
= expand_normal (arg0
);
8988 mode0
= insn_data
[icode
].operand
[0].mode
;
8990 if (arg0
== error_mark_node
)
8993 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8994 op0
= copy_to_mode_reg (mode0
, op0
);
8996 pat
= GEN_FCN (icode
) (op0
);
9009 paired_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
9011 rtx pat
, scratch
, tmp
;
9012 tree form
= CALL_EXPR_ARG (exp
, 0);
9013 tree arg0
= CALL_EXPR_ARG (exp
, 1);
9014 tree arg1
= CALL_EXPR_ARG (exp
, 2);
9015 rtx op0
= expand_normal (arg0
);
9016 rtx op1
= expand_normal (arg1
);
9017 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
9018 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
9022 if (TREE_CODE (form
) != INTEGER_CST
)
9024 error ("argument 1 of __builtin_paired_predicate must be a constant");
9028 form_int
= TREE_INT_CST_LOW (form
);
9030 gcc_assert (mode0
== mode1
);
9032 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
9036 || GET_MODE (target
) != SImode
9037 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
9038 target
= gen_reg_rtx (SImode
);
9039 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
9040 op0
= copy_to_mode_reg (mode0
, op0
);
9041 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
9042 op1
= copy_to_mode_reg (mode1
, op1
);
9044 scratch
= gen_reg_rtx (CCFPmode
);
9046 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
9068 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
9071 error ("argument 1 of __builtin_paired_predicate is out of range");
9075 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
9076 emit_move_insn (target
, tmp
);
9081 spe_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
9083 rtx pat
, scratch
, tmp
;
9084 tree form
= CALL_EXPR_ARG (exp
, 0);
9085 tree arg0
= CALL_EXPR_ARG (exp
, 1);
9086 tree arg1
= CALL_EXPR_ARG (exp
, 2);
9087 rtx op0
= expand_normal (arg0
);
9088 rtx op1
= expand_normal (arg1
);
9089 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
9090 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
9094 if (TREE_CODE (form
) != INTEGER_CST
)
9096 error ("argument 1 of __builtin_spe_predicate must be a constant");
9100 form_int
= TREE_INT_CST_LOW (form
);
9102 gcc_assert (mode0
== mode1
);
9104 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
9108 || GET_MODE (target
) != SImode
9109 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
9110 target
= gen_reg_rtx (SImode
);
9112 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
9113 op0
= copy_to_mode_reg (mode0
, op0
);
9114 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
9115 op1
= copy_to_mode_reg (mode1
, op1
);
9117 scratch
= gen_reg_rtx (CCmode
);
9119 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
9124 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
9125 _lower_. We use one compare, but look in different bits of the
9126 CR for each variant.
9128 There are 2 elements in each SPE simd type (upper/lower). The CR
9129 bits are set as follows:
9131 BIT0 | BIT 1 | BIT 2 | BIT 3
9132 U | L | (U | L) | (U & L)
9134 So, for an "all" relationship, BIT 3 would be set.
9135 For an "any" relationship, BIT 2 would be set. Etc.
9137 Following traditional nomenclature, these bits map to:
9139 BIT0 | BIT 1 | BIT 2 | BIT 3
9142 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
9147 /* All variant. OV bit. */
9149 /* We need to get to the OV bit, which is the ORDERED bit. We
9150 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
9151 that's ugly and will make validate_condition_mode die.
9152 So let's just use another pattern. */
9153 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
9155 /* Any variant. EQ bit. */
9159 /* Upper variant. LT bit. */
9163 /* Lower variant. GT bit. */
9168 error ("argument 1 of __builtin_spe_predicate is out of range");
9172 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
9173 emit_move_insn (target
, tmp
);
9178 /* The evsel builtins look like this:
9180 e = __builtin_spe_evsel_OP (a, b, c, d);
9184 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
9185 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
9189 spe_expand_evsel_builtin (enum insn_code icode
, tree exp
, rtx target
)
9192 tree arg0
= CALL_EXPR_ARG (exp
, 0);
9193 tree arg1
= CALL_EXPR_ARG (exp
, 1);
9194 tree arg2
= CALL_EXPR_ARG (exp
, 2);
9195 tree arg3
= CALL_EXPR_ARG (exp
, 3);
9196 rtx op0
= expand_normal (arg0
);
9197 rtx op1
= expand_normal (arg1
);
9198 rtx op2
= expand_normal (arg2
);
9199 rtx op3
= expand_normal (arg3
);
9200 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
9201 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
9203 gcc_assert (mode0
== mode1
);
9205 if (arg0
== error_mark_node
|| arg1
== error_mark_node
9206 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
9210 || GET_MODE (target
) != mode0
9211 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
9212 target
= gen_reg_rtx (mode0
);
9214 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
9215 op0
= copy_to_mode_reg (mode0
, op0
);
9216 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
9217 op1
= copy_to_mode_reg (mode0
, op1
);
9218 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
9219 op2
= copy_to_mode_reg (mode0
, op2
);
9220 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
9221 op3
= copy_to_mode_reg (mode0
, op3
);
9223 /* Generate the compare. */
9224 scratch
= gen_reg_rtx (CCmode
);
9225 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
9230 if (mode0
== V2SImode
)
9231 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
9233 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
9238 /* Expand an expression EXP that calls a built-in function,
9239 with result going to TARGET if that's convenient
9240 (and in mode MODE if that's convenient).
9241 SUBTARGET may be used as the target for computing one of EXP's operands.
9242 IGNORE is nonzero if the value is to be ignored. */
9245 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
9246 enum machine_mode mode ATTRIBUTE_UNUSED
,
9247 int ignore ATTRIBUTE_UNUSED
)
9249 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
9250 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
9251 const struct builtin_description
*d
;
9256 if (fcode
== RS6000_BUILTIN_RECIP
)
9257 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3
, exp
, target
);
9259 if (fcode
== RS6000_BUILTIN_RECIPF
)
9260 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3
, exp
, target
);
9262 if (fcode
== RS6000_BUILTIN_RSQRTF
)
9263 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2
, exp
, target
);
9265 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_LOAD
9266 || fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
9268 int icode
= (int) CODE_FOR_altivec_lvsr
;
9269 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
9270 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
9274 gcc_assert (TARGET_ALTIVEC
);
9276 arg
= CALL_EXPR_ARG (exp
, 0);
9277 gcc_assert (TREE_CODE (TREE_TYPE (arg
)) == POINTER_TYPE
);
9278 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
9279 addr
= memory_address (mode
, op
);
9280 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
9284 /* For the load case need to negate the address. */
9285 op
= gen_reg_rtx (GET_MODE (addr
));
9286 emit_insn (gen_rtx_SET (VOIDmode
, op
,
9287 gen_rtx_NEG (GET_MODE (addr
), addr
)));
9289 op
= gen_rtx_MEM (mode
, op
);
9292 || GET_MODE (target
) != tmode
9293 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
9294 target
= gen_reg_rtx (tmode
);
9296 /*pat = gen_altivec_lvsr (target, op);*/
9297 pat
= GEN_FCN (icode
) (target
, op
);
9305 /* FIXME: There's got to be a nicer way to handle this case than
9306 constructing a new CALL_EXPR. */
9307 if (fcode
== ALTIVEC_BUILTIN_VCFUX
9308 || fcode
== ALTIVEC_BUILTIN_VCFSX
9309 || fcode
== ALTIVEC_BUILTIN_VCTUXS
9310 || fcode
== ALTIVEC_BUILTIN_VCTSXS
)
9312 if (call_expr_nargs (exp
) == 1)
9313 exp
= build_call_nary (TREE_TYPE (exp
), CALL_EXPR_FN (exp
),
9314 2, CALL_EXPR_ARG (exp
, 0), integer_zero_node
);
9319 ret
= altivec_expand_builtin (exp
, target
, &success
);
9326 ret
= spe_expand_builtin (exp
, target
, &success
);
9331 if (TARGET_PAIRED_FLOAT
)
9333 ret
= paired_expand_builtin (exp
, target
, &success
);
9339 gcc_assert (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
);
9341 /* Handle simple unary operations. */
9342 d
= (struct builtin_description
*) bdesc_1arg
;
9343 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
9344 if (d
->code
== fcode
)
9345 return rs6000_expand_unop_builtin (d
->icode
, exp
, target
);
9347 /* Handle simple binary operations. */
9348 d
= (struct builtin_description
*) bdesc_2arg
;
9349 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
9350 if (d
->code
== fcode
)
9351 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
9353 /* Handle simple ternary operations. */
9355 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
9356 if (d
->code
== fcode
)
9357 return rs6000_expand_ternop_builtin (d
->icode
, exp
, target
);
9363 rs6000_init_builtins (void)
9367 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
9368 V2SF_type_node
= build_vector_type (float_type_node
, 2);
9369 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
9370 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
9371 V4SF_type_node
= build_vector_type (float_type_node
, 4);
9372 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
9373 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
9375 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
9376 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
9377 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
9379 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
9380 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
9381 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
9382 opaque_V4SI_type_node
= build_opaque_vector_type (intSI_type_node
, 4);
9384 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
9385 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
9386 'vector unsigned short'. */
9388 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
9389 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
9390 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
9391 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
9393 long_integer_type_internal_node
= long_integer_type_node
;
9394 long_unsigned_type_internal_node
= long_unsigned_type_node
;
9395 intQI_type_internal_node
= intQI_type_node
;
9396 uintQI_type_internal_node
= unsigned_intQI_type_node
;
9397 intHI_type_internal_node
= intHI_type_node
;
9398 uintHI_type_internal_node
= unsigned_intHI_type_node
;
9399 intSI_type_internal_node
= intSI_type_node
;
9400 uintSI_type_internal_node
= unsigned_intSI_type_node
;
9401 float_type_internal_node
= float_type_node
;
9402 void_type_internal_node
= void_type_node
;
9404 tdecl
= build_decl (TYPE_DECL
, get_identifier ("__bool char"),
9405 bool_char_type_node
);
9406 TYPE_NAME (bool_char_type_node
) = tdecl
;
9407 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9408 tdecl
= build_decl (TYPE_DECL
, get_identifier ("__bool short"),
9409 bool_short_type_node
);
9410 TYPE_NAME (bool_short_type_node
) = tdecl
;
9411 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9412 tdecl
= build_decl (TYPE_DECL
, get_identifier ("__bool int"),
9413 bool_int_type_node
);
9414 TYPE_NAME (bool_int_type_node
) = tdecl
;
9415 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9416 tdecl
= build_decl (TYPE_DECL
, get_identifier ("__pixel"),
9418 TYPE_NAME (pixel_type_node
) = tdecl
;
9419 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9421 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
9422 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
9423 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
9424 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
9426 tdecl
= build_decl (TYPE_DECL
, get_identifier ("__vector unsigned char"),
9427 unsigned_V16QI_type_node
);
9428 TYPE_NAME (unsigned_V16QI_type_node
) = tdecl
;
9429 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9430 tdecl
= build_decl (TYPE_DECL
, get_identifier ("__vector signed char"),
9432 TYPE_NAME (V16QI_type_node
) = tdecl
;
9433 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9434 tdecl
= build_decl (TYPE_DECL
, get_identifier ("__vector __bool char"),
9435 bool_V16QI_type_node
);
9436 TYPE_NAME ( bool_V16QI_type_node
) = tdecl
;
9437 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9439 tdecl
= build_decl (TYPE_DECL
, get_identifier ("__vector unsigned short"),
9440 unsigned_V8HI_type_node
);
9441 TYPE_NAME (unsigned_V8HI_type_node
) = tdecl
;
9442 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9443 tdecl
= build_decl (TYPE_DECL
, get_identifier ("__vector signed short"),
9445 TYPE_NAME (V8HI_type_node
) = tdecl
;
9446 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9447 tdecl
= build_decl (TYPE_DECL
, get_identifier ("__vector __bool short"),
9448 bool_V8HI_type_node
);
9449 TYPE_NAME (bool_V8HI_type_node
) = tdecl
;
9450 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9452 tdecl
= build_decl (TYPE_DECL
, get_identifier ("__vector unsigned int"),
9453 unsigned_V4SI_type_node
);
9454 TYPE_NAME (unsigned_V4SI_type_node
) = tdecl
;
9455 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9456 tdecl
= build_decl (TYPE_DECL
, get_identifier ("__vector signed int"),
9458 TYPE_NAME (V4SI_type_node
) = tdecl
;
9459 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9460 tdecl
= build_decl (TYPE_DECL
, get_identifier ("__vector __bool int"),
9461 bool_V4SI_type_node
);
9462 TYPE_NAME (bool_V4SI_type_node
) = tdecl
;
9463 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9465 tdecl
= build_decl (TYPE_DECL
, get_identifier ("__vector float"),
9467 TYPE_NAME (V4SF_type_node
) = tdecl
;
9468 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9469 tdecl
= build_decl (TYPE_DECL
, get_identifier ("__vector __pixel"),
9470 pixel_V8HI_type_node
);
9471 TYPE_NAME (pixel_V8HI_type_node
) = tdecl
;
9472 (*lang_hooks
.decls
.pushdecl
) (tdecl
);
9474 if (TARGET_PAIRED_FLOAT
)
9475 paired_init_builtins ();
9477 spe_init_builtins ();
9479 altivec_init_builtins ();
9480 if (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
)
9481 rs6000_common_init_builtins ();
9482 if (TARGET_PPC_GFXOPT
)
9484 tree ftype
= build_function_type_list (float_type_node
,
9488 def_builtin (MASK_PPC_GFXOPT
, "__builtin_recipdivf", ftype
,
9489 RS6000_BUILTIN_RECIPF
);
9491 ftype
= build_function_type_list (float_type_node
,
9494 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrtf", ftype
,
9495 RS6000_BUILTIN_RSQRTF
);
9499 tree ftype
= build_function_type_list (double_type_node
,
9503 def_builtin (MASK_POPCNTB
, "__builtin_recipdiv", ftype
,
9504 RS6000_BUILTIN_RECIP
);
9509 /* AIX libm provides clog as __clog. */
9510 if (built_in_decls
[BUILT_IN_CLOG
])
9511 set_user_assembler_name (built_in_decls
[BUILT_IN_CLOG
], "__clog");
9514 #ifdef SUBTARGET_INIT_BUILTINS
9515 SUBTARGET_INIT_BUILTINS
;
9519 /* Search through a set of builtins and enable the mask bits.
9520 DESC is an array of builtins.
9521 SIZE is the total number of builtins.
9522 START is the builtin enum at which to start.
9523 END is the builtin enum at which to end. */
9525 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
9526 enum rs6000_builtins start
,
9527 enum rs6000_builtins end
)
9531 for (i
= 0; i
< size
; ++i
)
9532 if (desc
[i
].code
== start
)
9538 for (; i
< size
; ++i
)
9540 /* Flip all the bits on. */
9541 desc
[i
].mask
= target_flags
;
9542 if (desc
[i
].code
== end
)
9548 spe_init_builtins (void)
9550 tree endlink
= void_list_node
;
9551 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
9552 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
9553 struct builtin_description
*d
;
9556 tree v2si_ftype_4_v2si
9557 = build_function_type
9558 (opaque_V2SI_type_node
,
9559 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9560 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9561 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9562 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9565 tree v2sf_ftype_4_v2sf
9566 = build_function_type
9567 (opaque_V2SF_type_node
,
9568 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9569 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9570 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9571 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9574 tree int_ftype_int_v2si_v2si
9575 = build_function_type
9577 tree_cons (NULL_TREE
, integer_type_node
,
9578 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9579 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9582 tree int_ftype_int_v2sf_v2sf
9583 = build_function_type
9585 tree_cons (NULL_TREE
, integer_type_node
,
9586 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9587 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9590 tree void_ftype_v2si_puint_int
9591 = build_function_type (void_type_node
,
9592 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9593 tree_cons (NULL_TREE
, puint_type_node
,
9594 tree_cons (NULL_TREE
,
9598 tree void_ftype_v2si_puint_char
9599 = build_function_type (void_type_node
,
9600 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9601 tree_cons (NULL_TREE
, puint_type_node
,
9602 tree_cons (NULL_TREE
,
9606 tree void_ftype_v2si_pv2si_int
9607 = build_function_type (void_type_node
,
9608 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9609 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
9610 tree_cons (NULL_TREE
,
9614 tree void_ftype_v2si_pv2si_char
9615 = build_function_type (void_type_node
,
9616 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9617 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
9618 tree_cons (NULL_TREE
,
9623 = build_function_type (void_type_node
,
9624 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
9627 = build_function_type (integer_type_node
, endlink
);
9629 tree v2si_ftype_pv2si_int
9630 = build_function_type (opaque_V2SI_type_node
,
9631 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
9632 tree_cons (NULL_TREE
, integer_type_node
,
9635 tree v2si_ftype_puint_int
9636 = build_function_type (opaque_V2SI_type_node
,
9637 tree_cons (NULL_TREE
, puint_type_node
,
9638 tree_cons (NULL_TREE
, integer_type_node
,
9641 tree v2si_ftype_pushort_int
9642 = build_function_type (opaque_V2SI_type_node
,
9643 tree_cons (NULL_TREE
, pushort_type_node
,
9644 tree_cons (NULL_TREE
, integer_type_node
,
9647 tree v2si_ftype_signed_char
9648 = build_function_type (opaque_V2SI_type_node
,
9649 tree_cons (NULL_TREE
, signed_char_type_node
,
9652 /* The initialization of the simple binary and unary builtins is
9653 done in rs6000_common_init_builtins, but we have to enable the
9654 mask bits here manually because we have run out of `target_flags'
9655 bits. We really need to redesign this mask business. */
9657 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
9658 ARRAY_SIZE (bdesc_2arg
),
9661 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
9662 ARRAY_SIZE (bdesc_1arg
),
9664 SPE_BUILTIN_EVSUBFUSIAAW
);
9665 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
9666 ARRAY_SIZE (bdesc_spe_predicates
),
9667 SPE_BUILTIN_EVCMPEQ
,
9668 SPE_BUILTIN_EVFSTSTLT
);
9669 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
9670 ARRAY_SIZE (bdesc_spe_evsel
),
9671 SPE_BUILTIN_EVSEL_CMPGTS
,
9672 SPE_BUILTIN_EVSEL_FSTSTEQ
);
9674 (*lang_hooks
.decls
.pushdecl
)
9675 (build_decl (TYPE_DECL
, get_identifier ("__ev64_opaque__"),
9676 opaque_V2SI_type_node
));
9678 /* Initialize irregular SPE builtins. */
9680 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
9681 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
9682 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
9683 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
9684 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
9685 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
9686 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
9687 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
9688 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
9689 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
9690 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
9691 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
9692 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
9693 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
9694 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
9695 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
9696 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
9697 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
9700 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
9701 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
9702 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
9703 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
9704 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
9705 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
9706 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
9707 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
9708 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
9709 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
9710 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
9711 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
9712 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
9713 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
9714 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
9715 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
9716 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
9717 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
9718 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
9719 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
9720 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
9721 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
9724 d
= (struct builtin_description
*) bdesc_spe_predicates
;
9725 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
9729 switch (insn_data
[d
->icode
].operand
[1].mode
)
9732 type
= int_ftype_int_v2si_v2si
;
9735 type
= int_ftype_int_v2sf_v2sf
;
9741 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9744 /* Evsel predicates. */
9745 d
= (struct builtin_description
*) bdesc_spe_evsel
;
9746 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
9750 switch (insn_data
[d
->icode
].operand
[1].mode
)
9753 type
= v2si_ftype_4_v2si
;
9756 type
= v2sf_ftype_4_v2sf
;
9762 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9767 paired_init_builtins (void)
9769 const struct builtin_description
*d
;
9771 tree endlink
= void_list_node
;
9773 tree int_ftype_int_v2sf_v2sf
9774 = build_function_type
9776 tree_cons (NULL_TREE
, integer_type_node
,
9777 tree_cons (NULL_TREE
, V2SF_type_node
,
9778 tree_cons (NULL_TREE
, V2SF_type_node
,
9780 tree pcfloat_type_node
=
9781 build_pointer_type (build_qualified_type
9782 (float_type_node
, TYPE_QUAL_CONST
));
9784 tree v2sf_ftype_long_pcfloat
= build_function_type_list (V2SF_type_node
,
9785 long_integer_type_node
,
9788 tree void_ftype_v2sf_long_pcfloat
=
9789 build_function_type_list (void_type_node
,
9791 long_integer_type_node
,
9796 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat
,
9800 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat
,
9801 PAIRED_BUILTIN_STX
);
9804 d
= bdesc_paired_preds
;
9805 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); ++i
, d
++)
9809 switch (insn_data
[d
->icode
].operand
[1].mode
)
9812 type
= int_ftype_int_v2sf_v2sf
;
9818 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9823 altivec_init_builtins (void)
9825 const struct builtin_description
*d
;
9826 const struct builtin_description_predicates
*dp
;
9830 tree pfloat_type_node
= build_pointer_type (float_type_node
);
9831 tree pint_type_node
= build_pointer_type (integer_type_node
);
9832 tree pshort_type_node
= build_pointer_type (short_integer_type_node
);
9833 tree pchar_type_node
= build_pointer_type (char_type_node
);
9835 tree pvoid_type_node
= build_pointer_type (void_type_node
);
9837 tree pcfloat_type_node
= build_pointer_type (build_qualified_type (float_type_node
, TYPE_QUAL_CONST
));
9838 tree pcint_type_node
= build_pointer_type (build_qualified_type (integer_type_node
, TYPE_QUAL_CONST
));
9839 tree pcshort_type_node
= build_pointer_type (build_qualified_type (short_integer_type_node
, TYPE_QUAL_CONST
));
9840 tree pcchar_type_node
= build_pointer_type (build_qualified_type (char_type_node
, TYPE_QUAL_CONST
));
9842 tree pcvoid_type_node
= build_pointer_type (build_qualified_type (void_type_node
, TYPE_QUAL_CONST
));
9844 tree int_ftype_opaque
9845 = build_function_type_list (integer_type_node
,
9846 opaque_V4SI_type_node
, NULL_TREE
);
9847 tree opaque_ftype_opaque
9848 = build_function_type (integer_type_node
,
9850 tree opaque_ftype_opaque_int
9851 = build_function_type_list (opaque_V4SI_type_node
,
9852 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
9853 tree opaque_ftype_opaque_opaque_int
9854 = build_function_type_list (opaque_V4SI_type_node
,
9855 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
9856 integer_type_node
, NULL_TREE
);
9857 tree int_ftype_int_opaque_opaque
9858 = build_function_type_list (integer_type_node
,
9859 integer_type_node
, opaque_V4SI_type_node
,
9860 opaque_V4SI_type_node
, NULL_TREE
);
9861 tree int_ftype_int_v4si_v4si
9862 = build_function_type_list (integer_type_node
,
9863 integer_type_node
, V4SI_type_node
,
9864 V4SI_type_node
, NULL_TREE
);
9865 tree v4sf_ftype_pcfloat
9866 = build_function_type_list (V4SF_type_node
, pcfloat_type_node
, NULL_TREE
);
9867 tree void_ftype_pfloat_v4sf
9868 = build_function_type_list (void_type_node
,
9869 pfloat_type_node
, V4SF_type_node
, NULL_TREE
);
9870 tree v4si_ftype_pcint
9871 = build_function_type_list (V4SI_type_node
, pcint_type_node
, NULL_TREE
);
9872 tree void_ftype_pint_v4si
9873 = build_function_type_list (void_type_node
,
9874 pint_type_node
, V4SI_type_node
, NULL_TREE
);
9875 tree v8hi_ftype_pcshort
9876 = build_function_type_list (V8HI_type_node
, pcshort_type_node
, NULL_TREE
);
9877 tree void_ftype_pshort_v8hi
9878 = build_function_type_list (void_type_node
,
9879 pshort_type_node
, V8HI_type_node
, NULL_TREE
);
9880 tree v16qi_ftype_pcchar
9881 = build_function_type_list (V16QI_type_node
, pcchar_type_node
, NULL_TREE
);
9882 tree void_ftype_pchar_v16qi
9883 = build_function_type_list (void_type_node
,
9884 pchar_type_node
, V16QI_type_node
, NULL_TREE
);
9885 tree void_ftype_v4si
9886 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
9887 tree v8hi_ftype_void
9888 = build_function_type (V8HI_type_node
, void_list_node
);
9889 tree void_ftype_void
9890 = build_function_type (void_type_node
, void_list_node
);
9892 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
9894 tree opaque_ftype_long_pcvoid
9895 = build_function_type_list (opaque_V4SI_type_node
,
9896 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9897 tree v16qi_ftype_long_pcvoid
9898 = build_function_type_list (V16QI_type_node
,
9899 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9900 tree v8hi_ftype_long_pcvoid
9901 = build_function_type_list (V8HI_type_node
,
9902 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9903 tree v4si_ftype_long_pcvoid
9904 = build_function_type_list (V4SI_type_node
,
9905 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9907 tree void_ftype_opaque_long_pvoid
9908 = build_function_type_list (void_type_node
,
9909 opaque_V4SI_type_node
, long_integer_type_node
,
9910 pvoid_type_node
, NULL_TREE
);
9911 tree void_ftype_v4si_long_pvoid
9912 = build_function_type_list (void_type_node
,
9913 V4SI_type_node
, long_integer_type_node
,
9914 pvoid_type_node
, NULL_TREE
);
9915 tree void_ftype_v16qi_long_pvoid
9916 = build_function_type_list (void_type_node
,
9917 V16QI_type_node
, long_integer_type_node
,
9918 pvoid_type_node
, NULL_TREE
);
9919 tree void_ftype_v8hi_long_pvoid
9920 = build_function_type_list (void_type_node
,
9921 V8HI_type_node
, long_integer_type_node
,
9922 pvoid_type_node
, NULL_TREE
);
9923 tree int_ftype_int_v8hi_v8hi
9924 = build_function_type_list (integer_type_node
,
9925 integer_type_node
, V8HI_type_node
,
9926 V8HI_type_node
, NULL_TREE
);
9927 tree int_ftype_int_v16qi_v16qi
9928 = build_function_type_list (integer_type_node
,
9929 integer_type_node
, V16QI_type_node
,
9930 V16QI_type_node
, NULL_TREE
);
9931 tree int_ftype_int_v4sf_v4sf
9932 = build_function_type_list (integer_type_node
,
9933 integer_type_node
, V4SF_type_node
,
9934 V4SF_type_node
, NULL_TREE
);
9935 tree v4si_ftype_v4si
9936 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
9937 tree v8hi_ftype_v8hi
9938 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
9939 tree v16qi_ftype_v16qi
9940 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
9941 tree v4sf_ftype_v4sf
9942 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
9943 tree void_ftype_pcvoid_int_int
9944 = build_function_type_list (void_type_node
,
9945 pcvoid_type_node
, integer_type_node
,
9946 integer_type_node
, NULL_TREE
);
9948 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat
,
9949 ALTIVEC_BUILTIN_LD_INTERNAL_4sf
);
9950 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf
,
9951 ALTIVEC_BUILTIN_ST_INTERNAL_4sf
);
9952 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint
,
9953 ALTIVEC_BUILTIN_LD_INTERNAL_4si
);
9954 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si
,
9955 ALTIVEC_BUILTIN_ST_INTERNAL_4si
);
9956 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort
,
9957 ALTIVEC_BUILTIN_LD_INTERNAL_8hi
);
9958 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi
,
9959 ALTIVEC_BUILTIN_ST_INTERNAL_8hi
);
9960 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar
,
9961 ALTIVEC_BUILTIN_LD_INTERNAL_16qi
);
9962 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi
,
9963 ALTIVEC_BUILTIN_ST_INTERNAL_16qi
);
9964 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
9965 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
9966 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
9967 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
9968 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
9969 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
9970 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
9971 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
9972 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
9973 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
9974 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
9975 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
9976 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
9977 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
9978 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
9979 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
9980 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
9981 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
9982 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
9983 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
9984 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
9985 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
9986 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
9987 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
9988 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
9989 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
9990 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
9991 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
9992 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
9993 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
9995 if (rs6000_cpu
== PROCESSOR_CELL
)
9997 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLX
);
9998 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLXL
);
9999 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRX
);
10000 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRXL
);
10002 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLX
);
10003 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLXL
);
10004 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRX
);
10005 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRXL
);
10007 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLX
);
10008 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLXL
);
10009 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRX
);
10010 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRXL
);
10012 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLX
);
10013 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLXL
);
10014 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRX
);
10015 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRXL
);
10017 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
10018 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splats", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_SPLATS
);
10019 def_builtin (MASK_ALTIVEC
, "__builtin_vec_promote", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_PROMOTE
);
10021 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
10022 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
10023 def_builtin (MASK_ALTIVEC
, "__builtin_vec_extract", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_EXTRACT
);
10024 def_builtin (MASK_ALTIVEC
, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_INSERT
);
10025 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
10026 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
10027 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
10028 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
10029 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
10030 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
10031 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
10032 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
10034 /* Add the DST variants. */
10036 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
10037 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
10039 /* Initialize the predicates. */
10040 dp
= bdesc_altivec_preds
;
10041 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
10043 enum machine_mode mode1
;
10045 bool is_overloaded
= dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10046 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10051 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
10056 type
= int_ftype_int_opaque_opaque
;
10059 type
= int_ftype_int_v4si_v4si
;
10062 type
= int_ftype_int_v8hi_v8hi
;
10065 type
= int_ftype_int_v16qi_v16qi
;
10068 type
= int_ftype_int_v4sf_v4sf
;
10071 gcc_unreachable ();
10074 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
10077 /* Initialize the abs* operators. */
10079 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
10081 enum machine_mode mode0
;
10084 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10089 type
= v4si_ftype_v4si
;
10092 type
= v8hi_ftype_v8hi
;
10095 type
= v16qi_ftype_v16qi
;
10098 type
= v4sf_ftype_v4sf
;
10101 gcc_unreachable ();
10104 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10107 if (TARGET_ALTIVEC
)
10111 /* Initialize target builtin that implements
10112 targetm.vectorize.builtin_mask_for_load. */
10114 decl
= add_builtin_function ("__builtin_altivec_mask_for_load",
10115 v16qi_ftype_long_pcvoid
,
10116 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
10117 BUILT_IN_MD
, NULL
, NULL_TREE
);
10118 TREE_READONLY (decl
) = 1;
10119 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
10120 altivec_builtin_mask_for_load
= decl
;
10123 /* Access to the vec_init patterns. */
10124 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
10125 integer_type_node
, integer_type_node
,
10126 integer_type_node
, NULL_TREE
);
10127 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4si", ftype
,
10128 ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
10130 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
10131 short_integer_type_node
,
10132 short_integer_type_node
,
10133 short_integer_type_node
,
10134 short_integer_type_node
,
10135 short_integer_type_node
,
10136 short_integer_type_node
,
10137 short_integer_type_node
, NULL_TREE
);
10138 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v8hi", ftype
,
10139 ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
10141 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
10142 char_type_node
, char_type_node
,
10143 char_type_node
, char_type_node
,
10144 char_type_node
, char_type_node
,
10145 char_type_node
, char_type_node
,
10146 char_type_node
, char_type_node
,
10147 char_type_node
, char_type_node
,
10148 char_type_node
, char_type_node
,
10149 char_type_node
, NULL_TREE
);
10150 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v16qi", ftype
,
10151 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
10153 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
10154 float_type_node
, float_type_node
,
10155 float_type_node
, NULL_TREE
);
10156 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4sf", ftype
,
10157 ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
10159 /* Access to the vec_set patterns. */
10160 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
10162 integer_type_node
, NULL_TREE
);
10163 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4si", ftype
,
10164 ALTIVEC_BUILTIN_VEC_SET_V4SI
);
10166 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
10168 integer_type_node
, NULL_TREE
);
10169 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v8hi", ftype
,
10170 ALTIVEC_BUILTIN_VEC_SET_V8HI
);
10172 ftype
= build_function_type_list (V8HI_type_node
, V16QI_type_node
,
10174 integer_type_node
, NULL_TREE
);
10175 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v16qi", ftype
,
10176 ALTIVEC_BUILTIN_VEC_SET_V16QI
);
10178 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
10180 integer_type_node
, NULL_TREE
);
10181 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4sf", ftype
,
10182 ALTIVEC_BUILTIN_VEC_SET_V4SF
);
10184 /* Access to the vec_extract patterns. */
10185 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
10186 integer_type_node
, NULL_TREE
);
10187 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4si", ftype
,
10188 ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
10190 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
10191 integer_type_node
, NULL_TREE
);
10192 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v8hi", ftype
,
10193 ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
10195 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
10196 integer_type_node
, NULL_TREE
);
10197 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v16qi", ftype
,
10198 ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
10200 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
10201 integer_type_node
, NULL_TREE
);
10202 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4sf", ftype
,
10203 ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
10207 rs6000_common_init_builtins (void)
10209 const struct builtin_description
*d
;
10212 tree v2sf_ftype_v2sf_v2sf_v2sf
10213 = build_function_type_list (V2SF_type_node
,
10214 V2SF_type_node
, V2SF_type_node
,
10215 V2SF_type_node
, NULL_TREE
);
10217 tree v4sf_ftype_v4sf_v4sf_v16qi
10218 = build_function_type_list (V4SF_type_node
,
10219 V4SF_type_node
, V4SF_type_node
,
10220 V16QI_type_node
, NULL_TREE
);
10221 tree v4si_ftype_v4si_v4si_v16qi
10222 = build_function_type_list (V4SI_type_node
,
10223 V4SI_type_node
, V4SI_type_node
,
10224 V16QI_type_node
, NULL_TREE
);
10225 tree v8hi_ftype_v8hi_v8hi_v16qi
10226 = build_function_type_list (V8HI_type_node
,
10227 V8HI_type_node
, V8HI_type_node
,
10228 V16QI_type_node
, NULL_TREE
);
10229 tree v16qi_ftype_v16qi_v16qi_v16qi
10230 = build_function_type_list (V16QI_type_node
,
10231 V16QI_type_node
, V16QI_type_node
,
10232 V16QI_type_node
, NULL_TREE
);
10233 tree v4si_ftype_int
10234 = build_function_type_list (V4SI_type_node
, integer_type_node
, NULL_TREE
);
10235 tree v8hi_ftype_int
10236 = build_function_type_list (V8HI_type_node
, integer_type_node
, NULL_TREE
);
10237 tree v16qi_ftype_int
10238 = build_function_type_list (V16QI_type_node
, integer_type_node
, NULL_TREE
);
10239 tree v8hi_ftype_v16qi
10240 = build_function_type_list (V8HI_type_node
, V16QI_type_node
, NULL_TREE
);
10241 tree v4sf_ftype_v4sf
10242 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10244 tree v2si_ftype_v2si_v2si
10245 = build_function_type_list (opaque_V2SI_type_node
,
10246 opaque_V2SI_type_node
,
10247 opaque_V2SI_type_node
, NULL_TREE
);
10249 tree v2sf_ftype_v2sf_v2sf_spe
10250 = build_function_type_list (opaque_V2SF_type_node
,
10251 opaque_V2SF_type_node
,
10252 opaque_V2SF_type_node
, NULL_TREE
);
10254 tree v2sf_ftype_v2sf_v2sf
10255 = build_function_type_list (V2SF_type_node
,
10257 V2SF_type_node
, NULL_TREE
);
10260 tree v2si_ftype_int_int
10261 = build_function_type_list (opaque_V2SI_type_node
,
10262 integer_type_node
, integer_type_node
,
10265 tree opaque_ftype_opaque
10266 = build_function_type_list (opaque_V4SI_type_node
,
10267 opaque_V4SI_type_node
, NULL_TREE
);
10269 tree v2si_ftype_v2si
10270 = build_function_type_list (opaque_V2SI_type_node
,
10271 opaque_V2SI_type_node
, NULL_TREE
);
10273 tree v2sf_ftype_v2sf_spe
10274 = build_function_type_list (opaque_V2SF_type_node
,
10275 opaque_V2SF_type_node
, NULL_TREE
);
10277 tree v2sf_ftype_v2sf
10278 = build_function_type_list (V2SF_type_node
,
10279 V2SF_type_node
, NULL_TREE
);
10281 tree v2sf_ftype_v2si
10282 = build_function_type_list (opaque_V2SF_type_node
,
10283 opaque_V2SI_type_node
, NULL_TREE
);
10285 tree v2si_ftype_v2sf
10286 = build_function_type_list (opaque_V2SI_type_node
,
10287 opaque_V2SF_type_node
, NULL_TREE
);
10289 tree v2si_ftype_v2si_char
10290 = build_function_type_list (opaque_V2SI_type_node
,
10291 opaque_V2SI_type_node
,
10292 char_type_node
, NULL_TREE
);
10294 tree v2si_ftype_int_char
10295 = build_function_type_list (opaque_V2SI_type_node
,
10296 integer_type_node
, char_type_node
, NULL_TREE
);
10298 tree v2si_ftype_char
10299 = build_function_type_list (opaque_V2SI_type_node
,
10300 char_type_node
, NULL_TREE
);
10302 tree int_ftype_int_int
10303 = build_function_type_list (integer_type_node
,
10304 integer_type_node
, integer_type_node
,
10307 tree opaque_ftype_opaque_opaque
10308 = build_function_type_list (opaque_V4SI_type_node
,
10309 opaque_V4SI_type_node
, opaque_V4SI_type_node
, NULL_TREE
);
10310 tree v4si_ftype_v4si_v4si
10311 = build_function_type_list (V4SI_type_node
,
10312 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
10313 tree v4sf_ftype_v4si_int
10314 = build_function_type_list (V4SF_type_node
,
10315 V4SI_type_node
, integer_type_node
, NULL_TREE
);
10316 tree v4si_ftype_v4sf_int
10317 = build_function_type_list (V4SI_type_node
,
10318 V4SF_type_node
, integer_type_node
, NULL_TREE
);
10319 tree v4si_ftype_v4si_int
10320 = build_function_type_list (V4SI_type_node
,
10321 V4SI_type_node
, integer_type_node
, NULL_TREE
);
10322 tree v8hi_ftype_v8hi_int
10323 = build_function_type_list (V8HI_type_node
,
10324 V8HI_type_node
, integer_type_node
, NULL_TREE
);
10325 tree v16qi_ftype_v16qi_int
10326 = build_function_type_list (V16QI_type_node
,
10327 V16QI_type_node
, integer_type_node
, NULL_TREE
);
10328 tree v16qi_ftype_v16qi_v16qi_int
10329 = build_function_type_list (V16QI_type_node
,
10330 V16QI_type_node
, V16QI_type_node
,
10331 integer_type_node
, NULL_TREE
);
10332 tree v8hi_ftype_v8hi_v8hi_int
10333 = build_function_type_list (V8HI_type_node
,
10334 V8HI_type_node
, V8HI_type_node
,
10335 integer_type_node
, NULL_TREE
);
10336 tree v4si_ftype_v4si_v4si_int
10337 = build_function_type_list (V4SI_type_node
,
10338 V4SI_type_node
, V4SI_type_node
,
10339 integer_type_node
, NULL_TREE
);
10340 tree v4sf_ftype_v4sf_v4sf_int
10341 = build_function_type_list (V4SF_type_node
,
10342 V4SF_type_node
, V4SF_type_node
,
10343 integer_type_node
, NULL_TREE
);
10344 tree v4sf_ftype_v4sf_v4sf
10345 = build_function_type_list (V4SF_type_node
,
10346 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10347 tree opaque_ftype_opaque_opaque_opaque
10348 = build_function_type_list (opaque_V4SI_type_node
,
10349 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
10350 opaque_V4SI_type_node
, NULL_TREE
);
10351 tree v4sf_ftype_v4sf_v4sf_v4si
10352 = build_function_type_list (V4SF_type_node
,
10353 V4SF_type_node
, V4SF_type_node
,
10354 V4SI_type_node
, NULL_TREE
);
10355 tree v4sf_ftype_v4sf_v4sf_v4sf
10356 = build_function_type_list (V4SF_type_node
,
10357 V4SF_type_node
, V4SF_type_node
,
10358 V4SF_type_node
, NULL_TREE
);
10359 tree v4si_ftype_v4si_v4si_v4si
10360 = build_function_type_list (V4SI_type_node
,
10361 V4SI_type_node
, V4SI_type_node
,
10362 V4SI_type_node
, NULL_TREE
);
10363 tree v8hi_ftype_v8hi_v8hi
10364 = build_function_type_list (V8HI_type_node
,
10365 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10366 tree v8hi_ftype_v8hi_v8hi_v8hi
10367 = build_function_type_list (V8HI_type_node
,
10368 V8HI_type_node
, V8HI_type_node
,
10369 V8HI_type_node
, NULL_TREE
);
10370 tree v4si_ftype_v8hi_v8hi_v4si
10371 = build_function_type_list (V4SI_type_node
,
10372 V8HI_type_node
, V8HI_type_node
,
10373 V4SI_type_node
, NULL_TREE
);
10374 tree v4si_ftype_v16qi_v16qi_v4si
10375 = build_function_type_list (V4SI_type_node
,
10376 V16QI_type_node
, V16QI_type_node
,
10377 V4SI_type_node
, NULL_TREE
);
10378 tree v16qi_ftype_v16qi_v16qi
10379 = build_function_type_list (V16QI_type_node
,
10380 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10381 tree v4si_ftype_v4sf_v4sf
10382 = build_function_type_list (V4SI_type_node
,
10383 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10384 tree v8hi_ftype_v16qi_v16qi
10385 = build_function_type_list (V8HI_type_node
,
10386 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10387 tree v4si_ftype_v8hi_v8hi
10388 = build_function_type_list (V4SI_type_node
,
10389 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10390 tree v8hi_ftype_v4si_v4si
10391 = build_function_type_list (V8HI_type_node
,
10392 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
10393 tree v16qi_ftype_v8hi_v8hi
10394 = build_function_type_list (V16QI_type_node
,
10395 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10396 tree v4si_ftype_v16qi_v4si
10397 = build_function_type_list (V4SI_type_node
,
10398 V16QI_type_node
, V4SI_type_node
, NULL_TREE
);
10399 tree v4si_ftype_v16qi_v16qi
10400 = build_function_type_list (V4SI_type_node
,
10401 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10402 tree v4si_ftype_v8hi_v4si
10403 = build_function_type_list (V4SI_type_node
,
10404 V8HI_type_node
, V4SI_type_node
, NULL_TREE
);
10405 tree v4si_ftype_v8hi
10406 = build_function_type_list (V4SI_type_node
, V8HI_type_node
, NULL_TREE
);
10407 tree int_ftype_v4si_v4si
10408 = build_function_type_list (integer_type_node
,
10409 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
10410 tree int_ftype_v4sf_v4sf
10411 = build_function_type_list (integer_type_node
,
10412 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10413 tree int_ftype_v16qi_v16qi
10414 = build_function_type_list (integer_type_node
,
10415 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10416 tree int_ftype_v8hi_v8hi
10417 = build_function_type_list (integer_type_node
,
10418 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10420 /* Add the simple ternary operators. */
10422 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
10424 enum machine_mode mode0
, mode1
, mode2
, mode3
;
10426 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10427 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10438 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
10441 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10442 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10443 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
10444 mode3
= insn_data
[d
->icode
].operand
[3].mode
;
10447 /* When all four are of the same mode. */
10448 if (mode0
== mode1
&& mode1
== mode2
&& mode2
== mode3
)
10453 type
= opaque_ftype_opaque_opaque_opaque
;
10456 type
= v4si_ftype_v4si_v4si_v4si
;
10459 type
= v4sf_ftype_v4sf_v4sf_v4sf
;
10462 type
= v8hi_ftype_v8hi_v8hi_v8hi
;
10465 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
10468 type
= v2sf_ftype_v2sf_v2sf_v2sf
;
10471 gcc_unreachable ();
10474 else if (mode0
== mode1
&& mode1
== mode2
&& mode3
== V16QImode
)
10479 type
= v4si_ftype_v4si_v4si_v16qi
;
10482 type
= v4sf_ftype_v4sf_v4sf_v16qi
;
10485 type
= v8hi_ftype_v8hi_v8hi_v16qi
;
10488 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
10491 gcc_unreachable ();
10494 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
10495 && mode3
== V4SImode
)
10496 type
= v4si_ftype_v16qi_v16qi_v4si
;
10497 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
10498 && mode3
== V4SImode
)
10499 type
= v4si_ftype_v8hi_v8hi_v4si
;
10500 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
10501 && mode3
== V4SImode
)
10502 type
= v4sf_ftype_v4sf_v4sf_v4si
;
10504 /* vchar, vchar, vchar, 4-bit literal. */
10505 else if (mode0
== V16QImode
&& mode1
== mode0
&& mode2
== mode0
10506 && mode3
== QImode
)
10507 type
= v16qi_ftype_v16qi_v16qi_int
;
10509 /* vshort, vshort, vshort, 4-bit literal. */
10510 else if (mode0
== V8HImode
&& mode1
== mode0
&& mode2
== mode0
10511 && mode3
== QImode
)
10512 type
= v8hi_ftype_v8hi_v8hi_int
;
10514 /* vint, vint, vint, 4-bit literal. */
10515 else if (mode0
== V4SImode
&& mode1
== mode0
&& mode2
== mode0
10516 && mode3
== QImode
)
10517 type
= v4si_ftype_v4si_v4si_int
;
10519 /* vfloat, vfloat, vfloat, 4-bit literal. */
10520 else if (mode0
== V4SFmode
&& mode1
== mode0
&& mode2
== mode0
10521 && mode3
== QImode
)
10522 type
= v4sf_ftype_v4sf_v4sf_int
;
10525 gcc_unreachable ();
10527 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10530 /* Add the simple binary operators. */
10531 d
= (struct builtin_description
*) bdesc_2arg
;
10532 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
10534 enum machine_mode mode0
, mode1
, mode2
;
10536 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10537 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10547 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
10550 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10551 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10552 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
10555 /* When all three operands are of the same mode. */
10556 if (mode0
== mode1
&& mode1
== mode2
)
10561 type
= opaque_ftype_opaque_opaque
;
10564 type
= v4sf_ftype_v4sf_v4sf
;
10567 type
= v4si_ftype_v4si_v4si
;
10570 type
= v16qi_ftype_v16qi_v16qi
;
10573 type
= v8hi_ftype_v8hi_v8hi
;
10576 type
= v2si_ftype_v2si_v2si
;
10579 if (TARGET_PAIRED_FLOAT
)
10580 type
= v2sf_ftype_v2sf_v2sf
;
10582 type
= v2sf_ftype_v2sf_v2sf_spe
;
10585 type
= int_ftype_int_int
;
10588 gcc_unreachable ();
10592 /* A few other combos we really don't want to do manually. */
10594 /* vint, vfloat, vfloat. */
10595 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
)
10596 type
= v4si_ftype_v4sf_v4sf
;
10598 /* vshort, vchar, vchar. */
10599 else if (mode0
== V8HImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
10600 type
= v8hi_ftype_v16qi_v16qi
;
10602 /* vint, vshort, vshort. */
10603 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
10604 type
= v4si_ftype_v8hi_v8hi
;
10606 /* vshort, vint, vint. */
10607 else if (mode0
== V8HImode
&& mode1
== V4SImode
&& mode2
== V4SImode
)
10608 type
= v8hi_ftype_v4si_v4si
;
10610 /* vchar, vshort, vshort. */
10611 else if (mode0
== V16QImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
10612 type
= v16qi_ftype_v8hi_v8hi
;
10614 /* vint, vchar, vint. */
10615 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V4SImode
)
10616 type
= v4si_ftype_v16qi_v4si
;
10618 /* vint, vchar, vchar. */
10619 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
10620 type
= v4si_ftype_v16qi_v16qi
;
10622 /* vint, vshort, vint. */
10623 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V4SImode
)
10624 type
= v4si_ftype_v8hi_v4si
;
10626 /* vint, vint, 5-bit literal. */
10627 else if (mode0
== V4SImode
&& mode1
== V4SImode
&& mode2
== QImode
)
10628 type
= v4si_ftype_v4si_int
;
10630 /* vshort, vshort, 5-bit literal. */
10631 else if (mode0
== V8HImode
&& mode1
== V8HImode
&& mode2
== QImode
)
10632 type
= v8hi_ftype_v8hi_int
;
10634 /* vchar, vchar, 5-bit literal. */
10635 else if (mode0
== V16QImode
&& mode1
== V16QImode
&& mode2
== QImode
)
10636 type
= v16qi_ftype_v16qi_int
;
10638 /* vfloat, vint, 5-bit literal. */
10639 else if (mode0
== V4SFmode
&& mode1
== V4SImode
&& mode2
== QImode
)
10640 type
= v4sf_ftype_v4si_int
;
10642 /* vint, vfloat, 5-bit literal. */
10643 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== QImode
)
10644 type
= v4si_ftype_v4sf_int
;
10646 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== SImode
)
10647 type
= v2si_ftype_int_int
;
10649 else if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
10650 type
= v2si_ftype_v2si_char
;
10652 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== QImode
)
10653 type
= v2si_ftype_int_char
;
10658 gcc_assert (mode0
== SImode
);
10662 type
= int_ftype_v4si_v4si
;
10665 type
= int_ftype_v4sf_v4sf
;
10668 type
= int_ftype_v16qi_v16qi
;
10671 type
= int_ftype_v8hi_v8hi
;
10674 gcc_unreachable ();
10678 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10681 /* Add the simple unary operators. */
10682 d
= (struct builtin_description
*) bdesc_1arg
;
10683 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
10685 enum machine_mode mode0
, mode1
;
10687 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10688 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10697 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
10700 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10701 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10704 if (mode0
== V4SImode
&& mode1
== QImode
)
10705 type
= v4si_ftype_int
;
10706 else if (mode0
== V8HImode
&& mode1
== QImode
)
10707 type
= v8hi_ftype_int
;
10708 else if (mode0
== V16QImode
&& mode1
== QImode
)
10709 type
= v16qi_ftype_int
;
10710 else if (mode0
== VOIDmode
&& mode1
== VOIDmode
)
10711 type
= opaque_ftype_opaque
;
10712 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
)
10713 type
= v4sf_ftype_v4sf
;
10714 else if (mode0
== V8HImode
&& mode1
== V16QImode
)
10715 type
= v8hi_ftype_v16qi
;
10716 else if (mode0
== V4SImode
&& mode1
== V8HImode
)
10717 type
= v4si_ftype_v8hi
;
10718 else if (mode0
== V2SImode
&& mode1
== V2SImode
)
10719 type
= v2si_ftype_v2si
;
10720 else if (mode0
== V2SFmode
&& mode1
== V2SFmode
)
10722 if (TARGET_PAIRED_FLOAT
)
10723 type
= v2sf_ftype_v2sf
;
10725 type
= v2sf_ftype_v2sf_spe
;
10727 else if (mode0
== V2SFmode
&& mode1
== V2SImode
)
10728 type
= v2sf_ftype_v2si
;
10729 else if (mode0
== V2SImode
&& mode1
== V2SFmode
)
10730 type
= v2si_ftype_v2sf
;
10731 else if (mode0
== V2SImode
&& mode1
== QImode
)
10732 type
= v2si_ftype_char
;
10734 gcc_unreachable ();
10736 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10741 rs6000_init_libfuncs (void)
10743 if (DEFAULT_ABI
!= ABI_V4
&& TARGET_XCOFF
10744 && !TARGET_POWER2
&& !TARGET_POWERPC
)
10746 /* AIX library routines for float->int conversion. */
10747 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
10748 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
10749 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
10750 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
10753 if (!TARGET_IEEEQUAD
)
10754 /* AIX/Darwin/64-bit Linux quad floating point routines. */
10755 if (!TARGET_XL_COMPAT
)
10757 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
10758 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
10759 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
10760 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
10762 if (!(TARGET_HARD_FLOAT
&& (TARGET_FPRS
|| TARGET_E500_DOUBLE
)))
10764 set_optab_libfunc (neg_optab
, TFmode
, "__gcc_qneg");
10765 set_optab_libfunc (eq_optab
, TFmode
, "__gcc_qeq");
10766 set_optab_libfunc (ne_optab
, TFmode
, "__gcc_qne");
10767 set_optab_libfunc (gt_optab
, TFmode
, "__gcc_qgt");
10768 set_optab_libfunc (ge_optab
, TFmode
, "__gcc_qge");
10769 set_optab_libfunc (lt_optab
, TFmode
, "__gcc_qlt");
10770 set_optab_libfunc (le_optab
, TFmode
, "__gcc_qle");
10772 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "__gcc_stoq");
10773 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "__gcc_dtoq");
10774 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "__gcc_qtos");
10775 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "__gcc_qtod");
10776 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "__gcc_qtoi");
10777 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "__gcc_qtou");
10778 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "__gcc_itoq");
10779 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "__gcc_utoq");
10782 if (!(TARGET_HARD_FLOAT
&& TARGET_FPRS
))
10783 set_optab_libfunc (unord_optab
, TFmode
, "__gcc_qunord");
10787 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
10788 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
10789 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
10790 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
10794 /* 32-bit SVR4 quad floating point routines. */
10796 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
10797 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
10798 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
10799 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
10800 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
10801 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
10802 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
10804 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
10805 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
10806 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
10807 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
10808 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
10809 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
10811 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
10812 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
10813 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
10814 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
10815 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
10816 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
10817 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
10818 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "_q_utoq");
10823 /* Expand a block clear operation, and return 1 if successful. Return 0
10824 if we should let the compiler generate normal code.
10826 operands[0] is the destination
10827 operands[1] is the length
10828 operands[3] is the alignment */
10831 expand_block_clear (rtx operands
[])
10833 rtx orig_dest
= operands
[0];
10834 rtx bytes_rtx
= operands
[1];
10835 rtx align_rtx
= operands
[3];
10836 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
10837 HOST_WIDE_INT align
;
10838 HOST_WIDE_INT bytes
;
10843 /* If this is not a fixed size move, just call memcpy */
10847 /* This must be a fixed size alignment */
10848 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
10849 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
10851 /* Anything to clear? */
10852 bytes
= INTVAL (bytes_rtx
);
10856 /* Use the builtin memset after a point, to avoid huge code bloat.
10857 When optimize_size, avoid any significant code bloat; calling
10858 memset is about 4 instructions, so allow for one instruction to
10859 load zero and three to do clearing. */
10860 if (TARGET_ALTIVEC
&& align
>= 128)
10862 else if (TARGET_POWERPC64
&& align
>= 32)
10864 else if (TARGET_SPE
&& align
>= 64)
10869 if (optimize_size
&& bytes
> 3 * clear_step
)
10871 if (! optimize_size
&& bytes
> 8 * clear_step
)
10874 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
10876 enum machine_mode mode
= BLKmode
;
10879 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
10884 else if (bytes
>= 8 && TARGET_SPE
&& align
>= 64)
10889 else if (bytes
>= 8 && TARGET_POWERPC64
10890 /* 64-bit loads and stores require word-aligned
10892 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
10897 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
10898 { /* move 4 bytes */
10902 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
10903 { /* move 2 bytes */
10907 else /* move 1 byte at a time */
10913 dest
= adjust_address (orig_dest
, mode
, offset
);
10915 emit_move_insn (dest
, CONST0_RTX (mode
));
10922 /* Expand a block move operation, and return 1 if successful. Return 0
10923 if we should let the compiler generate normal code.
10925 operands[0] is the destination
10926 operands[1] is the source
10927 operands[2] is the length
10928 operands[3] is the alignment */
10930 #define MAX_MOVE_REG 4
10933 expand_block_move (rtx operands
[])
10935 rtx orig_dest
= operands
[0];
10936 rtx orig_src
= operands
[1];
10937 rtx bytes_rtx
= operands
[2];
10938 rtx align_rtx
= operands
[3];
10939 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
10944 rtx stores
[MAX_MOVE_REG
];
10947 /* If this is not a fixed size move, just call memcpy */
10951 /* This must be a fixed size alignment */
10952 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
10953 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
10955 /* Anything to move? */
10956 bytes
= INTVAL (bytes_rtx
);
10960 /* store_one_arg depends on expand_block_move to handle at least the size of
10961 reg_parm_stack_space. */
10962 if (bytes
> (TARGET_POWERPC64
? 64 : 32))
10965 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
10968 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
10969 rtx (*mov
) (rtx
, rtx
);
10971 enum machine_mode mode
= BLKmode
;
10974 /* Altivec first, since it will be faster than a string move
10975 when it applies, and usually not significantly larger. */
10976 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
10980 gen_func
.mov
= gen_movv4si
;
10982 else if (TARGET_SPE
&& bytes
>= 8 && align
>= 64)
10986 gen_func
.mov
= gen_movv2si
;
10988 else if (TARGET_STRING
10989 && bytes
> 24 /* move up to 32 bytes at a time */
10995 && ! fixed_regs
[10]
10996 && ! fixed_regs
[11]
10997 && ! fixed_regs
[12])
10999 move_bytes
= (bytes
> 32) ? 32 : bytes
;
11000 gen_func
.movmemsi
= gen_movmemsi_8reg
;
11002 else if (TARGET_STRING
11003 && bytes
> 16 /* move up to 24 bytes at a time */
11009 && ! fixed_regs
[10])
11011 move_bytes
= (bytes
> 24) ? 24 : bytes
;
11012 gen_func
.movmemsi
= gen_movmemsi_6reg
;
11014 else if (TARGET_STRING
11015 && bytes
> 8 /* move up to 16 bytes at a time */
11019 && ! fixed_regs
[8])
11021 move_bytes
= (bytes
> 16) ? 16 : bytes
;
11022 gen_func
.movmemsi
= gen_movmemsi_4reg
;
11024 else if (bytes
>= 8 && TARGET_POWERPC64
11025 /* 64-bit loads and stores require word-aligned
11027 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
11031 gen_func
.mov
= gen_movdi
;
11033 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
11034 { /* move up to 8 bytes at a time */
11035 move_bytes
= (bytes
> 8) ? 8 : bytes
;
11036 gen_func
.movmemsi
= gen_movmemsi_2reg
;
11038 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
11039 { /* move 4 bytes */
11042 gen_func
.mov
= gen_movsi
;
11044 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
11045 { /* move 2 bytes */
11048 gen_func
.mov
= gen_movhi
;
11050 else if (TARGET_STRING
&& bytes
> 1)
11051 { /* move up to 4 bytes at a time */
11052 move_bytes
= (bytes
> 4) ? 4 : bytes
;
11053 gen_func
.movmemsi
= gen_movmemsi_1reg
;
11055 else /* move 1 byte at a time */
11059 gen_func
.mov
= gen_movqi
;
11062 src
= adjust_address (orig_src
, mode
, offset
);
11063 dest
= adjust_address (orig_dest
, mode
, offset
);
11065 if (mode
!= BLKmode
)
11067 rtx tmp_reg
= gen_reg_rtx (mode
);
11069 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
11070 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
11073 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
11076 for (i
= 0; i
< num_reg
; i
++)
11077 emit_insn (stores
[i
]);
11081 if (mode
== BLKmode
)
11083 /* Move the address into scratch registers. The movmemsi
11084 patterns require zero offset. */
11085 if (!REG_P (XEXP (src
, 0)))
11087 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
11088 src
= replace_equiv_address (src
, src_reg
);
11090 set_mem_size (src
, GEN_INT (move_bytes
));
11092 if (!REG_P (XEXP (dest
, 0)))
11094 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
11095 dest
= replace_equiv_address (dest
, dest_reg
);
11097 set_mem_size (dest
, GEN_INT (move_bytes
));
11099 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
11100 GEN_INT (move_bytes
& 31),
11109 /* Return a string to perform a load_multiple operation.
11110 operands[0] is the vector.
11111 operands[1] is the source address.
11112 operands[2] is the first destination register. */
11115 rs6000_output_load_multiple (rtx operands
[3])
11117 /* We have to handle the case where the pseudo used to contain the address
11118 is assigned to one of the output registers. */
11120 int words
= XVECLEN (operands
[0], 0);
11123 if (XVECLEN (operands
[0], 0) == 1)
11124 return "{l|lwz} %2,0(%1)";
11126 for (i
= 0; i
< words
; i
++)
11127 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
11128 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
11132 xop
[0] = GEN_INT (4 * (words
-1));
11133 xop
[1] = operands
[1];
11134 xop
[2] = operands
[2];
11135 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
11140 xop
[0] = GEN_INT (4 * (words
-1));
11141 xop
[1] = operands
[1];
11142 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
11143 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
);
11148 for (j
= 0; j
< words
; j
++)
11151 xop
[0] = GEN_INT (j
* 4);
11152 xop
[1] = operands
[1];
11153 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
11154 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
11156 xop
[0] = GEN_INT (i
* 4);
11157 xop
[1] = operands
[1];
11158 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
11163 return "{lsi|lswi} %2,%1,%N0";
11167 /* A validation routine: say whether CODE, a condition code, and MODE
11168 match. The other alternatives either don't make sense or should
11169 never be generated. */
11172 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
11174 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
11175 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
11176 && GET_MODE_CLASS (mode
) == MODE_CC
);
11178 /* These don't make sense. */
11179 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
11180 || mode
!= CCUNSmode
);
11182 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
11183 || mode
== CCUNSmode
);
11185 gcc_assert (mode
== CCFPmode
11186 || (code
!= ORDERED
&& code
!= UNORDERED
11187 && code
!= UNEQ
&& code
!= LTGT
11188 && code
!= UNGT
&& code
!= UNLT
11189 && code
!= UNGE
&& code
!= UNLE
));
11191 /* These should never be generated except for
11192 flag_finite_math_only. */
11193 gcc_assert (mode
!= CCFPmode
11194 || flag_finite_math_only
11195 || (code
!= LE
&& code
!= GE
11196 && code
!= UNEQ
&& code
!= LTGT
11197 && code
!= UNGT
&& code
!= UNLT
));
11199 /* These are invalid; the information is not there. */
11200 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
11204 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
11205 mask required to convert the result of a rotate insn into a shift
11206 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
11209 includes_lshift_p (rtx shiftop
, rtx andop
)
11211 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
11213 shift_mask
<<= INTVAL (shiftop
);
11215 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
11218 /* Similar, but for right shift. */
11221 includes_rshift_p (rtx shiftop
, rtx andop
)
11223 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
11225 shift_mask
>>= INTVAL (shiftop
);
11227 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
11230 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
11231 to perform a left shift. It must have exactly SHIFTOP least
11232 significant 0's, then one or more 1's, then zero or more 0's. */
11235 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
11237 if (GET_CODE (andop
) == CONST_INT
)
11239 HOST_WIDE_INT c
, lsb
, shift_mask
;
11241 c
= INTVAL (andop
);
11242 if (c
== 0 || c
== ~0)
11246 shift_mask
<<= INTVAL (shiftop
);
11248 /* Find the least significant one bit. */
11251 /* It must coincide with the LSB of the shift mask. */
11252 if (-lsb
!= shift_mask
)
11255 /* Invert to look for the next transition (if any). */
11258 /* Remove the low group of ones (originally low group of zeros). */
11261 /* Again find the lsb, and check we have all 1's above. */
11265 else if (GET_CODE (andop
) == CONST_DOUBLE
11266 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
11268 HOST_WIDE_INT low
, high
, lsb
;
11269 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
11271 low
= CONST_DOUBLE_LOW (andop
);
11272 if (HOST_BITS_PER_WIDE_INT
< 64)
11273 high
= CONST_DOUBLE_HIGH (andop
);
11275 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
11276 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
11279 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
11281 shift_mask_high
= ~0;
11282 if (INTVAL (shiftop
) > 32)
11283 shift_mask_high
<<= INTVAL (shiftop
) - 32;
11285 lsb
= high
& -high
;
11287 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
11293 lsb
= high
& -high
;
11294 return high
== -lsb
;
11297 shift_mask_low
= ~0;
11298 shift_mask_low
<<= INTVAL (shiftop
);
11302 if (-lsb
!= shift_mask_low
)
11305 if (HOST_BITS_PER_WIDE_INT
< 64)
11310 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
11312 lsb
= high
& -high
;
11313 return high
== -lsb
;
11317 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
11323 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
11324 to perform a left shift. It must have SHIFTOP or more least
11325 significant 0's, with the remainder of the word 1's. */
11328 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
11330 if (GET_CODE (andop
) == CONST_INT
)
11332 HOST_WIDE_INT c
, lsb
, shift_mask
;
11335 shift_mask
<<= INTVAL (shiftop
);
11336 c
= INTVAL (andop
);
11338 /* Find the least significant one bit. */
11341 /* It must be covered by the shift mask.
11342 This test also rejects c == 0. */
11343 if ((lsb
& shift_mask
) == 0)
11346 /* Check we have all 1's above the transition, and reject all 1's. */
11347 return c
== -lsb
&& lsb
!= 1;
11349 else if (GET_CODE (andop
) == CONST_DOUBLE
11350 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
11352 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
11354 low
= CONST_DOUBLE_LOW (andop
);
11356 if (HOST_BITS_PER_WIDE_INT
< 64)
11358 HOST_WIDE_INT high
, shift_mask_high
;
11360 high
= CONST_DOUBLE_HIGH (andop
);
11364 shift_mask_high
= ~0;
11365 if (INTVAL (shiftop
) > 32)
11366 shift_mask_high
<<= INTVAL (shiftop
) - 32;
11368 lsb
= high
& -high
;
11370 if ((lsb
& shift_mask_high
) == 0)
11373 return high
== -lsb
;
11379 shift_mask_low
= ~0;
11380 shift_mask_low
<<= INTVAL (shiftop
);
11384 if ((lsb
& shift_mask_low
) == 0)
11387 return low
== -lsb
&& lsb
!= 1;
11393 /* Return 1 if operands will generate a valid arguments to rlwimi
11394 instruction for insert with right shift in 64-bit mode. The mask may
11395 not start on the first bit or stop on the last bit because wrap-around
11396 effects of instruction do not correspond to semantics of RTL insn. */
11399 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
11401 if (INTVAL (startop
) > 32
11402 && INTVAL (startop
) < 64
11403 && INTVAL (sizeop
) > 1
11404 && INTVAL (sizeop
) + INTVAL (startop
) < 64
11405 && INTVAL (shiftop
) > 0
11406 && INTVAL (sizeop
) + INTVAL (shiftop
) < 32
11407 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
11413 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
11414 for lfq and stfq insns iff the registers are hard registers. */
11417 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
11419 /* We might have been passed a SUBREG. */
11420 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
11423 /* We might have been passed non floating point registers. */
11424 if (!FP_REGNO_P (REGNO (reg1
))
11425 || !FP_REGNO_P (REGNO (reg2
)))
11428 return (REGNO (reg1
) == REGNO (reg2
) - 1);
11431 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
11432 addr1 and addr2 must be in consecutive memory locations
11433 (addr2 == addr1 + 8). */
11436 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
11439 unsigned int reg1
, reg2
;
11440 int offset1
, offset2
;
11442 /* The mems cannot be volatile. */
11443 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
11446 addr1
= XEXP (mem1
, 0);
11447 addr2
= XEXP (mem2
, 0);
11449 /* Extract an offset (if used) from the first addr. */
11450 if (GET_CODE (addr1
) == PLUS
)
11452 /* If not a REG, return zero. */
11453 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
11457 reg1
= REGNO (XEXP (addr1
, 0));
11458 /* The offset must be constant! */
11459 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
11461 offset1
= INTVAL (XEXP (addr1
, 1));
11464 else if (GET_CODE (addr1
) != REG
)
11468 reg1
= REGNO (addr1
);
11469 /* This was a simple (mem (reg)) expression. Offset is 0. */
11473 /* And now for the second addr. */
11474 if (GET_CODE (addr2
) == PLUS
)
11476 /* If not a REG, return zero. */
11477 if (GET_CODE (XEXP (addr2
, 0)) != REG
)
11481 reg2
= REGNO (XEXP (addr2
, 0));
11482 /* The offset must be constant. */
11483 if (GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
11485 offset2
= INTVAL (XEXP (addr2
, 1));
11488 else if (GET_CODE (addr2
) != REG
)
11492 reg2
= REGNO (addr2
);
11493 /* This was a simple (mem (reg)) expression. Offset is 0. */
11497 /* Both of these must have the same base register. */
11501 /* The offset for the second addr must be 8 more than the first addr. */
11502 if (offset2
!= offset1
+ 8)
11505 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
11512 rs6000_secondary_memory_needed_rtx (enum machine_mode mode
)
11514 static bool eliminated
= false;
11515 if (mode
!= SDmode
)
11516 return assign_stack_local (mode
, GET_MODE_SIZE (mode
), 0);
11519 rtx mem
= cfun
->machine
->sdmode_stack_slot
;
11520 gcc_assert (mem
!= NULL_RTX
);
11524 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
11525 cfun
->machine
->sdmode_stack_slot
= mem
;
11533 rs6000_check_sdmode (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
11535 /* Don't walk into types. */
11536 if (*tp
== NULL_TREE
|| *tp
== error_mark_node
|| TYPE_P (*tp
))
11538 *walk_subtrees
= 0;
11542 switch (TREE_CODE (*tp
))
11551 case ALIGN_INDIRECT_REF
:
11552 case MISALIGNED_INDIRECT_REF
:
11553 case VIEW_CONVERT_EXPR
:
11554 if (TYPE_MODE (TREE_TYPE (*tp
)) == SDmode
)
11565 /* Allocate a 64-bit stack slot to be used for copying SDmode
11566 values through if this function has any SDmode references. */
11569 rs6000_alloc_sdmode_stack_slot (void)
11573 gimple_stmt_iterator gsi
;
11575 gcc_assert (cfun
->machine
->sdmode_stack_slot
== NULL_RTX
);
11578 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
11580 tree ret
= walk_gimple_op (gsi_stmt (gsi
), rs6000_check_sdmode
, NULL
);
11583 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
11584 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
11590 /* Check for any SDmode parameters of the function. */
11591 for (t
= DECL_ARGUMENTS (cfun
->decl
); t
; t
= TREE_CHAIN (t
))
11593 if (TREE_TYPE (t
) == error_mark_node
)
11596 if (TYPE_MODE (TREE_TYPE (t
)) == SDmode
11597 || TYPE_MODE (DECL_ARG_TYPE (t
)) == SDmode
)
11599 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
11600 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
11608 rs6000_instantiate_decls (void)
11610 if (cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
11611 instantiate_decl_rtl (cfun
->machine
->sdmode_stack_slot
);
11614 /* Return the register class of a scratch register needed to copy IN into
11615 or out of a register in RCLASS in MODE. If it can be done directly,
11616 NO_REGS is returned. */
11619 rs6000_secondary_reload_class (enum reg_class rclass
,
11620 enum machine_mode mode ATTRIBUTE_UNUSED
,
11625 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
11627 && MACHOPIC_INDIRECT
11631 /* We cannot copy a symbolic operand directly into anything
11632 other than BASE_REGS for TARGET_ELF. So indicate that a
11633 register from BASE_REGS is needed as an intermediate
11636 On Darwin, pic addresses require a load from memory, which
11637 needs a base register. */
11638 if (rclass
!= BASE_REGS
11639 && (GET_CODE (in
) == SYMBOL_REF
11640 || GET_CODE (in
) == HIGH
11641 || GET_CODE (in
) == LABEL_REF
11642 || GET_CODE (in
) == CONST
))
11646 if (GET_CODE (in
) == REG
)
11648 regno
= REGNO (in
);
11649 if (regno
>= FIRST_PSEUDO_REGISTER
)
11651 regno
= true_regnum (in
);
11652 if (regno
>= FIRST_PSEUDO_REGISTER
)
11656 else if (GET_CODE (in
) == SUBREG
)
11658 regno
= true_regnum (in
);
11659 if (regno
>= FIRST_PSEUDO_REGISTER
)
11665 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
11667 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
11668 || (regno
>= 0 && INT_REGNO_P (regno
)))
11671 /* Constants, memory, and FP registers can go into FP registers. */
11672 if ((regno
== -1 || FP_REGNO_P (regno
))
11673 && (rclass
== FLOAT_REGS
|| rclass
== NON_SPECIAL_REGS
))
11674 return (mode
!= SDmode
) ? NO_REGS
: GENERAL_REGS
;
11676 /* Memory, and AltiVec registers can go into AltiVec registers. */
11677 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
11678 && rclass
== ALTIVEC_REGS
)
11681 /* We can copy among the CR registers. */
11682 if ((rclass
== CR_REGS
|| rclass
== CR0_REGS
)
11683 && regno
>= 0 && CR_REGNO_P (regno
))
11686 /* Otherwise, we need GENERAL_REGS. */
11687 return GENERAL_REGS
;
11690 /* Given a comparison operation, return the bit number in CCR to test. We
11691 know this is a valid comparison.
11693 SCC_P is 1 if this is for an scc. That means that %D will have been
11694 used instead of %C, so the bits will be in different places.
11696 Return -1 if OP isn't a valid comparison for some reason. */
11699 ccr_bit (rtx op
, int scc_p
)
11701 enum rtx_code code
= GET_CODE (op
);
11702 enum machine_mode cc_mode
;
11707 if (!COMPARISON_P (op
))
11710 reg
= XEXP (op
, 0);
11712 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
11714 cc_mode
= GET_MODE (reg
);
11715 cc_regnum
= REGNO (reg
);
11716 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
11718 validate_condition_mode (code
, cc_mode
);
11720 /* When generating a sCOND operation, only positive conditions are
11723 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
11724 || code
== GTU
|| code
== LTU
);
11729 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
11731 return base_bit
+ 2;
11732 case GT
: case GTU
: case UNLE
:
11733 return base_bit
+ 1;
11734 case LT
: case LTU
: case UNGE
:
11736 case ORDERED
: case UNORDERED
:
11737 return base_bit
+ 3;
11740 /* If scc, we will have done a cror to put the bit in the
11741 unordered position. So test that bit. For integer, this is ! LT
11742 unless this is an scc insn. */
11743 return scc_p
? base_bit
+ 3 : base_bit
;
11746 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
11749 gcc_unreachable ();
11753 /* Return the GOT register. */
11756 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
11758 /* The second flow pass currently (June 1999) can't update
11759 regs_ever_live without disturbing other parts of the compiler, so
11760 update it here to make the prolog/epilogue code happy. */
11761 if (!can_create_pseudo_p ()
11762 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
))
11763 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM
, true);
11765 crtl
->uses_pic_offset_table
= 1;
11767 return pic_offset_table_rtx
;
11770 /* Function to init struct machine_function.
11771 This will be called, via a pointer variable,
11772 from push_function_context. */
11774 static struct machine_function
*
11775 rs6000_init_machine_status (void)
11777 return GGC_CNEW (machine_function
);
11780 /* These macros test for integers and extract the low-order bits. */
11782 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
11783 && GET_MODE (X) == VOIDmode)
11785 #define INT_LOWPART(X) \
11786 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
11789 extract_MB (rtx op
)
11792 unsigned long val
= INT_LOWPART (op
);
11794 /* If the high bit is zero, the value is the first 1 bit we find
11796 if ((val
& 0x80000000) == 0)
11798 gcc_assert (val
& 0xffffffff);
11801 while (((val
<<= 1) & 0x80000000) == 0)
11806 /* If the high bit is set and the low bit is not, or the mask is all
11807 1's, the value is zero. */
11808 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
11811 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11814 while (((val
>>= 1) & 1) != 0)
11821 extract_ME (rtx op
)
11824 unsigned long val
= INT_LOWPART (op
);
11826 /* If the low bit is zero, the value is the first 1 bit we find from
11828 if ((val
& 1) == 0)
11830 gcc_assert (val
& 0xffffffff);
11833 while (((val
>>= 1) & 1) == 0)
11839 /* If the low bit is set and the high bit is not, or the mask is all
11840 1's, the value is 31. */
11841 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
11844 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11847 while (((val
<<= 1) & 0x80000000) != 0)
11853 /* Locate some local-dynamic symbol still in use by this function
11854 so that we can print its name in some tls_ld pattern. */
11856 static const char *
11857 rs6000_get_some_local_dynamic_name (void)
11861 if (cfun
->machine
->some_ld_name
)
11862 return cfun
->machine
->some_ld_name
;
11864 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
11866 && for_each_rtx (&PATTERN (insn
),
11867 rs6000_get_some_local_dynamic_name_1
, 0))
11868 return cfun
->machine
->some_ld_name
;
11870 gcc_unreachable ();
11873 /* Helper function for rs6000_get_some_local_dynamic_name. */
11876 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
11880 if (GET_CODE (x
) == SYMBOL_REF
)
11882 const char *str
= XSTR (x
, 0);
11883 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
11885 cfun
->machine
->some_ld_name
= str
;
11893 /* Write out a function code label. */
11896 rs6000_output_function_entry (FILE *file
, const char *fname
)
11898 if (fname
[0] != '.')
11900 switch (DEFAULT_ABI
)
11903 gcc_unreachable ();
11909 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
11918 RS6000_OUTPUT_BASENAME (file
, fname
);
11920 assemble_name (file
, fname
);
11923 /* Print an operand. Recognize special options, documented below. */
11926 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
11927 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
11929 #define SMALL_DATA_RELOC "sda21"
11930 #define SMALL_DATA_REG 0
11934 print_operand (FILE *file
, rtx x
, int code
)
11938 unsigned HOST_WIDE_INT uval
;
11943 /* Write out an instruction after the call which may be replaced
11944 with glue code by the loader. This depends on the AIX version. */
11945 asm_fprintf (file
, RS6000_CALL_GLUE
);
11948 /* %a is output_address. */
11951 /* If X is a constant integer whose low-order 5 bits are zero,
11952 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
11953 in the AIX assembler where "sri" with a zero shift count
11954 writes a trash instruction. */
11955 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
11962 /* If constant, low-order 16 bits of constant, unsigned.
11963 Otherwise, write normally. */
11965 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
11967 print_operand (file
, x
, 0);
11971 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
11972 for 64-bit mask direction. */
11973 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
11976 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
11980 /* X is a CR register. Print the number of the GT bit of the CR. */
11981 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
11982 output_operand_lossage ("invalid %%E value");
11984 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
11988 /* Like 'J' but get to the GT bit only. */
11989 gcc_assert (GET_CODE (x
) == REG
);
11991 /* Bit 1 is GT bit. */
11992 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 1;
11994 /* Add one for shift count in rlinm for scc. */
11995 fprintf (file
, "%d", i
+ 1);
11999 /* X is a CR register. Print the number of the EQ bit of the CR */
12000 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
12001 output_operand_lossage ("invalid %%E value");
12003 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
12007 /* X is a CR register. Print the shift count needed to move it
12008 to the high-order four bits. */
12009 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
12010 output_operand_lossage ("invalid %%f value");
12012 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
12016 /* Similar, but print the count for the rotate in the opposite
12018 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
12019 output_operand_lossage ("invalid %%F value");
12021 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
12025 /* X is a constant integer. If it is negative, print "m",
12026 otherwise print "z". This is to make an aze or ame insn. */
12027 if (GET_CODE (x
) != CONST_INT
)
12028 output_operand_lossage ("invalid %%G value");
12029 else if (INTVAL (x
) >= 0)
12036 /* If constant, output low-order five bits. Otherwise, write
12039 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
12041 print_operand (file
, x
, 0);
12045 /* If constant, output low-order six bits. Otherwise, write
12048 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
12050 print_operand (file
, x
, 0);
12054 /* Print `i' if this is a constant, else nothing. */
12060 /* Write the bit number in CCR for jump. */
12061 i
= ccr_bit (x
, 0);
12063 output_operand_lossage ("invalid %%j code");
12065 fprintf (file
, "%d", i
);
12069 /* Similar, but add one for shift count in rlinm for scc and pass
12070 scc flag to `ccr_bit'. */
12071 i
= ccr_bit (x
, 1);
12073 output_operand_lossage ("invalid %%J code");
12075 /* If we want bit 31, write a shift count of zero, not 32. */
12076 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
12080 /* X must be a constant. Write the 1's complement of the
12083 output_operand_lossage ("invalid %%k value");
12085 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
12089 /* X must be a symbolic constant on ELF. Write an
12090 expression suitable for an 'addi' that adds in the low 16
12091 bits of the MEM. */
12092 if (GET_CODE (x
) != CONST
)
12094 print_operand_address (file
, x
);
12095 fputs ("@l", file
);
12099 if (GET_CODE (XEXP (x
, 0)) != PLUS
12100 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
12101 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
12102 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
12103 output_operand_lossage ("invalid %%K value");
12104 print_operand_address (file
, XEXP (XEXP (x
, 0), 0));
12105 fputs ("@l", file
);
12106 /* For GNU as, there must be a non-alphanumeric character
12107 between 'l' and the number. The '-' is added by
12108 print_operand() already. */
12109 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
12111 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
12115 /* %l is output_asm_label. */
12118 /* Write second word of DImode or DFmode reference. Works on register
12119 or non-indexed memory only. */
12120 if (GET_CODE (x
) == REG
)
12121 fputs (reg_names
[REGNO (x
) + 1], file
);
12122 else if (GET_CODE (x
) == MEM
)
12124 /* Handle possible auto-increment. Since it is pre-increment and
12125 we have already done it, we can just use an offset of word. */
12126 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
12127 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12128 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
12130 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12131 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
12134 output_address (XEXP (adjust_address_nv (x
, SImode
,
12138 if (small_data_operand (x
, GET_MODE (x
)))
12139 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12140 reg_names
[SMALL_DATA_REG
]);
12145 /* MB value for a mask operand. */
12146 if (! mask_operand (x
, SImode
))
12147 output_operand_lossage ("invalid %%m value");
12149 fprintf (file
, "%d", extract_MB (x
));
12153 /* ME value for a mask operand. */
12154 if (! mask_operand (x
, SImode
))
12155 output_operand_lossage ("invalid %%M value");
12157 fprintf (file
, "%d", extract_ME (x
));
12160 /* %n outputs the negative of its operand. */
12163 /* Write the number of elements in the vector times 4. */
12164 if (GET_CODE (x
) != PARALLEL
)
12165 output_operand_lossage ("invalid %%N value");
12167 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
12171 /* Similar, but subtract 1 first. */
12172 if (GET_CODE (x
) != PARALLEL
)
12173 output_operand_lossage ("invalid %%O value");
12175 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
12179 /* X is a CONST_INT that is a power of two. Output the logarithm. */
12181 || INT_LOWPART (x
) < 0
12182 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
12183 output_operand_lossage ("invalid %%p value");
12185 fprintf (file
, "%d", i
);
12189 /* The operand must be an indirect memory reference. The result
12190 is the register name. */
12191 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
12192 || REGNO (XEXP (x
, 0)) >= 32)
12193 output_operand_lossage ("invalid %%P value");
12195 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
12199 /* This outputs the logical code corresponding to a boolean
12200 expression. The expression may have one or both operands
12201 negated (if one, only the first one). For condition register
12202 logical operations, it will also treat the negated
12203 CR codes as NOTs, but not handle NOTs of them. */
12205 const char *const *t
= 0;
12207 enum rtx_code code
= GET_CODE (x
);
12208 static const char * const tbl
[3][3] = {
12209 { "and", "andc", "nor" },
12210 { "or", "orc", "nand" },
12211 { "xor", "eqv", "xor" } };
12215 else if (code
== IOR
)
12217 else if (code
== XOR
)
12220 output_operand_lossage ("invalid %%q value");
12222 if (GET_CODE (XEXP (x
, 0)) != NOT
)
12226 if (GET_CODE (XEXP (x
, 1)) == NOT
)
12244 /* X is a CR register. Print the mask for `mtcrf'. */
12245 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
12246 output_operand_lossage ("invalid %%R value");
12248 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
12252 /* Low 5 bits of 32 - value */
12254 output_operand_lossage ("invalid %%s value");
12256 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
12260 /* PowerPC64 mask position. All 0's is excluded.
12261 CONST_INT 32-bit mask is considered sign-extended so any
12262 transition must occur within the CONST_INT, not on the boundary. */
12263 if (! mask64_operand (x
, DImode
))
12264 output_operand_lossage ("invalid %%S value");
12266 uval
= INT_LOWPART (x
);
12268 if (uval
& 1) /* Clear Left */
12270 #if HOST_BITS_PER_WIDE_INT > 64
12271 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
12275 else /* Clear Right */
12278 #if HOST_BITS_PER_WIDE_INT > 64
12279 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
12285 gcc_assert (i
>= 0);
12286 fprintf (file
, "%d", i
);
12290 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
12291 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
12293 /* Bit 3 is OV bit. */
12294 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
12296 /* If we want bit 31, write a shift count of zero, not 32. */
12297 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
12301 /* Print the symbolic name of a branch target register. */
12302 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LR_REGNO
12303 && REGNO (x
) != CTR_REGNO
))
12304 output_operand_lossage ("invalid %%T value");
12305 else if (REGNO (x
) == LR_REGNO
)
12306 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
12308 fputs ("ctr", file
);
12312 /* High-order 16 bits of constant for use in unsigned operand. */
12314 output_operand_lossage ("invalid %%u value");
12316 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
12317 (INT_LOWPART (x
) >> 16) & 0xffff);
12321 /* High-order 16 bits of constant for use in signed operand. */
12323 output_operand_lossage ("invalid %%v value");
12325 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
12326 (INT_LOWPART (x
) >> 16) & 0xffff);
12330 /* Print `u' if this has an auto-increment or auto-decrement. */
12331 if (GET_CODE (x
) == MEM
12332 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
12333 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
12334 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
))
12339 /* Print the trap code for this operand. */
12340 switch (GET_CODE (x
))
12343 fputs ("eq", file
); /* 4 */
12346 fputs ("ne", file
); /* 24 */
12349 fputs ("lt", file
); /* 16 */
12352 fputs ("le", file
); /* 20 */
12355 fputs ("gt", file
); /* 8 */
12358 fputs ("ge", file
); /* 12 */
12361 fputs ("llt", file
); /* 2 */
12364 fputs ("lle", file
); /* 6 */
12367 fputs ("lgt", file
); /* 1 */
12370 fputs ("lge", file
); /* 5 */
12373 gcc_unreachable ();
12378 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
12381 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
12382 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
12384 print_operand (file
, x
, 0);
12388 /* MB value for a PowerPC64 rldic operand. */
12389 val
= (GET_CODE (x
) == CONST_INT
12390 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
12395 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
12396 if ((val
<<= 1) < 0)
12399 #if HOST_BITS_PER_WIDE_INT == 32
12400 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
12401 i
+= 32; /* zero-extend high-part was all 0's */
12402 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
12404 val
= CONST_DOUBLE_LOW (x
);
12410 for ( ; i
< 64; i
++)
12411 if ((val
<<= 1) < 0)
12416 fprintf (file
, "%d", i
+ 1);
12420 if (GET_CODE (x
) == MEM
12421 && (legitimate_indexed_address_p (XEXP (x
, 0), 0)
12422 || (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
12423 && legitimate_indexed_address_p (XEXP (XEXP (x
, 0), 1), 0))))
12428 /* Like 'L', for third word of TImode */
12429 if (GET_CODE (x
) == REG
)
12430 fputs (reg_names
[REGNO (x
) + 2], file
);
12431 else if (GET_CODE (x
) == MEM
)
12433 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
12434 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12435 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
12436 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12437 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
12439 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
12440 if (small_data_operand (x
, GET_MODE (x
)))
12441 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12442 reg_names
[SMALL_DATA_REG
]);
12447 /* X is a SYMBOL_REF. Write out the name preceded by a
12448 period and without any trailing data in brackets. Used for function
12449 names. If we are configured for System V (or the embedded ABI) on
12450 the PowerPC, do not emit the period, since those systems do not use
12451 TOCs and the like. */
12452 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
12454 /* Mark the decl as referenced so that cgraph will output the
12456 if (SYMBOL_REF_DECL (x
))
12457 mark_decl_referenced (SYMBOL_REF_DECL (x
));
12459 /* For macho, check to see if we need a stub. */
12462 const char *name
= XSTR (x
, 0);
12464 if (MACHOPIC_INDIRECT
12465 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
12466 name
= machopic_indirection_name (x
, /*stub_p=*/true);
12468 assemble_name (file
, name
);
12470 else if (!DOT_SYMBOLS
)
12471 assemble_name (file
, XSTR (x
, 0));
12473 rs6000_output_function_entry (file
, XSTR (x
, 0));
12477 /* Like 'L', for last word of TImode. */
12478 if (GET_CODE (x
) == REG
)
12479 fputs (reg_names
[REGNO (x
) + 3], file
);
12480 else if (GET_CODE (x
) == MEM
)
12482 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
12483 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12484 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
12485 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12486 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
12488 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
12489 if (small_data_operand (x
, GET_MODE (x
)))
12490 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12491 reg_names
[SMALL_DATA_REG
]);
12495 /* Print AltiVec or SPE memory operand. */
12500 gcc_assert (GET_CODE (x
) == MEM
);
12504 /* Ugly hack because %y is overloaded. */
12505 if ((TARGET_SPE
|| TARGET_E500_DOUBLE
)
12506 && (GET_MODE_SIZE (GET_MODE (x
)) == 8
12507 || GET_MODE (x
) == TFmode
12508 || GET_MODE (x
) == TImode
))
12510 /* Handle [reg]. */
12511 if (GET_CODE (tmp
) == REG
)
12513 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
12516 /* Handle [reg+UIMM]. */
12517 else if (GET_CODE (tmp
) == PLUS
&&
12518 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
12522 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
12524 x
= INTVAL (XEXP (tmp
, 1));
12525 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
12529 /* Fall through. Must be [reg+reg]. */
12532 && GET_CODE (tmp
) == AND
12533 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
12534 && INTVAL (XEXP (tmp
, 1)) == -16)
12535 tmp
= XEXP (tmp
, 0);
12536 if (GET_CODE (tmp
) == REG
)
12537 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
12540 if (!GET_CODE (tmp
) == PLUS
12541 || !REG_P (XEXP (tmp
, 0))
12542 || !REG_P (XEXP (tmp
, 1)))
12544 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
12548 if (REGNO (XEXP (tmp
, 0)) == 0)
12549 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
12550 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
12552 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
12553 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
12559 if (GET_CODE (x
) == REG
)
12560 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
12561 else if (GET_CODE (x
) == MEM
)
12563 /* We need to handle PRE_INC and PRE_DEC here, since we need to
12564 know the width from the mode. */
12565 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
12566 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
12567 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
12568 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12569 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
12570 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
12571 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12572 output_address (XEXP (XEXP (x
, 0), 1));
12574 output_address (XEXP (x
, 0));
12577 output_addr_const (file
, x
);
12581 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
12585 output_operand_lossage ("invalid %%xn code");
12589 /* Print the address of an operand. */
12592 print_operand_address (FILE *file
, rtx x
)
12594 if (GET_CODE (x
) == REG
)
12595 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
12596 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
12597 || GET_CODE (x
) == LABEL_REF
)
12599 output_addr_const (file
, x
);
12600 if (small_data_operand (x
, GET_MODE (x
)))
12601 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12602 reg_names
[SMALL_DATA_REG
]);
12604 gcc_assert (!TARGET_TOC
);
12606 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
12608 gcc_assert (REG_P (XEXP (x
, 0)));
12609 if (REGNO (XEXP (x
, 0)) == 0)
12610 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
12611 reg_names
[ REGNO (XEXP (x
, 0)) ]);
12613 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
12614 reg_names
[ REGNO (XEXP (x
, 1)) ]);
12616 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
12617 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
12618 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
12620 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
12621 && CONSTANT_P (XEXP (x
, 1)))
12623 output_addr_const (file
, XEXP (x
, 1));
12624 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
12628 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
12629 && CONSTANT_P (XEXP (x
, 1)))
12631 fprintf (file
, "lo16(");
12632 output_addr_const (file
, XEXP (x
, 1));
12633 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
12636 else if (legitimate_constant_pool_address_p (x
))
12638 output_addr_const (file
, XEXP (x
, 1));
12639 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
12642 gcc_unreachable ();
12645 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
12648 rs6000_output_addr_const_extra (FILE *file
, rtx x
)
12650 if (GET_CODE (x
) == UNSPEC
)
12651 switch (XINT (x
, 1))
12653 case UNSPEC_TOCREL
:
12654 x
= XVECEXP (x
, 0, 0);
12655 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
12656 output_addr_const (file
, x
);
12657 if (!TARGET_AIX
|| (TARGET_ELF
&& TARGET_MINIMAL_TOC
))
12660 assemble_name (file
, toc_label_name
);
12662 else if (TARGET_ELF
)
12663 fputs ("@toc", file
);
12667 case UNSPEC_MACHOPIC_OFFSET
:
12668 output_addr_const (file
, XVECEXP (x
, 0, 0));
12670 machopic_output_function_base_name (file
);
12677 /* Target hook for assembling integer objects. The PowerPC version has
12678 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
12679 is defined. It also needs to handle DI-mode objects on 64-bit
12683 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
12685 #ifdef RELOCATABLE_NEEDS_FIXUP
12686 /* Special handling for SI values. */
12687 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
12689 static int recurse
= 0;
12691 /* For -mrelocatable, we mark all addresses that need to be fixed up
12692 in the .fixup section. */
12693 if (TARGET_RELOCATABLE
12694 && in_section
!= toc_section
12695 && in_section
!= text_section
12696 && !unlikely_text_section_p (in_section
)
12698 && GET_CODE (x
) != CONST_INT
12699 && GET_CODE (x
) != CONST_DOUBLE
12705 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
12707 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
12708 fprintf (asm_out_file
, "\t.long\t(");
12709 output_addr_const (asm_out_file
, x
);
12710 fprintf (asm_out_file
, ")@fixup\n");
12711 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
12712 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
12713 fprintf (asm_out_file
, "\t.long\t");
12714 assemble_name (asm_out_file
, buf
);
12715 fprintf (asm_out_file
, "\n\t.previous\n");
12719 /* Remove initial .'s to turn a -mcall-aixdesc function
12720 address into the address of the descriptor, not the function
12722 else if (GET_CODE (x
) == SYMBOL_REF
12723 && XSTR (x
, 0)[0] == '.'
12724 && DEFAULT_ABI
== ABI_AIX
)
12726 const char *name
= XSTR (x
, 0);
12727 while (*name
== '.')
12730 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
12734 #endif /* RELOCATABLE_NEEDS_FIXUP */
12735 return default_assemble_integer (x
, size
, aligned_p
);
12738 #ifdef HAVE_GAS_HIDDEN
12739 /* Emit an assembler directive to set symbol visibility for DECL to
12740 VISIBILITY_TYPE. */
12743 rs6000_assemble_visibility (tree decl
, int vis
)
12745 /* Functions need to have their entry point symbol visibility set as
12746 well as their descriptor symbol visibility. */
12747 if (DEFAULT_ABI
== ABI_AIX
12749 && TREE_CODE (decl
) == FUNCTION_DECL
)
12751 static const char * const visibility_types
[] = {
12752 NULL
, "internal", "hidden", "protected"
12755 const char *name
, *type
;
12757 name
= ((* targetm
.strip_name_encoding
)
12758 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
12759 type
= visibility_types
[vis
];
12761 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
12762 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
12765 default_assemble_visibility (decl
, vis
);
12770 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
12772 /* Reversal of FP compares takes care -- an ordered compare
12773 becomes an unordered compare and vice versa. */
12774 if (mode
== CCFPmode
12775 && (!flag_finite_math_only
12776 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
12777 || code
== UNEQ
|| code
== LTGT
))
12778 return reverse_condition_maybe_unordered (code
);
12780 return reverse_condition (code
);
12783 /* Generate a compare for CODE. Return a brand-new rtx that
12784 represents the result of the compare. */
12787 rs6000_generate_compare (enum rtx_code code
)
12789 enum machine_mode comp_mode
;
12790 rtx compare_result
;
12792 if (rs6000_compare_fp_p
)
12793 comp_mode
= CCFPmode
;
12794 else if (code
== GTU
|| code
== LTU
12795 || code
== GEU
|| code
== LEU
)
12796 comp_mode
= CCUNSmode
;
12797 else if ((code
== EQ
|| code
== NE
)
12798 && GET_CODE (rs6000_compare_op0
) == SUBREG
12799 && GET_CODE (rs6000_compare_op1
) == SUBREG
12800 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0
)
12801 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1
))
12802 /* These are unsigned values, perhaps there will be a later
12803 ordering compare that can be shared with this one.
12804 Unfortunately we cannot detect the signedness of the operands
12805 for non-subregs. */
12806 comp_mode
= CCUNSmode
;
12808 comp_mode
= CCmode
;
12810 /* First, the compare. */
12811 compare_result
= gen_reg_rtx (comp_mode
);
12813 /* E500 FP compare instructions on the GPRs. Yuck! */
12814 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
)
12815 && rs6000_compare_fp_p
)
12817 rtx cmp
, or_result
, compare_result2
;
12818 enum machine_mode op_mode
= GET_MODE (rs6000_compare_op0
);
12820 if (op_mode
== VOIDmode
)
12821 op_mode
= GET_MODE (rs6000_compare_op1
);
12823 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
12824 This explains the following mess. */
12828 case EQ
: case UNEQ
: case NE
: case LTGT
:
12832 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12833 ? gen_tstsfeq_gpr (compare_result
, rs6000_compare_op0
,
12834 rs6000_compare_op1
)
12835 : gen_cmpsfeq_gpr (compare_result
, rs6000_compare_op0
,
12836 rs6000_compare_op1
);
12840 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12841 ? gen_tstdfeq_gpr (compare_result
, rs6000_compare_op0
,
12842 rs6000_compare_op1
)
12843 : gen_cmpdfeq_gpr (compare_result
, rs6000_compare_op0
,
12844 rs6000_compare_op1
);
12848 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12849 ? gen_tsttfeq_gpr (compare_result
, rs6000_compare_op0
,
12850 rs6000_compare_op1
)
12851 : gen_cmptfeq_gpr (compare_result
, rs6000_compare_op0
,
12852 rs6000_compare_op1
);
12856 gcc_unreachable ();
12860 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
12864 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12865 ? gen_tstsfgt_gpr (compare_result
, rs6000_compare_op0
,
12866 rs6000_compare_op1
)
12867 : gen_cmpsfgt_gpr (compare_result
, rs6000_compare_op0
,
12868 rs6000_compare_op1
);
12872 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12873 ? gen_tstdfgt_gpr (compare_result
, rs6000_compare_op0
,
12874 rs6000_compare_op1
)
12875 : gen_cmpdfgt_gpr (compare_result
, rs6000_compare_op0
,
12876 rs6000_compare_op1
);
12880 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12881 ? gen_tsttfgt_gpr (compare_result
, rs6000_compare_op0
,
12882 rs6000_compare_op1
)
12883 : gen_cmptfgt_gpr (compare_result
, rs6000_compare_op0
,
12884 rs6000_compare_op1
);
12888 gcc_unreachable ();
12892 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
12896 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12897 ? gen_tstsflt_gpr (compare_result
, rs6000_compare_op0
,
12898 rs6000_compare_op1
)
12899 : gen_cmpsflt_gpr (compare_result
, rs6000_compare_op0
,
12900 rs6000_compare_op1
);
12904 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12905 ? gen_tstdflt_gpr (compare_result
, rs6000_compare_op0
,
12906 rs6000_compare_op1
)
12907 : gen_cmpdflt_gpr (compare_result
, rs6000_compare_op0
,
12908 rs6000_compare_op1
);
12912 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12913 ? gen_tsttflt_gpr (compare_result
, rs6000_compare_op0
,
12914 rs6000_compare_op1
)
12915 : gen_cmptflt_gpr (compare_result
, rs6000_compare_op0
,
12916 rs6000_compare_op1
);
12920 gcc_unreachable ();
12924 gcc_unreachable ();
12927 /* Synthesize LE and GE from LT/GT || EQ. */
12928 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
12934 case LE
: code
= LT
; break;
12935 case GE
: code
= GT
; break;
12936 case LEU
: code
= LT
; break;
12937 case GEU
: code
= GT
; break;
12938 default: gcc_unreachable ();
12941 compare_result2
= gen_reg_rtx (CCFPmode
);
12947 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12948 ? gen_tstsfeq_gpr (compare_result2
, rs6000_compare_op0
,
12949 rs6000_compare_op1
)
12950 : gen_cmpsfeq_gpr (compare_result2
, rs6000_compare_op0
,
12951 rs6000_compare_op1
);
12955 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12956 ? gen_tstdfeq_gpr (compare_result2
, rs6000_compare_op0
,
12957 rs6000_compare_op1
)
12958 : gen_cmpdfeq_gpr (compare_result2
, rs6000_compare_op0
,
12959 rs6000_compare_op1
);
12963 cmp
= (flag_finite_math_only
&& !flag_trapping_math
)
12964 ? gen_tsttfeq_gpr (compare_result2
, rs6000_compare_op0
,
12965 rs6000_compare_op1
)
12966 : gen_cmptfeq_gpr (compare_result2
, rs6000_compare_op0
,
12967 rs6000_compare_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 (rs6000_compare_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
,
13005 rs6000_compare_op0
,
13006 rs6000_compare_op1
)),
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 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
13014 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)))));
13015 else if (GET_CODE (rs6000_compare_op1
) == UNSPEC
13016 && XINT (rs6000_compare_op1
, 1) == UNSPEC_SP_TEST
)
13018 rtx op1
= XVECEXP (rs6000_compare_op1
, 0, 0);
13019 comp_mode
= CCEQmode
;
13020 compare_result
= gen_reg_rtx (CCEQmode
);
13022 emit_insn (gen_stack_protect_testdi (compare_result
,
13023 rs6000_compare_op0
, op1
));
13025 emit_insn (gen_stack_protect_testsi (compare_result
,
13026 rs6000_compare_op0
, op1
));
13029 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
13030 gen_rtx_COMPARE (comp_mode
,
13031 rs6000_compare_op0
,
13032 rs6000_compare_op1
)));
13035 /* Some kinds of FP comparisons need an OR operation;
13036 under flag_finite_math_only we don't bother. */
13037 if (rs6000_compare_fp_p
13038 && !flag_finite_math_only
13039 && !(TARGET_HARD_FLOAT
&& !TARGET_FPRS
)
13040 && (code
== LE
|| code
== GE
13041 || code
== UNEQ
|| code
== LTGT
13042 || code
== UNGT
|| code
== UNLT
))
13044 enum rtx_code or1
, or2
;
13045 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
13046 rtx or_result
= gen_reg_rtx (CCEQmode
);
13050 case LE
: or1
= LT
; or2
= EQ
; break;
13051 case GE
: or1
= GT
; or2
= EQ
; break;
13052 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
13053 case LTGT
: or1
= LT
; or2
= GT
; break;
13054 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
13055 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
13056 default: gcc_unreachable ();
13058 validate_condition_mode (or1
, comp_mode
);
13059 validate_condition_mode (or2
, comp_mode
);
13060 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
13061 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
13062 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
13063 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
13065 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
13067 compare_result
= or_result
;
13071 validate_condition_mode (code
, GET_MODE (compare_result
));
13073 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
13077 /* Emit the RTL for an sCOND pattern. */
13080 rs6000_emit_sCOND (enum rtx_code code
, rtx result
)
13083 enum machine_mode op_mode
;
13084 enum rtx_code cond_code
;
13086 condition_rtx
= rs6000_generate_compare (code
);
13087 cond_code
= GET_CODE (condition_rtx
);
13089 if (rs6000_compare_fp_p
13090 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
13094 PUT_MODE (condition_rtx
, SImode
);
13095 t
= XEXP (condition_rtx
, 0);
13097 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
13099 if (cond_code
== NE
)
13100 emit_insn (gen_e500_flip_gt_bit (t
, t
));
13102 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
13106 if (cond_code
== NE
13107 || cond_code
== GE
|| cond_code
== LE
13108 || cond_code
== GEU
|| cond_code
== LEU
13109 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
13111 rtx not_result
= gen_reg_rtx (CCEQmode
);
13112 rtx not_op
, rev_cond_rtx
;
13113 enum machine_mode cc_mode
;
13115 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
13117 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
13118 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
13119 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
13120 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
13121 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
13124 op_mode
= GET_MODE (rs6000_compare_op0
);
13125 if (op_mode
== VOIDmode
)
13126 op_mode
= GET_MODE (rs6000_compare_op1
);
13128 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| rs6000_compare_fp_p
))
13130 PUT_MODE (condition_rtx
, DImode
);
13131 convert_move (result
, condition_rtx
, 0);
13135 PUT_MODE (condition_rtx
, SImode
);
13136 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
13140 /* Emit a branch of kind CODE to location LOC. */
13143 rs6000_emit_cbranch (enum rtx_code code
, rtx loc
)
13145 rtx condition_rtx
, loc_ref
;
13147 condition_rtx
= rs6000_generate_compare (code
);
13148 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, loc
);
13149 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
13150 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
13151 loc_ref
, pc_rtx
)));
13154 /* Return the string to output a conditional branch to LABEL, which is
13155 the operand number of the label, or -1 if the branch is really a
13156 conditional return.
13158 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
13159 condition code register and its mode specifies what kind of
13160 comparison we made.
13162 REVERSED is nonzero if we should reverse the sense of the comparison.
13164 INSN is the insn. */
13167 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
13169 static char string
[64];
13170 enum rtx_code code
= GET_CODE (op
);
13171 rtx cc_reg
= XEXP (op
, 0);
13172 enum machine_mode mode
= GET_MODE (cc_reg
);
13173 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
13174 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
13175 int really_reversed
= reversed
^ need_longbranch
;
13181 validate_condition_mode (code
, mode
);
13183 /* Work out which way this really branches. We could use
13184 reverse_condition_maybe_unordered here always but this
13185 makes the resulting assembler clearer. */
13186 if (really_reversed
)
13188 /* Reversal of FP compares takes care -- an ordered compare
13189 becomes an unordered compare and vice versa. */
13190 if (mode
== CCFPmode
)
13191 code
= reverse_condition_maybe_unordered (code
);
13193 code
= reverse_condition (code
);
13196 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
13198 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
13203 /* Opposite of GT. */
13212 gcc_unreachable ();
13218 /* Not all of these are actually distinct opcodes, but
13219 we distinguish them for clarity of the resulting assembler. */
13220 case NE
: case LTGT
:
13221 ccode
= "ne"; break;
13222 case EQ
: case UNEQ
:
13223 ccode
= "eq"; break;
13225 ccode
= "ge"; break;
13226 case GT
: case GTU
: case UNGT
:
13227 ccode
= "gt"; break;
13229 ccode
= "le"; break;
13230 case LT
: case LTU
: case UNLT
:
13231 ccode
= "lt"; break;
13232 case UNORDERED
: ccode
= "un"; break;
13233 case ORDERED
: ccode
= "nu"; break;
13234 case UNGE
: ccode
= "nl"; break;
13235 case UNLE
: ccode
= "ng"; break;
13237 gcc_unreachable ();
13240 /* Maybe we have a guess as to how likely the branch is.
13241 The old mnemonics don't have a way to specify this information. */
13243 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
13244 if (note
!= NULL_RTX
)
13246 /* PROB is the difference from 50%. */
13247 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
13249 /* Only hint for highly probable/improbable branches on newer
13250 cpus as static prediction overrides processor dynamic
13251 prediction. For older cpus we may as well always hint, but
13252 assume not taken for branches that are very close to 50% as a
13253 mispredicted taken branch is more expensive than a
13254 mispredicted not-taken branch. */
13255 if (rs6000_always_hint
13256 || (abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48
13257 && br_prob_note_reliable_p (note
)))
13259 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
13260 && ((prob
> 0) ^ need_longbranch
))
13268 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
13270 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
13272 /* We need to escape any '%' characters in the reg_names string.
13273 Assume they'd only be the first character.... */
13274 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
13276 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
13280 /* If the branch distance was too far, we may have to use an
13281 unconditional branch to go the distance. */
13282 if (need_longbranch
)
13283 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
13285 s
+= sprintf (s
, ",%s", label
);
13291 /* Return the string to flip the GT bit on a CR. */
13293 output_e500_flip_gt_bit (rtx dst
, rtx src
)
13295 static char string
[64];
13298 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
13299 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
13302 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
13303 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
13305 sprintf (string
, "crnot %d,%d", a
, b
);
13309 /* Return insn index for the vector compare instruction for given CODE,
13310 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
13314 get_vec_cmp_insn (enum rtx_code code
,
13315 enum machine_mode dest_mode
,
13316 enum machine_mode op_mode
)
13318 if (!TARGET_ALTIVEC
)
13319 return INSN_NOT_AVAILABLE
;
13324 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
13325 return UNSPEC_VCMPEQUB
;
13326 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
13327 return UNSPEC_VCMPEQUH
;
13328 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
13329 return UNSPEC_VCMPEQUW
;
13330 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
13331 return UNSPEC_VCMPEQFP
;
13334 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
13335 return UNSPEC_VCMPGEFP
;
13337 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
13338 return UNSPEC_VCMPGTSB
;
13339 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
13340 return UNSPEC_VCMPGTSH
;
13341 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
13342 return UNSPEC_VCMPGTSW
;
13343 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
13344 return UNSPEC_VCMPGTFP
;
13347 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
13348 return UNSPEC_VCMPGTUB
;
13349 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
13350 return UNSPEC_VCMPGTUH
;
13351 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
13352 return UNSPEC_VCMPGTUW
;
13357 return INSN_NOT_AVAILABLE
;
13360 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
13361 DMODE is expected destination mode. This is a recursive function. */
13364 rs6000_emit_vector_compare (enum rtx_code rcode
,
13366 enum machine_mode dmode
)
13370 enum machine_mode dest_mode
;
13371 enum machine_mode op_mode
= GET_MODE (op1
);
13373 gcc_assert (TARGET_ALTIVEC
);
13374 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
13376 /* Floating point vector compare instructions uses destination V4SImode.
13377 Move destination to appropriate mode later. */
13378 if (dmode
== V4SFmode
)
13379 dest_mode
= V4SImode
;
13383 mask
= gen_reg_rtx (dest_mode
);
13384 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
13386 if (vec_cmp_insn
== INSN_NOT_AVAILABLE
)
13388 bool swap_operands
= false;
13389 bool try_again
= false;
13394 swap_operands
= true;
13399 swap_operands
= true;
13407 /* Invert condition and try again.
13408 e.g., A != B becomes ~(A==B). */
13410 enum rtx_code rev_code
;
13411 enum insn_code nor_code
;
13414 rev_code
= reverse_condition_maybe_unordered (rcode
);
13415 eq_rtx
= rs6000_emit_vector_compare (rev_code
, op0
, op1
,
13418 nor_code
= optab_handler (one_cmpl_optab
, (int)dest_mode
)->insn_code
;
13419 gcc_assert (nor_code
!= CODE_FOR_nothing
);
13420 emit_insn (GEN_FCN (nor_code
) (mask
, eq_rtx
));
13422 if (dmode
!= dest_mode
)
13424 rtx temp
= gen_reg_rtx (dest_mode
);
13425 convert_move (temp
, mask
, 0);
13435 /* Try GT/GTU/LT/LTU OR EQ */
13438 enum insn_code ior_code
;
13439 enum rtx_code new_code
;
13460 gcc_unreachable ();
13463 c_rtx
= rs6000_emit_vector_compare (new_code
,
13464 op0
, op1
, dest_mode
);
13465 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
,
13468 ior_code
= optab_handler (ior_optab
, (int)dest_mode
)->insn_code
;
13469 gcc_assert (ior_code
!= CODE_FOR_nothing
);
13470 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
13471 if (dmode
!= dest_mode
)
13473 rtx temp
= gen_reg_rtx (dest_mode
);
13474 convert_move (temp
, mask
, 0);
13481 gcc_unreachable ();
13486 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
13487 /* You only get two chances. */
13488 gcc_assert (vec_cmp_insn
!= INSN_NOT_AVAILABLE
);
13500 emit_insn (gen_rtx_SET (VOIDmode
, mask
,
13501 gen_rtx_UNSPEC (dest_mode
,
13502 gen_rtvec (2, op0
, op1
),
13504 if (dmode
!= dest_mode
)
13506 rtx temp
= gen_reg_rtx (dest_mode
);
13507 convert_move (temp
, mask
, 0);
13513 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
13514 valid insn doesn exist for given mode. */
13517 get_vsel_insn (enum machine_mode mode
)
13522 return UNSPEC_VSEL4SI
;
13525 return UNSPEC_VSEL4SF
;
13528 return UNSPEC_VSEL8HI
;
13531 return UNSPEC_VSEL16QI
;
13534 return INSN_NOT_AVAILABLE
;
13537 return INSN_NOT_AVAILABLE
;
13540 /* Emit vector select insn where DEST is destination using
13541 operands OP1, OP2 and MASK. */
13544 rs6000_emit_vector_select (rtx dest
, rtx op1
, rtx op2
, rtx mask
)
13547 enum machine_mode dest_mode
= GET_MODE (dest
);
13548 int vsel_insn_index
= get_vsel_insn (GET_MODE (dest
));
13550 temp
= gen_reg_rtx (dest_mode
);
13552 /* For each vector element, select op1 when mask is 1 otherwise
13554 t
= gen_rtx_SET (VOIDmode
, temp
,
13555 gen_rtx_UNSPEC (dest_mode
,
13556 gen_rtvec (3, op2
, op1
, mask
),
13559 emit_move_insn (dest
, temp
);
13563 /* Emit vector conditional expression.
13564 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
13565 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
13568 rs6000_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
13569 rtx cond
, rtx cc_op0
, rtx cc_op1
)
13571 enum machine_mode dest_mode
= GET_MODE (dest
);
13572 enum rtx_code rcode
= GET_CODE (cond
);
13575 if (!TARGET_ALTIVEC
)
13578 /* Get the vector mask for the given relational operations. */
13579 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
13581 rs6000_emit_vector_select (dest
, op1
, op2
, mask
);
13586 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
13587 operands of the last comparison is nonzero/true, FALSE_COND if it
13588 is zero/false. Return 0 if the hardware has no such operation. */
13591 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
13593 enum rtx_code code
= GET_CODE (op
);
13594 rtx op0
= rs6000_compare_op0
;
13595 rtx op1
= rs6000_compare_op1
;
13596 REAL_VALUE_TYPE c1
;
13597 enum machine_mode compare_mode
= GET_MODE (op0
);
13598 enum machine_mode result_mode
= GET_MODE (dest
);
13600 bool is_against_zero
;
13602 /* These modes should always match. */
13603 if (GET_MODE (op1
) != compare_mode
13604 /* In the isel case however, we can use a compare immediate, so
13605 op1 may be a small constant. */
13606 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
13608 if (GET_MODE (true_cond
) != result_mode
)
13610 if (GET_MODE (false_cond
) != result_mode
)
13613 /* First, work out if the hardware can do this at all, or
13614 if it's too slow.... */
13615 if (! rs6000_compare_fp_p
)
13618 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
13621 else if (TARGET_HARD_FLOAT
&& !TARGET_FPRS
13622 && SCALAR_FLOAT_MODE_P (compare_mode
))
13625 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
13627 /* A floating-point subtract might overflow, underflow, or produce
13628 an inexact result, thus changing the floating-point flags, so it
13629 can't be generated if we care about that. It's safe if one side
13630 of the construct is zero, since then no subtract will be
13632 if (SCALAR_FLOAT_MODE_P (compare_mode
)
13633 && flag_trapping_math
&& ! is_against_zero
)
13636 /* Eliminate half of the comparisons by switching operands, this
13637 makes the remaining code simpler. */
13638 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
13639 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
13641 code
= reverse_condition_maybe_unordered (code
);
13643 true_cond
= false_cond
;
13647 /* UNEQ and LTGT take four instructions for a comparison with zero,
13648 it'll probably be faster to use a branch here too. */
13649 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
13652 if (GET_CODE (op1
) == CONST_DOUBLE
)
13653 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
13655 /* We're going to try to implement comparisons by performing
13656 a subtract, then comparing against zero. Unfortunately,
13657 Inf - Inf is NaN which is not zero, and so if we don't
13658 know that the operand is finite and the comparison
13659 would treat EQ different to UNORDERED, we can't do it. */
13660 if (HONOR_INFINITIES (compare_mode
)
13661 && code
!= GT
&& code
!= UNGE
13662 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
13663 /* Constructs of the form (a OP b ? a : b) are safe. */
13664 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
13665 || (! rtx_equal_p (op0
, true_cond
)
13666 && ! rtx_equal_p (op1
, true_cond
))))
13669 /* At this point we know we can use fsel. */
13671 /* Reduce the comparison to a comparison against zero. */
13672 if (! is_against_zero
)
13674 temp
= gen_reg_rtx (compare_mode
);
13675 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13676 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
13678 op1
= CONST0_RTX (compare_mode
);
13681 /* If we don't care about NaNs we can reduce some of the comparisons
13682 down to faster ones. */
13683 if (! HONOR_NANS (compare_mode
))
13689 true_cond
= false_cond
;
13702 /* Now, reduce everything down to a GE. */
13709 temp
= gen_reg_rtx (compare_mode
);
13710 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
13715 temp
= gen_reg_rtx (compare_mode
);
13716 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
13721 temp
= gen_reg_rtx (compare_mode
);
13722 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13723 gen_rtx_NEG (compare_mode
,
13724 gen_rtx_ABS (compare_mode
, op0
))));
13729 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
13730 temp
= gen_reg_rtx (result_mode
);
13731 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13732 gen_rtx_IF_THEN_ELSE (result_mode
,
13733 gen_rtx_GE (VOIDmode
,
13735 true_cond
, false_cond
)));
13736 false_cond
= true_cond
;
13739 temp
= gen_reg_rtx (compare_mode
);
13740 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
13745 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
13746 temp
= gen_reg_rtx (result_mode
);
13747 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13748 gen_rtx_IF_THEN_ELSE (result_mode
,
13749 gen_rtx_GE (VOIDmode
,
13751 true_cond
, false_cond
)));
13752 true_cond
= false_cond
;
13755 temp
= gen_reg_rtx (compare_mode
);
13756 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
13761 gcc_unreachable ();
13764 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
13765 gen_rtx_IF_THEN_ELSE (result_mode
,
13766 gen_rtx_GE (VOIDmode
,
13768 true_cond
, false_cond
)));
13772 /* Same as above, but for ints (isel). */
13775 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
13777 rtx condition_rtx
, cr
;
13779 /* All isel implementations thus far are 32-bits. */
13780 if (GET_MODE (rs6000_compare_op0
) != SImode
)
13783 /* We still have to do the compare, because isel doesn't do a
13784 compare, it just looks at the CRx bits set by a previous compare
13786 condition_rtx
= rs6000_generate_compare (GET_CODE (op
));
13787 cr
= XEXP (condition_rtx
, 0);
13789 if (GET_MODE (cr
) == CCmode
)
13790 emit_insn (gen_isel_signed (dest
, condition_rtx
,
13791 true_cond
, false_cond
, cr
));
13793 emit_insn (gen_isel_unsigned (dest
, condition_rtx
,
13794 true_cond
, false_cond
, cr
));
13800 output_isel (rtx
*operands
)
13802 enum rtx_code code
;
13804 code
= GET_CODE (operands
[1]);
13805 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
13807 PUT_CODE (operands
[1], reverse_condition (code
));
13808 return "isel %0,%3,%2,%j1";
13811 return "isel %0,%2,%3,%j1";
13815 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
13817 enum machine_mode mode
= GET_MODE (op0
);
13821 if (code
== SMAX
|| code
== SMIN
)
13826 if (code
== SMAX
|| code
== UMAX
)
13827 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
13828 op0
, op1
, mode
, 0);
13830 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
13831 op1
, op0
, mode
, 0);
13832 gcc_assert (target
);
13833 if (target
!= dest
)
13834 emit_move_insn (dest
, target
);
13837 /* Emit instructions to perform a load-reserved/store-conditional operation.
13838 The operation performed is an atomic
13839 (set M (CODE:MODE M OP))
13840 If not NULL, BEFORE is atomically set to M before the operation, and
13841 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
13842 If SYNC_P then a memory barrier is emitted before the operation.
13843 Either OP or M may be wrapped in a NOT operation. */
13846 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
13847 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
13850 enum machine_mode used_mode
;
13851 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
13854 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
13855 rtx shift
= NULL_RTX
;
13858 emit_insn (gen_lwsync ());
13862 /* If this is smaller than SImode, we'll have to use SImode with
13864 if (mode
== QImode
|| mode
== HImode
)
13868 if (MEM_ALIGN (used_m
) >= 32)
13871 if (BYTES_BIG_ENDIAN
)
13872 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
13874 shift
= GEN_INT (ishift
);
13875 used_m
= change_address (used_m
, SImode
, 0);
13879 rtx addrSI
, aligned_addr
;
13880 int shift_mask
= mode
== QImode
? 0x18 : 0x10;
13882 addrSI
= gen_lowpart_common (SImode
,
13883 force_reg (Pmode
, XEXP (used_m
, 0)));
13884 addrSI
= force_reg (SImode
, addrSI
);
13885 shift
= gen_reg_rtx (SImode
);
13887 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
13888 GEN_INT (shift_mask
)));
13889 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
13891 aligned_addr
= expand_binop (Pmode
, and_optab
,
13893 GEN_INT (-4), NULL_RTX
,
13894 1, OPTAB_LIB_WIDEN
);
13895 used_m
= change_address (used_m
, SImode
, aligned_addr
);
13896 set_mem_align (used_m
, 32);
13898 /* It's safe to keep the old alias set of USED_M, because
13899 the operation is atomic and only affects the original
13903 if (GET_CODE (op
) == NOT
)
13905 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
13906 oldop
= gen_rtx_NOT (SImode
, oldop
);
13909 oldop
= lowpart_subreg (SImode
, op
, mode
);
13915 newop
= expand_binop (SImode
, and_optab
,
13916 oldop
, GEN_INT (imask
), NULL_RTX
,
13917 1, OPTAB_LIB_WIDEN
);
13918 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
13921 case NOT
: /* NAND */
13922 newop
= expand_binop (SImode
, ior_optab
,
13923 oldop
, GEN_INT (~imask
), NULL_RTX
,
13924 1, OPTAB_LIB_WIDEN
);
13925 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
13929 newop
= expand_binop (SImode
, ior_optab
,
13930 oldop
, GEN_INT (~imask
), NULL_RTX
,
13931 1, OPTAB_LIB_WIDEN
);
13932 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
13940 newop
= expand_binop (SImode
, and_optab
,
13941 oldop
, GEN_INT (imask
), NULL_RTX
,
13942 1, OPTAB_LIB_WIDEN
);
13943 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
13945 mask
= gen_reg_rtx (SImode
);
13946 emit_move_insn (mask
, GEN_INT (imask
));
13947 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
13950 newop
= gen_rtx_PLUS (SImode
, m
, newop
);
13952 newop
= gen_rtx_MINUS (SImode
, m
, newop
);
13953 newop
= gen_rtx_AND (SImode
, newop
, mask
);
13954 newop
= gen_rtx_IOR (SImode
, newop
,
13955 gen_rtx_AND (SImode
,
13956 gen_rtx_NOT (SImode
, mask
),
13962 gcc_unreachable ();
13966 used_mode
= SImode
;
13967 before
= gen_reg_rtx (used_mode
);
13968 after
= gen_reg_rtx (used_mode
);
13973 before
= before_param
;
13974 after
= after_param
;
13976 if (before
== NULL_RTX
)
13977 before
= gen_reg_rtx (used_mode
);
13978 if (after
== NULL_RTX
)
13979 after
= gen_reg_rtx (used_mode
);
13982 if ((code
== PLUS
|| code
== MINUS
)
13983 && used_mode
!= mode
)
13984 the_op
= op
; /* Computed above. */
13985 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
13986 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
13987 else if (code
== NOT
)
13988 the_op
= gen_rtx_fmt_ee (IOR
, used_mode
,
13989 gen_rtx_NOT (used_mode
, m
),
13990 gen_rtx_NOT (used_mode
, op
));
13992 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
13994 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
13995 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
13996 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
13997 gen_rtx_UNSPEC (used_mode
,
13998 gen_rtvec (1, the_op
),
14000 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
14002 if ((code
== PLUS
|| code
== MINUS
) && used_mode
!= mode
)
14003 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
14004 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
14006 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
14007 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
14009 /* Shift and mask the return values properly. */
14010 if (used_mode
!= mode
&& before_param
)
14012 emit_insn (gen_lshrsi3 (before
, before
, shift
));
14013 convert_move (before_param
, before
, 1);
14016 if (used_mode
!= mode
&& after_param
)
14018 emit_insn (gen_lshrsi3 (after
, after
, shift
));
14019 convert_move (after_param
, after
, 1);
14022 /* The previous sequence will end with a branch that's dependent on
14023 the conditional store, so placing an isync will ensure that no
14024 other instructions (especially, no load or store instructions)
14025 can start before the atomic operation completes. */
14027 emit_insn (gen_isync ());
14030 /* A subroutine of the atomic operation splitters. Jump to LABEL if
14031 COND is true. Mark the jump as unlikely to be taken. */
14034 emit_unlikely_jump (rtx cond
, rtx label
)
14036 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
14039 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
14040 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
14041 add_reg_note (x
, REG_BR_PROB
, very_unlikely
);
14044 /* A subroutine of the atomic operation splitters. Emit a load-locked
14045 instruction in MODE. */
14048 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
14050 rtx (*fn
) (rtx
, rtx
) = NULL
;
14051 if (mode
== SImode
)
14052 fn
= gen_load_locked_si
;
14053 else if (mode
== DImode
)
14054 fn
= gen_load_locked_di
;
14055 emit_insn (fn (reg
, mem
));
14058 /* A subroutine of the atomic operation splitters. Emit a store-conditional
14059 instruction in MODE. */
14062 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
14064 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
14065 if (mode
== SImode
)
14066 fn
= gen_store_conditional_si
;
14067 else if (mode
== DImode
)
14068 fn
= gen_store_conditional_di
;
14070 /* Emit sync before stwcx. to address PPC405 Erratum. */
14071 if (PPC405_ERRATUM77
)
14072 emit_insn (gen_memory_barrier ());
14074 emit_insn (fn (res
, mem
, val
));
14077 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
14078 to perform. MEM is the memory on which to operate. VAL is the second
14079 operand of the binary operator. BEFORE and AFTER are optional locations to
14080 return the value of MEM either before of after the operation. SCRATCH is
14081 a scratch register. */
14084 rs6000_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
14085 rtx before
, rtx after
, rtx scratch
)
14087 enum machine_mode mode
= GET_MODE (mem
);
14088 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
14090 emit_insn (gen_lwsync ());
14092 label
= gen_label_rtx ();
14093 emit_label (label
);
14094 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
14096 if (before
== NULL_RTX
)
14098 emit_load_locked (mode
, before
, mem
);
14101 x
= gen_rtx_IOR (mode
,
14102 gen_rtx_NOT (mode
, before
),
14103 gen_rtx_NOT (mode
, val
));
14104 else if (code
== AND
)
14105 x
= gen_rtx_UNSPEC (mode
, gen_rtvec (2, before
, val
), UNSPEC_AND
);
14107 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
14109 if (after
!= NULL_RTX
)
14110 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
14111 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
14113 emit_store_conditional (mode
, cond
, mem
, scratch
);
14115 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14116 emit_unlikely_jump (x
, label
);
14118 emit_insn (gen_isync ());
14121 /* Expand an atomic compare and swap operation. MEM is the memory on which
14122 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
14123 value to be stored. SCRATCH is a scratch GPR. */
14126 rs6000_split_compare_and_swap (rtx retval
, rtx mem
, rtx oldval
, rtx newval
,
14129 enum machine_mode mode
= GET_MODE (mem
);
14130 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
14132 emit_insn (gen_lwsync ());
14134 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
14135 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
14136 emit_label (XEXP (label1
, 0));
14138 emit_load_locked (mode
, retval
, mem
);
14140 x
= gen_rtx_COMPARE (CCmode
, retval
, oldval
);
14141 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
14143 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14144 emit_unlikely_jump (x
, label2
);
14146 emit_move_insn (scratch
, newval
);
14147 emit_store_conditional (mode
, cond
, mem
, scratch
);
14149 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14150 emit_unlikely_jump (x
, label1
);
14152 emit_insn (gen_isync ());
14153 emit_label (XEXP (label2
, 0));
14156 /* Expand an atomic test and set operation. MEM is the memory on which
14157 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
14160 rs6000_split_lock_test_and_set (rtx retval
, rtx mem
, rtx val
, rtx scratch
)
14162 enum machine_mode mode
= GET_MODE (mem
);
14163 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
14165 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
14166 emit_label (XEXP (label
, 0));
14168 emit_load_locked (mode
, retval
, mem
);
14169 emit_move_insn (scratch
, val
);
14170 emit_store_conditional (mode
, cond
, mem
, scratch
);
14172 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14173 emit_unlikely_jump (x
, label
);
14175 emit_insn (gen_isync ());
14179 rs6000_expand_compare_and_swapqhi (rtx dst
, rtx mem
, rtx oldval
, rtx newval
)
14181 enum machine_mode mode
= GET_MODE (mem
);
14182 rtx addrSI
, align
, wdst
, shift
, mask
;
14183 HOST_WIDE_INT shift_mask
= mode
== QImode
? 0x18 : 0x10;
14184 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
14186 /* Shift amount for subword relative to aligned word. */
14187 addrSI
= force_reg (GET_MODE (XEXP (mem
, 0)), XEXP (mem
, 0));
14188 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
, addrSI
));
14189 shift
= gen_reg_rtx (SImode
);
14190 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
14191 GEN_INT (shift_mask
)));
14192 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
14194 /* Shift and mask old value into position within word. */
14195 oldval
= convert_modes (SImode
, mode
, oldval
, 1);
14196 oldval
= expand_binop (SImode
, and_optab
,
14197 oldval
, GEN_INT (imask
), NULL_RTX
,
14198 1, OPTAB_LIB_WIDEN
);
14199 emit_insn (gen_ashlsi3 (oldval
, oldval
, shift
));
14201 /* Shift and mask new value into position within word. */
14202 newval
= convert_modes (SImode
, mode
, newval
, 1);
14203 newval
= expand_binop (SImode
, and_optab
,
14204 newval
, GEN_INT (imask
), NULL_RTX
,
14205 1, OPTAB_LIB_WIDEN
);
14206 emit_insn (gen_ashlsi3 (newval
, newval
, shift
));
14208 /* Mask for insertion. */
14209 mask
= gen_reg_rtx (SImode
);
14210 emit_move_insn (mask
, GEN_INT (imask
));
14211 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
14213 /* Address of aligned word containing subword. */
14214 align
= expand_binop (Pmode
, and_optab
, XEXP (mem
, 0), GEN_INT (-4),
14215 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
14216 mem
= change_address (mem
, SImode
, align
);
14217 set_mem_align (mem
, 32);
14218 MEM_VOLATILE_P (mem
) = 1;
14220 wdst
= gen_reg_rtx (SImode
);
14221 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst
, mask
,
14222 oldval
, newval
, mem
));
14224 /* Shift the result back. */
14225 emit_insn (gen_lshrsi3 (wdst
, wdst
, shift
));
14227 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
14231 rs6000_split_compare_and_swapqhi (rtx dest
, rtx mask
,
14232 rtx oldval
, rtx newval
, rtx mem
,
14235 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
14237 emit_insn (gen_lwsync ());
14238 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
14239 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
14240 emit_label (XEXP (label1
, 0));
14242 emit_load_locked (SImode
, scratch
, mem
);
14244 /* Mask subword within loaded value for comparison with oldval.
14245 Use UNSPEC_AND to avoid clobber.*/
14246 emit_insn (gen_rtx_SET (SImode
, dest
,
14247 gen_rtx_UNSPEC (SImode
,
14248 gen_rtvec (2, scratch
, mask
),
14251 x
= gen_rtx_COMPARE (CCmode
, dest
, oldval
);
14252 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
14254 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14255 emit_unlikely_jump (x
, label2
);
14257 /* Clear subword within loaded value for insertion of new value. */
14258 emit_insn (gen_rtx_SET (SImode
, scratch
,
14259 gen_rtx_AND (SImode
,
14260 gen_rtx_NOT (SImode
, mask
), scratch
)));
14261 emit_insn (gen_iorsi3 (scratch
, scratch
, newval
));
14262 emit_store_conditional (SImode
, cond
, mem
, scratch
);
14264 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14265 emit_unlikely_jump (x
, label1
);
14267 emit_insn (gen_isync ());
14268 emit_label (XEXP (label2
, 0));
14272 /* Emit instructions to move SRC to DST. Called by splitters for
14273 multi-register moves. It will emit at most one instruction for
14274 each register that is accessed; that is, it won't emit li/lis pairs
14275 (or equivalent for 64-bit code). One of SRC or DST must be a hard
14279 rs6000_split_multireg_move (rtx dst
, rtx src
)
14281 /* The register number of the first register being moved. */
14283 /* The mode that is to be moved. */
14284 enum machine_mode mode
;
14285 /* The mode that the move is being done in, and its size. */
14286 enum machine_mode reg_mode
;
14288 /* The number of registers that will be moved. */
14291 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
14292 mode
= GET_MODE (dst
);
14293 nregs
= hard_regno_nregs
[reg
][mode
];
14294 if (FP_REGNO_P (reg
))
14295 reg_mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
:
14296 ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? DFmode
: SFmode
);
14297 else if (ALTIVEC_REGNO_P (reg
))
14298 reg_mode
= V16QImode
;
14299 else if (TARGET_E500_DOUBLE
&& mode
== TFmode
)
14302 reg_mode
= word_mode
;
14303 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
14305 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
14307 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
14309 /* Move register range backwards, if we might have destructive
14312 for (i
= nregs
- 1; i
>= 0; i
--)
14313 emit_insn (gen_rtx_SET (VOIDmode
,
14314 simplify_gen_subreg (reg_mode
, dst
, mode
,
14315 i
* reg_mode_size
),
14316 simplify_gen_subreg (reg_mode
, src
, mode
,
14317 i
* reg_mode_size
)));
14323 bool used_update
= false;
14325 if (MEM_P (src
) && INT_REGNO_P (reg
))
14329 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
14330 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
14333 breg
= XEXP (XEXP (src
, 0), 0);
14334 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
14335 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
14336 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
14337 emit_insn (TARGET_32BIT
14338 ? gen_addsi3 (breg
, breg
, delta_rtx
)
14339 : gen_adddi3 (breg
, breg
, delta_rtx
));
14340 src
= replace_equiv_address (src
, breg
);
14342 else if (! rs6000_offsettable_memref_p (src
))
14345 basereg
= gen_rtx_REG (Pmode
, reg
);
14346 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
14347 src
= replace_equiv_address (src
, basereg
);
14350 breg
= XEXP (src
, 0);
14351 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
14352 breg
= XEXP (breg
, 0);
14354 /* If the base register we are using to address memory is
14355 also a destination reg, then change that register last. */
14357 && REGNO (breg
) >= REGNO (dst
)
14358 && REGNO (breg
) < REGNO (dst
) + nregs
)
14359 j
= REGNO (breg
) - REGNO (dst
);
14362 if (GET_CODE (dst
) == MEM
&& INT_REGNO_P (reg
))
14366 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
14367 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
14370 breg
= XEXP (XEXP (dst
, 0), 0);
14371 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
14372 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
14373 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
14375 /* We have to update the breg before doing the store.
14376 Use store with update, if available. */
14380 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
14381 emit_insn (TARGET_32BIT
14382 ? (TARGET_POWERPC64
14383 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
14384 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
14385 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
14386 used_update
= true;
14389 emit_insn (TARGET_32BIT
14390 ? gen_addsi3 (breg
, breg
, delta_rtx
)
14391 : gen_adddi3 (breg
, breg
, delta_rtx
));
14392 dst
= replace_equiv_address (dst
, breg
);
14395 gcc_assert (rs6000_offsettable_memref_p (dst
));
14398 for (i
= 0; i
< nregs
; i
++)
14400 /* Calculate index to next subword. */
14405 /* If compiler already emitted move of first word by
14406 store with update, no need to do anything. */
14407 if (j
== 0 && used_update
)
14410 emit_insn (gen_rtx_SET (VOIDmode
,
14411 simplify_gen_subreg (reg_mode
, dst
, mode
,
14412 j
* reg_mode_size
),
14413 simplify_gen_subreg (reg_mode
, src
, mode
,
14414 j
* reg_mode_size
)));
14420 /* This page contains routines that are used to determine what the
14421 function prologue and epilogue code will do and write them out. */
14423 /* Return the first fixed-point register that is required to be
14424 saved. 32 if none. */
14427 first_reg_to_save (void)
14431 /* Find lowest numbered live register. */
14432 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
14433 if (df_regs_ever_live_p (first_reg
)
14434 && (! call_used_regs
[first_reg
]
14435 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
14436 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
14437 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
14438 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
14443 && crtl
->uses_pic_offset_table
14444 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
14445 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
14451 /* Similar, for FP regs. */
14454 first_fp_reg_to_save (void)
14458 /* Find lowest numbered live register. */
14459 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
14460 if (df_regs_ever_live_p (first_reg
))
14466 /* Similar, for AltiVec regs. */
14469 first_altivec_reg_to_save (void)
14473 /* Stack frame remains as is unless we are in AltiVec ABI. */
14474 if (! TARGET_ALTIVEC_ABI
)
14475 return LAST_ALTIVEC_REGNO
+ 1;
14477 /* On Darwin, the unwind routines are compiled without
14478 TARGET_ALTIVEC, and use save_world to save/restore the
14479 altivec registers when necessary. */
14480 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
14481 && ! TARGET_ALTIVEC
)
14482 return FIRST_ALTIVEC_REGNO
+ 20;
14484 /* Find lowest numbered live register. */
14485 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14486 if (df_regs_ever_live_p (i
))
14492 /* Return a 32-bit mask of the AltiVec registers we need to set in
14493 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
14494 the 32-bit word is 0. */
14496 static unsigned int
14497 compute_vrsave_mask (void)
14499 unsigned int i
, mask
= 0;
14501 /* On Darwin, the unwind routines are compiled without
14502 TARGET_ALTIVEC, and use save_world to save/restore the
14503 call-saved altivec registers when necessary. */
14504 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
14505 && ! TARGET_ALTIVEC
)
14508 /* First, find out if we use _any_ altivec registers. */
14509 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14510 if (df_regs_ever_live_p (i
))
14511 mask
|= ALTIVEC_REG_BIT (i
);
14516 /* Next, remove the argument registers from the set. These must
14517 be in the VRSAVE mask set by the caller, so we don't need to add
14518 them in again. More importantly, the mask we compute here is
14519 used to generate CLOBBERs in the set_vrsave insn, and we do not
14520 wish the argument registers to die. */
14521 for (i
= crtl
->args
.info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
14522 mask
&= ~ALTIVEC_REG_BIT (i
);
14524 /* Similarly, remove the return value from the set. */
14527 diddle_return_value (is_altivec_return_reg
, &yes
);
14529 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
14535 /* For a very restricted set of circumstances, we can cut down the
14536 size of prologues/epilogues by calling our own save/restore-the-world
14540 compute_save_world_info (rs6000_stack_t
*info_ptr
)
14542 info_ptr
->world_save_p
= 1;
14543 info_ptr
->world_save_p
14544 = (WORLD_SAVE_P (info_ptr
)
14545 && DEFAULT_ABI
== ABI_DARWIN
14546 && ! (cfun
->calls_setjmp
&& flag_exceptions
)
14547 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
14548 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
14549 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
14550 && info_ptr
->cr_save_p
);
14552 /* This will not work in conjunction with sibcalls. Make sure there
14553 are none. (This check is expensive, but seldom executed.) */
14554 if (WORLD_SAVE_P (info_ptr
))
14557 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
14558 if ( GET_CODE (insn
) == CALL_INSN
14559 && SIBLING_CALL_P (insn
))
14561 info_ptr
->world_save_p
= 0;
14566 if (WORLD_SAVE_P (info_ptr
))
14568 /* Even if we're not touching VRsave, make sure there's room on the
14569 stack for it, if it looks like we're calling SAVE_WORLD, which
14570 will attempt to save it. */
14571 info_ptr
->vrsave_size
= 4;
14573 /* If we are going to save the world, we need to save the link register too. */
14574 info_ptr
->lr_save_p
= 1;
14576 /* "Save" the VRsave register too if we're saving the world. */
14577 if (info_ptr
->vrsave_mask
== 0)
14578 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
14580 /* Because the Darwin register save/restore routines only handle
14581 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
14583 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
14584 && (info_ptr
->first_altivec_reg_save
14585 >= FIRST_SAVED_ALTIVEC_REGNO
));
14592 is_altivec_return_reg (rtx reg
, void *xyes
)
14594 bool *yes
= (bool *) xyes
;
14595 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
14600 /* Calculate the stack information for the current function. This is
14601 complicated by having two separate calling sequences, the AIX calling
14602 sequence and the V.4 calling sequence.
14604 AIX (and Darwin/Mac OS X) stack frames look like:
14606 SP----> +---------------------------------------+
14607 | back chain to caller | 0 0
14608 +---------------------------------------+
14609 | saved CR | 4 8 (8-11)
14610 +---------------------------------------+
14612 +---------------------------------------+
14613 | reserved for compilers | 12 24
14614 +---------------------------------------+
14615 | reserved for binders | 16 32
14616 +---------------------------------------+
14617 | saved TOC pointer | 20 40
14618 +---------------------------------------+
14619 | Parameter save area (P) | 24 48
14620 +---------------------------------------+
14621 | Alloca space (A) | 24+P etc.
14622 +---------------------------------------+
14623 | Local variable space (L) | 24+P+A
14624 +---------------------------------------+
14625 | Float/int conversion temporary (X) | 24+P+A+L
14626 +---------------------------------------+
14627 | Save area for AltiVec registers (W) | 24+P+A+L+X
14628 +---------------------------------------+
14629 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
14630 +---------------------------------------+
14631 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
14632 +---------------------------------------+
14633 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
14634 +---------------------------------------+
14635 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
14636 +---------------------------------------+
14637 old SP->| back chain to caller's caller |
14638 +---------------------------------------+
14640 The required alignment for AIX configurations is two words (i.e., 8
14644 V.4 stack frames look like:
14646 SP----> +---------------------------------------+
14647 | back chain to caller | 0
14648 +---------------------------------------+
14649 | caller's saved LR | 4
14650 +---------------------------------------+
14651 | Parameter save area (P) | 8
14652 +---------------------------------------+
14653 | Alloca space (A) | 8+P
14654 +---------------------------------------+
14655 | Varargs save area (V) | 8+P+A
14656 +---------------------------------------+
14657 | Local variable space (L) | 8+P+A+V
14658 +---------------------------------------+
14659 | Float/int conversion temporary (X) | 8+P+A+V+L
14660 +---------------------------------------+
14661 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
14662 +---------------------------------------+
14663 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
14664 +---------------------------------------+
14665 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
14666 +---------------------------------------+
14667 | SPE: area for 64-bit GP registers |
14668 +---------------------------------------+
14669 | SPE alignment padding |
14670 +---------------------------------------+
14671 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
14672 +---------------------------------------+
14673 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
14674 +---------------------------------------+
14675 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
14676 +---------------------------------------+
14677 old SP->| back chain to caller's caller |
14678 +---------------------------------------+
14680 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
14681 given. (But note below and in sysv4.h that we require only 8 and
14682 may round up the size of our stack frame anyways. The historical
14683 reason is early versions of powerpc-linux which didn't properly
14684 align the stack at program startup. A happy side-effect is that
14685 -mno-eabi libraries can be used with -meabi programs.)
14687 The EABI configuration defaults to the V.4 layout. However,
14688 the stack alignment requirements may differ. If -mno-eabi is not
14689 given, the required stack alignment is 8 bytes; if -mno-eabi is
14690 given, the required alignment is 16 bytes. (But see V.4 comment
14693 #ifndef ABI_STACK_BOUNDARY
14694 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
14697 static rs6000_stack_t
*
14698 rs6000_stack_info (void)
14700 static rs6000_stack_t info
;
14701 rs6000_stack_t
*info_ptr
= &info
;
14702 int reg_size
= TARGET_32BIT
? 4 : 8;
14706 HOST_WIDE_INT non_fixed_size
;
14708 memset (&info
, 0, sizeof (info
));
14712 /* Cache value so we don't rescan instruction chain over and over. */
14713 if (cfun
->machine
->insn_chain_scanned_p
== 0)
14714 cfun
->machine
->insn_chain_scanned_p
14715 = spe_func_has_64bit_regs_p () + 1;
14716 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
14719 /* Select which calling sequence. */
14720 info_ptr
->abi
= DEFAULT_ABI
;
14722 /* Calculate which registers need to be saved & save area size. */
14723 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
14724 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
14725 even if it currently looks like we won't. Reload may need it to
14726 get at a constant; if so, it will have already created a constant
14727 pool entry for it. */
14728 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
14729 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
14730 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
14731 && crtl
->uses_const_pool
14732 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
14733 first_gp
= RS6000_PIC_OFFSET_TABLE_REGNUM
;
14735 first_gp
= info_ptr
->first_gp_reg_save
;
14737 info_ptr
->gp_size
= reg_size
* (32 - first_gp
);
14739 /* For the SPE, we have an additional upper 32-bits on each GPR.
14740 Ideally we should save the entire 64-bits only when the upper
14741 half is used in SIMD instructions. Since we only record
14742 registers live (not the size they are used in), this proves
14743 difficult because we'd have to traverse the instruction chain at
14744 the right time, taking reload into account. This is a real pain,
14745 so we opt to save the GPRs in 64-bits always if but one register
14746 gets used in 64-bits. Otherwise, all the registers in the frame
14747 get saved in 32-bits.
14749 So... since when we save all GPRs (except the SP) in 64-bits, the
14750 traditional GP save area will be empty. */
14751 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
14752 info_ptr
->gp_size
= 0;
14754 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
14755 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
14757 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
14758 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
14759 - info_ptr
->first_altivec_reg_save
);
14761 /* Does this function call anything? */
14762 info_ptr
->calls_p
= (! current_function_is_leaf
14763 || cfun
->machine
->ra_needs_full_frame
);
14765 /* Determine if we need to save the link register. */
14766 if ((DEFAULT_ABI
== ABI_AIX
14768 && !TARGET_PROFILE_KERNEL
)
14769 #ifdef TARGET_RELOCATABLE
14770 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
14772 || (info_ptr
->first_fp_reg_save
!= 64
14773 && !FP_SAVE_INLINE (info_ptr
->first_fp_reg_save
))
14774 || (DEFAULT_ABI
== ABI_V4
&& cfun
->calls_alloca
)
14775 || info_ptr
->calls_p
14776 || rs6000_ra_ever_killed ())
14778 info_ptr
->lr_save_p
= 1;
14779 df_set_regs_ever_live (LR_REGNO
, true);
14782 /* Determine if we need to save the condition code registers. */
14783 if (df_regs_ever_live_p (CR2_REGNO
)
14784 || df_regs_ever_live_p (CR3_REGNO
)
14785 || df_regs_ever_live_p (CR4_REGNO
))
14787 info_ptr
->cr_save_p
= 1;
14788 if (DEFAULT_ABI
== ABI_V4
)
14789 info_ptr
->cr_size
= reg_size
;
14792 /* If the current function calls __builtin_eh_return, then we need
14793 to allocate stack space for registers that will hold data for
14794 the exception handler. */
14795 if (crtl
->calls_eh_return
)
14798 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
14801 /* SPE saves EH registers in 64-bits. */
14802 ehrd_size
= i
* (TARGET_SPE_ABI
14803 && info_ptr
->spe_64bit_regs_used
!= 0
14804 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
14809 /* Determine various sizes. */
14810 info_ptr
->reg_size
= reg_size
;
14811 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
14812 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
14813 info_ptr
->parm_size
= RS6000_ALIGN (crtl
->outgoing_args_size
,
14814 TARGET_ALTIVEC
? 16 : 8);
14815 if (FRAME_GROWS_DOWNWARD
)
14816 info_ptr
->vars_size
14817 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
14818 + info_ptr
->parm_size
,
14819 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
14820 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
14821 + info_ptr
->parm_size
);
14823 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
14824 info_ptr
->spe_gp_size
= 8 * (32 - first_gp
);
14826 info_ptr
->spe_gp_size
= 0;
14828 if (TARGET_ALTIVEC_ABI
)
14829 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
14831 info_ptr
->vrsave_mask
= 0;
14833 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
14834 info_ptr
->vrsave_size
= 4;
14836 info_ptr
->vrsave_size
= 0;
14838 compute_save_world_info (info_ptr
);
14840 /* Calculate the offsets. */
14841 switch (DEFAULT_ABI
)
14845 gcc_unreachable ();
14849 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
14850 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
14852 if (TARGET_ALTIVEC_ABI
)
14854 info_ptr
->vrsave_save_offset
14855 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
14857 /* Align stack so vector save area is on a quadword boundary.
14858 The padding goes above the vectors. */
14859 if (info_ptr
->altivec_size
!= 0)
14860 info_ptr
->altivec_padding_size
14861 = info_ptr
->vrsave_save_offset
& 0xF;
14863 info_ptr
->altivec_padding_size
= 0;
14865 info_ptr
->altivec_save_offset
14866 = info_ptr
->vrsave_save_offset
14867 - info_ptr
->altivec_padding_size
14868 - info_ptr
->altivec_size
;
14869 gcc_assert (info_ptr
->altivec_size
== 0
14870 || info_ptr
->altivec_save_offset
% 16 == 0);
14872 /* Adjust for AltiVec case. */
14873 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
14876 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
14877 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
14878 info_ptr
->lr_save_offset
= 2*reg_size
;
14882 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
14883 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
14884 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
14886 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
14888 /* Align stack so SPE GPR save area is aligned on a
14889 double-word boundary. */
14890 if (info_ptr
->spe_gp_size
!= 0 && info_ptr
->cr_save_offset
!= 0)
14891 info_ptr
->spe_padding_size
14892 = 8 - (-info_ptr
->cr_save_offset
% 8);
14894 info_ptr
->spe_padding_size
= 0;
14896 info_ptr
->spe_gp_save_offset
14897 = info_ptr
->cr_save_offset
14898 - info_ptr
->spe_padding_size
14899 - info_ptr
->spe_gp_size
;
14901 /* Adjust for SPE case. */
14902 info_ptr
->ehrd_offset
= info_ptr
->spe_gp_save_offset
;
14904 else if (TARGET_ALTIVEC_ABI
)
14906 info_ptr
->vrsave_save_offset
14907 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
14909 /* Align stack so vector save area is on a quadword boundary. */
14910 if (info_ptr
->altivec_size
!= 0)
14911 info_ptr
->altivec_padding_size
14912 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
14914 info_ptr
->altivec_padding_size
= 0;
14916 info_ptr
->altivec_save_offset
14917 = info_ptr
->vrsave_save_offset
14918 - info_ptr
->altivec_padding_size
14919 - info_ptr
->altivec_size
;
14921 /* Adjust for AltiVec case. */
14922 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
;
14925 info_ptr
->ehrd_offset
= info_ptr
->cr_save_offset
;
14926 info_ptr
->ehrd_offset
-= ehrd_size
;
14927 info_ptr
->lr_save_offset
= reg_size
;
14931 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
14932 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
14933 + info_ptr
->gp_size
14934 + info_ptr
->altivec_size
14935 + info_ptr
->altivec_padding_size
14936 + info_ptr
->spe_gp_size
14937 + info_ptr
->spe_padding_size
14939 + info_ptr
->cr_size
14940 + info_ptr
->vrsave_size
,
14943 non_fixed_size
= (info_ptr
->vars_size
14944 + info_ptr
->parm_size
14945 + info_ptr
->save_size
);
14947 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
14948 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
14950 /* Determine if we need to allocate any stack frame:
14952 For AIX we need to push the stack if a frame pointer is needed
14953 (because the stack might be dynamically adjusted), if we are
14954 debugging, if we make calls, or if the sum of fp_save, gp_save,
14955 and local variables are more than the space needed to save all
14956 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
14957 + 18*8 = 288 (GPR13 reserved).
14959 For V.4 we don't have the stack cushion that AIX uses, but assume
14960 that the debugger can handle stackless frames. */
14962 if (info_ptr
->calls_p
)
14963 info_ptr
->push_p
= 1;
14965 else if (DEFAULT_ABI
== ABI_V4
)
14966 info_ptr
->push_p
= non_fixed_size
!= 0;
14968 else if (frame_pointer_needed
)
14969 info_ptr
->push_p
= 1;
14971 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
14972 info_ptr
->push_p
= 1;
14975 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
14977 /* Zero offsets if we're not saving those registers. */
14978 if (info_ptr
->fp_size
== 0)
14979 info_ptr
->fp_save_offset
= 0;
14981 if (info_ptr
->gp_size
== 0)
14982 info_ptr
->gp_save_offset
= 0;
14984 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
14985 info_ptr
->altivec_save_offset
= 0;
14987 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
14988 info_ptr
->vrsave_save_offset
= 0;
14990 if (! TARGET_SPE_ABI
14991 || info_ptr
->spe_64bit_regs_used
== 0
14992 || info_ptr
->spe_gp_size
== 0)
14993 info_ptr
->spe_gp_save_offset
= 0;
14995 if (! info_ptr
->lr_save_p
)
14996 info_ptr
->lr_save_offset
= 0;
14998 if (! info_ptr
->cr_save_p
)
14999 info_ptr
->cr_save_offset
= 0;
15004 /* Return true if the current function uses any GPRs in 64-bit SIMD
15008 spe_func_has_64bit_regs_p (void)
15012 /* Functions that save and restore all the call-saved registers will
15013 need to save/restore the registers in 64-bits. */
15014 if (crtl
->calls_eh_return
15015 || cfun
->calls_setjmp
15016 || crtl
->has_nonlocal_goto
)
15019 insns
= get_insns ();
15021 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
15027 /* FIXME: This should be implemented with attributes...
15029 (set_attr "spe64" "true")....then,
15030 if (get_spe64(insn)) return true;
15032 It's the only reliable way to do the stuff below. */
15034 i
= PATTERN (insn
);
15035 if (GET_CODE (i
) == SET
)
15037 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
15039 if (SPE_VECTOR_MODE (mode
))
15041 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
))
15051 debug_stack_info (rs6000_stack_t
*info
)
15053 const char *abi_string
;
15056 info
= rs6000_stack_info ();
15058 fprintf (stderr
, "\nStack information for function %s:\n",
15059 ((current_function_decl
&& DECL_NAME (current_function_decl
))
15060 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
15065 default: abi_string
= "Unknown"; break;
15066 case ABI_NONE
: abi_string
= "NONE"; break;
15067 case ABI_AIX
: abi_string
= "AIX"; break;
15068 case ABI_DARWIN
: abi_string
= "Darwin"; break;
15069 case ABI_V4
: abi_string
= "V.4"; break;
15072 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
15074 if (TARGET_ALTIVEC_ABI
)
15075 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
15077 if (TARGET_SPE_ABI
)
15078 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
15080 if (info
->first_gp_reg_save
!= 32)
15081 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
15083 if (info
->first_fp_reg_save
!= 64)
15084 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
15086 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
15087 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
15088 info
->first_altivec_reg_save
);
15090 if (info
->lr_save_p
)
15091 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
15093 if (info
->cr_save_p
)
15094 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
15096 if (info
->vrsave_mask
)
15097 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
15100 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
15103 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
15105 if (info
->gp_save_offset
)
15106 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
15108 if (info
->fp_save_offset
)
15109 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
15111 if (info
->altivec_save_offset
)
15112 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
15113 info
->altivec_save_offset
);
15115 if (info
->spe_gp_save_offset
)
15116 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
15117 info
->spe_gp_save_offset
);
15119 if (info
->vrsave_save_offset
)
15120 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
15121 info
->vrsave_save_offset
);
15123 if (info
->lr_save_offset
)
15124 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
15126 if (info
->cr_save_offset
)
15127 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
15129 if (info
->varargs_save_offset
)
15130 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
15132 if (info
->total_size
)
15133 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
15136 if (info
->vars_size
)
15137 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
15140 if (info
->parm_size
)
15141 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
15143 if (info
->fixed_size
)
15144 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
15147 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
15149 if (info
->spe_gp_size
)
15150 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
15153 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
15155 if (info
->altivec_size
)
15156 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
15158 if (info
->vrsave_size
)
15159 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
15161 if (info
->altivec_padding_size
)
15162 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
15163 info
->altivec_padding_size
);
15165 if (info
->spe_padding_size
)
15166 fprintf (stderr
, "\tspe_padding_size = %5d\n",
15167 info
->spe_padding_size
);
15170 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
15172 if (info
->save_size
)
15173 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
15175 if (info
->reg_size
!= 4)
15176 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
15178 fprintf (stderr
, "\n");
15182 rs6000_return_addr (int count
, rtx frame
)
15184 /* Currently we don't optimize very well between prolog and body
15185 code and for PIC code the code can be actually quite bad, so
15186 don't try to be too clever here. */
15187 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
15189 cfun
->machine
->ra_needs_full_frame
= 1;
15196 plus_constant (copy_to_reg
15197 (gen_rtx_MEM (Pmode
,
15198 memory_address (Pmode
, frame
))),
15199 RETURN_ADDRESS_OFFSET
)));
15202 cfun
->machine
->ra_need_lr
= 1;
15203 return get_hard_reg_initial_val (Pmode
, LR_REGNO
);
15206 /* Say whether a function is a candidate for sibcall handling or not.
15207 We do not allow indirect calls to be optimized into sibling calls.
15208 Also, we can't do it if there are any vector parameters; there's
15209 nowhere to put the VRsave code so it works; note that functions with
15210 vector parameters are required to have a prototype, so the argument
15211 type info must be available here. (The tail recursion case can work
15212 with vector parameters, but there's no way to distinguish here.) */
15214 rs6000_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
15219 if (TARGET_ALTIVEC_VRSAVE
)
15221 for (type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
15222 type
; type
= TREE_CHAIN (type
))
15224 if (TREE_CODE (TREE_VALUE (type
)) == VECTOR_TYPE
)
15228 if (DEFAULT_ABI
== ABI_DARWIN
15229 || ((*targetm
.binds_local_p
) (decl
)
15230 && (DEFAULT_ABI
!= ABI_AIX
|| !DECL_EXTERNAL (decl
))))
15232 tree attr_list
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
15234 if (!lookup_attribute ("longcall", attr_list
)
15235 || lookup_attribute ("shortcall", attr_list
))
15242 /* NULL if INSN insn is valid within a low-overhead loop.
15243 Otherwise return why doloop cannot be applied.
15244 PowerPC uses the COUNT register for branch on table instructions. */
15246 static const char *
15247 rs6000_invalid_within_doloop (const_rtx insn
)
15250 return "Function call in the loop.";
15253 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
15254 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
15255 return "Computed branch in the loop.";
15261 rs6000_ra_ever_killed (void)
15267 if (cfun
->is_thunk
)
15270 /* regs_ever_live has LR marked as used if any sibcalls are present,
15271 but this should not force saving and restoring in the
15272 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
15273 clobbers LR, so that is inappropriate. */
15275 /* Also, the prologue can generate a store into LR that
15276 doesn't really count, like this:
15279 bcl to set PIC register
15283 When we're called from the epilogue, we need to avoid counting
15284 this as a store. */
15286 push_topmost_sequence ();
15287 top
= get_insns ();
15288 pop_topmost_sequence ();
15289 reg
= gen_rtx_REG (Pmode
, LR_REGNO
);
15291 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
15297 if (!SIBLING_CALL_P (insn
))
15300 else if (find_regno_note (insn
, REG_INC
, LR_REGNO
))
15302 else if (set_of (reg
, insn
) != NULL_RTX
15303 && !prologue_epilogue_contains (insn
))
15310 /* Emit instructions needed to load the TOC register.
15311 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
15312 a constant pool; or for SVR4 -fpic. */
15315 rs6000_emit_load_toc_table (int fromprolog
)
15318 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
15320 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
15323 rtx lab
, tmp1
, tmp2
, got
;
15325 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
15326 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15328 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
15330 got
= rs6000_got_sym ();
15331 tmp1
= tmp2
= dest
;
15334 tmp1
= gen_reg_rtx (Pmode
);
15335 tmp2
= gen_reg_rtx (Pmode
);
15337 emit_insn (gen_load_toc_v4_PIC_1 (lab
));
15338 emit_move_insn (tmp1
,
15339 gen_rtx_REG (Pmode
, LR_REGNO
));
15340 emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
15341 emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
15343 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
15345 emit_insn (gen_load_toc_v4_pic_si ());
15346 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
15348 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
15351 rtx temp0
= (fromprolog
15352 ? gen_rtx_REG (Pmode
, 0)
15353 : gen_reg_rtx (Pmode
));
15359 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
15360 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15362 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
15363 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15365 emit_insn (gen_load_toc_v4_PIC_1 (symF
));
15366 emit_move_insn (dest
,
15367 gen_rtx_REG (Pmode
, LR_REGNO
));
15368 emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
, symL
, symF
));
15374 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
15375 emit_insn (gen_load_toc_v4_PIC_1b (tocsym
));
15376 emit_move_insn (dest
,
15377 gen_rtx_REG (Pmode
, LR_REGNO
));
15378 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
15380 emit_insn (gen_addsi3 (dest
, temp0
, dest
));
15382 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
15384 /* This is for AIX code running in non-PIC ELF32. */
15387 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
15388 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15390 emit_insn (gen_elf_high (dest
, realsym
));
15391 emit_insn (gen_elf_low (dest
, dest
, realsym
));
15395 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
15398 emit_insn (gen_load_toc_aix_si (dest
));
15400 emit_insn (gen_load_toc_aix_di (dest
));
15404 /* Emit instructions to restore the link register after determining where
15405 its value has been stored. */
15408 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
15410 rs6000_stack_t
*info
= rs6000_stack_info ();
15413 operands
[0] = source
;
15414 operands
[1] = scratch
;
15416 if (info
->lr_save_p
)
15418 rtx frame_rtx
= stack_pointer_rtx
;
15419 HOST_WIDE_INT sp_offset
= 0;
15422 if (frame_pointer_needed
15423 || cfun
->calls_alloca
15424 || info
->total_size
> 32767)
15426 tmp
= gen_frame_mem (Pmode
, frame_rtx
);
15427 emit_move_insn (operands
[1], tmp
);
15428 frame_rtx
= operands
[1];
15430 else if (info
->push_p
)
15431 sp_offset
= info
->total_size
;
15433 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
15434 tmp
= gen_frame_mem (Pmode
, tmp
);
15435 emit_move_insn (tmp
, operands
[0]);
15438 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
), operands
[0]);
15441 static GTY(()) alias_set_type set
= -1;
15444 get_TOC_alias_set (void)
15447 set
= new_alias_set ();
15451 /* This returns nonzero if the current function uses the TOC. This is
15452 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
15453 is generated by the ABI_V4 load_toc_* patterns. */
15460 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
15463 rtx pat
= PATTERN (insn
);
15466 if (GET_CODE (pat
) == PARALLEL
)
15467 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
15469 rtx sub
= XVECEXP (pat
, 0, i
);
15470 if (GET_CODE (sub
) == USE
)
15472 sub
= XEXP (sub
, 0);
15473 if (GET_CODE (sub
) == UNSPEC
15474 && XINT (sub
, 1) == UNSPEC_TOC
)
15484 create_TOC_reference (rtx symbol
)
15486 if (!can_create_pseudo_p ())
15487 df_set_regs_ever_live (TOC_REGISTER
, true);
15488 return gen_rtx_PLUS (Pmode
,
15489 gen_rtx_REG (Pmode
, TOC_REGISTER
),
15490 gen_rtx_CONST (Pmode
,
15491 gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, symbol
), UNSPEC_TOCREL
)));
15494 /* If _Unwind_* has been called from within the same module,
15495 toc register is not guaranteed to be saved to 40(1) on function
15496 entry. Save it there in that case. */
15499 rs6000_aix_emit_builtin_unwind_init (void)
15502 rtx stack_top
= gen_reg_rtx (Pmode
);
15503 rtx opcode_addr
= gen_reg_rtx (Pmode
);
15504 rtx opcode
= gen_reg_rtx (SImode
);
15505 rtx tocompare
= gen_reg_rtx (SImode
);
15506 rtx no_toc_save_needed
= gen_label_rtx ();
15508 mem
= gen_frame_mem (Pmode
, hard_frame_pointer_rtx
);
15509 emit_move_insn (stack_top
, mem
);
15511 mem
= gen_frame_mem (Pmode
,
15512 gen_rtx_PLUS (Pmode
, stack_top
,
15513 GEN_INT (2 * GET_MODE_SIZE (Pmode
))));
15514 emit_move_insn (opcode_addr
, mem
);
15515 emit_move_insn (opcode
, gen_rtx_MEM (SImode
, opcode_addr
));
15516 emit_move_insn (tocompare
, gen_int_mode (TARGET_32BIT
? 0x80410014
15517 : 0xE8410028, SImode
));
15519 do_compare_rtx_and_jump (opcode
, tocompare
, EQ
, 1,
15520 SImode
, NULL_RTX
, NULL_RTX
,
15521 no_toc_save_needed
);
15523 mem
= gen_frame_mem (Pmode
,
15524 gen_rtx_PLUS (Pmode
, stack_top
,
15525 GEN_INT (5 * GET_MODE_SIZE (Pmode
))));
15526 emit_move_insn (mem
, gen_rtx_REG (Pmode
, 2));
15527 emit_label (no_toc_save_needed
);
15530 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
15531 and the change to the stack pointer. */
15534 rs6000_emit_stack_tie (void)
15536 rtx mem
= gen_frame_mem (BLKmode
,
15537 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
15539 emit_insn (gen_stack_tie (mem
));
15542 /* Emit the correct code for allocating stack space, as insns.
15543 If COPY_R12, make sure a copy of the old frame is left in r12.
15544 If COPY_R11, make sure a copy of the old frame is left in r11,
15545 in preference to r12 if COPY_R12.
15546 The generated code may use hard register 0 as a temporary. */
15549 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, int copy_r12
, int copy_r11
)
15552 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
15553 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
15554 rtx todec
= gen_int_mode (-size
, Pmode
);
15557 if (INTVAL (todec
) != -size
)
15559 warning (0, "stack frame too large");
15560 emit_insn (gen_trap ());
15564 if (crtl
->limit_stack
)
15566 if (REG_P (stack_limit_rtx
)
15567 && REGNO (stack_limit_rtx
) > 1
15568 && REGNO (stack_limit_rtx
) <= 31)
15570 emit_insn (TARGET_32BIT
15571 ? gen_addsi3 (tmp_reg
,
15574 : gen_adddi3 (tmp_reg
,
15578 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
15581 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
15583 && DEFAULT_ABI
== ABI_V4
)
15585 rtx toload
= gen_rtx_CONST (VOIDmode
,
15586 gen_rtx_PLUS (Pmode
,
15590 emit_insn (gen_elf_high (tmp_reg
, toload
));
15591 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
15592 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
15596 warning (0, "stack limit expression is not supported");
15599 if (copy_r12
|| copy_r11
)
15600 emit_move_insn (copy_r11
15601 ? gen_rtx_REG (Pmode
, 11)
15602 : gen_rtx_REG (Pmode
, 12),
15607 /* Need a note here so that try_split doesn't get confused. */
15608 if (get_last_insn () == NULL_RTX
)
15609 emit_note (NOTE_INSN_DELETED
);
15610 insn
= emit_move_insn (tmp_reg
, todec
);
15611 try_split (PATTERN (insn
), insn
, 0);
15615 insn
= emit_insn (TARGET_32BIT
15616 ? gen_movsi_update_stack (stack_reg
, stack_reg
,
15618 : gen_movdi_di_update_stack (stack_reg
, stack_reg
,
15619 todec
, stack_reg
));
15620 /* Since we didn't use gen_frame_mem to generate the MEM, grab
15621 it now and set the alias set/attributes. The above gen_*_update
15622 calls will generate a PARALLEL with the MEM set being the first
15624 par
= PATTERN (insn
);
15625 gcc_assert (GET_CODE (par
) == PARALLEL
);
15626 set
= XVECEXP (par
, 0, 0);
15627 gcc_assert (GET_CODE (set
) == SET
);
15628 mem
= SET_DEST (set
);
15629 gcc_assert (MEM_P (mem
));
15630 MEM_NOTRAP_P (mem
) = 1;
15631 set_mem_alias_set (mem
, get_frame_alias_set ());
15633 RTX_FRAME_RELATED_P (insn
) = 1;
15634 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
15635 gen_rtx_SET (VOIDmode
, stack_reg
,
15636 gen_rtx_PLUS (Pmode
, stack_reg
,
15637 GEN_INT (-size
))));
15640 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
15641 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
15642 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
15643 deduce these equivalences by itself so it wasn't necessary to hold
15644 its hand so much. */
15647 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
15648 rtx reg2
, rtx rreg
)
15652 /* copy_rtx will not make unique copies of registers, so we need to
15653 ensure we don't have unwanted sharing here. */
15655 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
15658 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
15660 real
= copy_rtx (PATTERN (insn
));
15662 if (reg2
!= NULL_RTX
)
15663 real
= replace_rtx (real
, reg2
, rreg
);
15665 real
= replace_rtx (real
, reg
,
15666 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
15667 STACK_POINTER_REGNUM
),
15670 /* We expect that 'real' is either a SET or a PARALLEL containing
15671 SETs (and possibly other stuff). In a PARALLEL, all the SETs
15672 are important so they all have to be marked RTX_FRAME_RELATED_P. */
15674 if (GET_CODE (real
) == SET
)
15678 temp
= simplify_rtx (SET_SRC (set
));
15680 SET_SRC (set
) = temp
;
15681 temp
= simplify_rtx (SET_DEST (set
));
15683 SET_DEST (set
) = temp
;
15684 if (GET_CODE (SET_DEST (set
)) == MEM
)
15686 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
15688 XEXP (SET_DEST (set
), 0) = temp
;
15695 gcc_assert (GET_CODE (real
) == PARALLEL
);
15696 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
15697 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
15699 rtx set
= XVECEXP (real
, 0, i
);
15701 temp
= simplify_rtx (SET_SRC (set
));
15703 SET_SRC (set
) = temp
;
15704 temp
= simplify_rtx (SET_DEST (set
));
15706 SET_DEST (set
) = temp
;
15707 if (GET_CODE (SET_DEST (set
)) == MEM
)
15709 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
15711 XEXP (SET_DEST (set
), 0) = temp
;
15713 RTX_FRAME_RELATED_P (set
) = 1;
15717 RTX_FRAME_RELATED_P (insn
) = 1;
15718 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, real
);
15721 /* Returns an insn that has a vrsave set operation with the
15722 appropriate CLOBBERs. */
15725 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
15728 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
15729 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
15732 = gen_rtx_SET (VOIDmode
,
15734 gen_rtx_UNSPEC_VOLATILE (SImode
,
15735 gen_rtvec (2, reg
, vrsave
),
15736 UNSPECV_SET_VRSAVE
));
15740 /* We need to clobber the registers in the mask so the scheduler
15741 does not move sets to VRSAVE before sets of AltiVec registers.
15743 However, if the function receives nonlocal gotos, reload will set
15744 all call saved registers live. We will end up with:
15746 (set (reg 999) (mem))
15747 (parallel [ (set (reg vrsave) (unspec blah))
15748 (clobber (reg 999))])
15750 The clobber will cause the store into reg 999 to be dead, and
15751 flow will attempt to delete an epilogue insn. In this case, we
15752 need an unspec use/set of the register. */
15754 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
15755 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
15757 if (!epiloguep
|| call_used_regs
[i
])
15758 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
15759 gen_rtx_REG (V4SImode
, i
));
15762 rtx reg
= gen_rtx_REG (V4SImode
, i
);
15765 = gen_rtx_SET (VOIDmode
,
15767 gen_rtx_UNSPEC (V4SImode
,
15768 gen_rtvec (1, reg
), 27));
15772 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
15774 for (i
= 0; i
< nclobs
; ++i
)
15775 XVECEXP (insn
, 0, i
) = clobs
[i
];
15780 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
15781 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
15784 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
15785 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
15787 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
15788 rtx replacea
, replaceb
;
15790 int_rtx
= GEN_INT (offset
);
15792 /* Some cases that need register indexed addressing. */
15793 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
15794 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
15796 && SPE_VECTOR_MODE (mode
)
15797 && !SPE_CONST_OFFSET_OK (offset
)))
15799 /* Whomever calls us must make sure r11 is available in the
15800 flow path of instructions in the prologue. */
15801 offset_rtx
= gen_rtx_REG (Pmode
, 11);
15802 emit_move_insn (offset_rtx
, int_rtx
);
15804 replacea
= offset_rtx
;
15805 replaceb
= int_rtx
;
15809 offset_rtx
= int_rtx
;
15810 replacea
= NULL_RTX
;
15811 replaceb
= NULL_RTX
;
15814 reg
= gen_rtx_REG (mode
, regno
);
15815 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
15816 mem
= gen_frame_mem (mode
, addr
);
15818 insn
= emit_move_insn (mem
, reg
);
15820 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
15823 /* Emit an offset memory reference suitable for a frame store, while
15824 converting to a valid addressing mode. */
15827 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
15829 rtx int_rtx
, offset_rtx
;
15831 int_rtx
= GEN_INT (offset
);
15833 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
15834 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
15836 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
15837 emit_move_insn (offset_rtx
, int_rtx
);
15840 offset_rtx
= int_rtx
;
15842 return gen_frame_mem (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
15845 /* Look for user-defined global regs. We should not save and restore these,
15846 and cannot use stmw/lmw if there are any in its range. */
15849 no_global_regs_above (int first
, bool gpr
)
15852 for (i
= first
; i
< gpr
? 32 : 64 ; i
++)
15853 if (global_regs
[i
])
15858 #ifndef TARGET_FIX_AND_CONTINUE
15859 #define TARGET_FIX_AND_CONTINUE 0
15862 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
15863 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
15864 #define LAST_SAVRES_REGISTER 31
15865 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
15867 static GTY(()) rtx savres_routine_syms
[N_SAVRES_REGISTERS
][8];
15869 /* Return the symbol for an out-of-line register save/restore routine.
15870 We are saving/restoring GPRs if GPR is true. */
15873 rs6000_savres_routine_sym (rs6000_stack_t
*info
, bool savep
, bool gpr
, bool exitp
)
15875 int regno
= gpr
? info
->first_gp_reg_save
: (info
->first_fp_reg_save
- 32);
15877 int select
= ((savep
? 1 : 0) << 2
15879 /* On the SPE, we never have any FPRs, but we do have
15880 32/64-bit versions of the routines. */
15881 ? (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
? 1 : 0)
15885 /* Don't generate bogus routine names. */
15886 gcc_assert (FIRST_SAVRES_REGISTER
<= regno
&& regno
<= LAST_SAVRES_REGISTER
);
15888 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
];
15893 const char *action
;
15894 const char *regkind
;
15895 const char *exit_suffix
;
15897 action
= savep
? "save" : "rest";
15899 /* SPE has slightly different names for its routines depending on
15900 whether we are saving 32-bit or 64-bit registers. */
15901 if (TARGET_SPE_ABI
)
15903 /* No floating point saves on the SPE. */
15906 regkind
= info
->spe_64bit_regs_used
? "64gpr" : "32gpr";
15909 regkind
= gpr
? "gpr" : "fpr";
15911 exit_suffix
= exitp
? "_x" : "";
15913 sprintf (name
, "_%s%s_%d%s", action
, regkind
, regno
, exit_suffix
);
15915 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
]
15916 = gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (name
));
15922 /* Emit a sequence of insns, including a stack tie if needed, for
15923 resetting the stack pointer. If SAVRES is true, then don't reset the
15924 stack pointer, but move the base of the frame into r11 for use by
15925 out-of-line register restore routines. */
15928 rs6000_emit_stack_reset (rs6000_stack_t
*info
,
15929 rtx sp_reg_rtx
, rtx frame_reg_rtx
,
15930 int sp_offset
, bool savres
)
15932 /* This blockage is needed so that sched doesn't decide to move
15933 the sp change before the register restores. */
15934 if (frame_reg_rtx
!= sp_reg_rtx
15936 && info
->spe_64bit_regs_used
!= 0
15937 && info
->first_gp_reg_save
!= 32))
15938 rs6000_emit_stack_tie ();
15940 if (frame_reg_rtx
!= sp_reg_rtx
)
15942 if (sp_offset
!= 0)
15943 emit_insn (gen_addsi3 (sp_reg_rtx
, frame_reg_rtx
,
15944 GEN_INT (sp_offset
)));
15946 emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
15948 else if (sp_offset
!= 0)
15950 /* If we are restoring registers out-of-line, we will be using the
15951 "exit" variants of the restore routines, which will reset the
15952 stack for us. But we do need to point r11 into the right place
15953 for those routines. */
15954 rtx dest_reg
= (savres
15955 ? gen_rtx_REG (Pmode
, 11)
15958 emit_insn (TARGET_32BIT
15959 ? gen_addsi3 (dest_reg
, sp_reg_rtx
,
15960 GEN_INT (sp_offset
))
15961 : gen_adddi3 (dest_reg
, sp_reg_rtx
,
15962 GEN_INT (sp_offset
)));
15966 /* Construct a parallel rtx describing the effect of a call to an
15967 out-of-line register save/restore routine. */
15970 rs6000_make_savres_rtx (rs6000_stack_t
*info
,
15971 rtx frame_reg_rtx
, int save_area_offset
,
15972 enum machine_mode reg_mode
,
15973 bool savep
, bool gpr
, bool exitp
)
15976 int offset
, start_reg
, end_reg
, n_regs
;
15977 int reg_size
= GET_MODE_SIZE (reg_mode
);
15983 ? info
->first_gp_reg_save
15984 : info
->first_fp_reg_save
);
15985 end_reg
= gpr
? 32 : 64;
15986 n_regs
= end_reg
- start_reg
;
15987 p
= rtvec_alloc ((exitp
? 4 : 3) + n_regs
);
15989 /* If we're saving registers, then we should never say we're exiting. */
15990 gcc_assert ((savep
&& !exitp
) || !savep
);
15993 RTVEC_ELT (p
, offset
++) = gen_rtx_RETURN (VOIDmode
);
15995 RTVEC_ELT (p
, offset
++)
15996 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 65));
15998 sym
= rs6000_savres_routine_sym (info
, savep
, gpr
, exitp
);
15999 RTVEC_ELT (p
, offset
++) = gen_rtx_USE (VOIDmode
, sym
);
16000 RTVEC_ELT (p
, offset
++) = gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 11));
16002 for (i
= 0; i
< end_reg
- start_reg
; i
++)
16004 rtx addr
, reg
, mem
;
16005 reg
= gen_rtx_REG (reg_mode
, start_reg
+ i
);
16006 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16007 GEN_INT (save_area_offset
+ reg_size
*i
));
16008 mem
= gen_frame_mem (reg_mode
, addr
);
16010 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
,
16012 savep
? reg
: mem
);
16015 return gen_rtx_PARALLEL (VOIDmode
, p
);
16018 /* Determine whether the gp REG is really used. */
16021 rs6000_reg_live_or_pic_offset_p (int reg
)
16023 return ((df_regs_ever_live_p (reg
)
16024 && (!call_used_regs
[reg
]
16025 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
16026 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
16027 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
16028 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
16029 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))));
16033 SAVRES_MULTIPLE
= 0x1,
16034 SAVRES_INLINE_FPRS
= 0x2,
16035 SAVRES_INLINE_GPRS
= 0x4
16038 /* Determine the strategy for savings/restoring registers. */
16041 rs6000_savres_strategy (rs6000_stack_t
*info
, bool savep
,
16042 int using_static_chain_p
, int sibcall
)
16044 bool using_multiple_p
;
16046 bool savres_fprs_inline
;
16047 bool savres_gprs_inline
;
16048 bool noclobber_global_gprs
16049 = no_global_regs_above (info
->first_gp_reg_save
, /*gpr=*/true);
16051 using_multiple_p
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
16052 && (!TARGET_SPE_ABI
16053 || info
->spe_64bit_regs_used
== 0)
16054 && info
->first_gp_reg_save
< 31
16055 && noclobber_global_gprs
);
16056 /* Don't bother to try to save things out-of-line if r11 is occupied
16057 by the static chain. It would require too much fiddling and the
16058 static chain is rarely used anyway. */
16059 common
= (using_static_chain_p
16061 || crtl
->calls_eh_return
16062 || !info
->lr_save_p
16063 || cfun
->machine
->ra_need_lr
16064 || info
->total_size
> 32767);
16065 savres_fprs_inline
= (common
16066 || info
->first_fp_reg_save
== 64
16067 || !no_global_regs_above (info
->first_fp_reg_save
,
16069 || FP_SAVE_INLINE (info
->first_fp_reg_save
));
16070 savres_gprs_inline
= (common
16071 /* Saving CR interferes with the exit routines
16072 used on the SPE, so just punt here. */
16075 && info
->spe_64bit_regs_used
!= 0
16076 && info
->cr_save_p
!= 0)
16077 || info
->first_gp_reg_save
== 32
16078 || !noclobber_global_gprs
16079 || GP_SAVE_INLINE (info
->first_gp_reg_save
));
16082 /* If we are going to use store multiple, then don't even bother
16083 with the out-of-line routines, since the store-multiple instruction
16084 will always be smaller. */
16085 savres_gprs_inline
= savres_gprs_inline
|| using_multiple_p
;
16088 /* The situation is more complicated with load multiple. We'd
16089 prefer to use the out-of-line routines for restores, since the
16090 "exit" out-of-line routines can handle the restore of LR and
16091 the frame teardown. But we can only use the out-of-line
16092 routines if we know that we've used store multiple or
16093 out-of-line routines in the prologue, i.e. if we've saved all
16094 the registers from first_gp_reg_save. Otherwise, we risk
16095 loading garbage from the stack. Furthermore, we can only use
16096 the "exit" out-of-line gpr restore if we haven't saved any
16098 bool saved_all
= !savres_gprs_inline
|| using_multiple_p
;
16100 if (saved_all
&& info
->first_fp_reg_save
!= 64)
16101 /* We can't use the exit routine; use load multiple if it's
16103 savres_gprs_inline
= savres_gprs_inline
|| using_multiple_p
;
16106 return (using_multiple_p
16107 | (savres_fprs_inline
<< 1)
16108 | (savres_gprs_inline
<< 2));
16111 /* Emit function prologue as insns. */
16114 rs6000_emit_prologue (void)
16116 rs6000_stack_t
*info
= rs6000_stack_info ();
16117 enum machine_mode reg_mode
= Pmode
;
16118 int reg_size
= TARGET_32BIT
? 4 : 8;
16119 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
16120 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
16121 rtx frame_reg_rtx
= sp_reg_rtx
;
16122 rtx cr_save_rtx
= NULL_RTX
;
16125 int saving_FPRs_inline
;
16126 int saving_GPRs_inline
;
16127 int using_store_multiple
;
16128 int using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
16129 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
16130 && !call_used_regs
[STATIC_CHAIN_REGNUM
]);
16131 HOST_WIDE_INT sp_offset
= 0;
16133 if (TARGET_FIX_AND_CONTINUE
)
16135 /* gdb on darwin arranges to forward a function from the old
16136 address by modifying the first 5 instructions of the function
16137 to branch to the overriding function. This is necessary to
16138 permit function pointers that point to the old function to
16139 actually forward to the new function. */
16140 emit_insn (gen_nop ());
16141 emit_insn (gen_nop ());
16142 emit_insn (gen_nop ());
16143 emit_insn (gen_nop ());
16144 emit_insn (gen_nop ());
16147 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
16149 reg_mode
= V2SImode
;
16153 strategy
= rs6000_savres_strategy (info
, /*savep=*/true,
16154 /*static_chain_p=*/using_static_chain_p
,
16156 using_store_multiple
= strategy
& SAVRES_MULTIPLE
;
16157 saving_FPRs_inline
= strategy
& SAVRES_INLINE_FPRS
;
16158 saving_GPRs_inline
= strategy
& SAVRES_INLINE_GPRS
;
16160 /* For V.4, update stack before we do any saving and set back pointer. */
16161 if (! WORLD_SAVE_P (info
)
16163 && (DEFAULT_ABI
== ABI_V4
16164 || crtl
->calls_eh_return
))
16166 bool need_r11
= (TARGET_SPE
16167 ? (!saving_GPRs_inline
16168 && info
->spe_64bit_regs_used
== 0)
16169 : (!saving_FPRs_inline
|| !saving_GPRs_inline
));
16170 if (info
->total_size
< 32767)
16171 sp_offset
= info
->total_size
;
16173 frame_reg_rtx
= (need_r11
16174 ? gen_rtx_REG (Pmode
, 11)
16176 rs6000_emit_allocate_stack (info
->total_size
,
16177 (frame_reg_rtx
!= sp_reg_rtx
16178 && (info
->cr_save_p
16180 || info
->first_fp_reg_save
< 64
16181 || info
->first_gp_reg_save
< 32
16184 if (frame_reg_rtx
!= sp_reg_rtx
)
16185 rs6000_emit_stack_tie ();
16188 /* Handle world saves specially here. */
16189 if (WORLD_SAVE_P (info
))
16196 /* save_world expects lr in r0. */
16197 reg0
= gen_rtx_REG (Pmode
, 0);
16198 if (info
->lr_save_p
)
16200 insn
= emit_move_insn (reg0
,
16201 gen_rtx_REG (Pmode
, LR_REGNO
));
16202 RTX_FRAME_RELATED_P (insn
) = 1;
16205 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
16206 assumptions about the offsets of various bits of the stack
16208 gcc_assert (info
->gp_save_offset
== -220
16209 && info
->fp_save_offset
== -144
16210 && info
->lr_save_offset
== 8
16211 && info
->cr_save_offset
== 4
16214 && (!crtl
->calls_eh_return
16215 || info
->ehrd_offset
== -432)
16216 && info
->vrsave_save_offset
== -224
16217 && info
->altivec_save_offset
== -416);
16219 treg
= gen_rtx_REG (SImode
, 11);
16220 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
16222 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
16223 in R11. It also clobbers R12, so beware! */
16225 /* Preserve CR2 for save_world prologues */
16227 sz
+= 32 - info
->first_gp_reg_save
;
16228 sz
+= 64 - info
->first_fp_reg_save
;
16229 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
16230 p
= rtvec_alloc (sz
);
16232 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
16233 gen_rtx_REG (SImode
,
16235 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
16236 gen_rtx_SYMBOL_REF (Pmode
,
16238 /* We do floats first so that the instruction pattern matches
16240 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
16242 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
16243 ? DFmode
: SFmode
),
16244 info
->first_fp_reg_save
+ i
);
16245 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16246 GEN_INT (info
->fp_save_offset
16247 + sp_offset
+ 8 * i
));
16248 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
16249 ? DFmode
: SFmode
), addr
);
16251 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
16253 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
16255 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
16256 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16257 GEN_INT (info
->altivec_save_offset
16258 + sp_offset
+ 16 * i
));
16259 rtx mem
= gen_frame_mem (V4SImode
, addr
);
16261 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
16263 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16265 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16266 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16267 GEN_INT (info
->gp_save_offset
16268 + sp_offset
+ reg_size
* i
));
16269 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16271 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
16275 /* CR register traditionally saved as CR2. */
16276 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
16277 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16278 GEN_INT (info
->cr_save_offset
16280 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16282 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
16284 /* Explain about use of R0. */
16285 if (info
->lr_save_p
)
16287 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16288 GEN_INT (info
->lr_save_offset
16290 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16292 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg0
);
16294 /* Explain what happens to the stack pointer. */
16296 rtx newval
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
, treg
);
16297 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, sp_reg_rtx
, newval
);
16300 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16301 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16302 treg
, GEN_INT (-info
->total_size
));
16303 sp_offset
= info
->total_size
;
16306 /* If we use the link register, get it into r0. */
16307 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
16309 rtx addr
, reg
, mem
;
16311 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
16312 gen_rtx_REG (Pmode
, LR_REGNO
));
16313 RTX_FRAME_RELATED_P (insn
) = 1;
16315 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16316 GEN_INT (info
->lr_save_offset
+ sp_offset
));
16317 reg
= gen_rtx_REG (Pmode
, 0);
16318 mem
= gen_rtx_MEM (Pmode
, addr
);
16319 /* This should not be of rs6000_sr_alias_set, because of
16320 __builtin_return_address. */
16322 insn
= emit_move_insn (mem
, reg
);
16323 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16324 NULL_RTX
, NULL_RTX
);
16327 /* If we need to save CR, put it into r12. */
16328 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
16332 cr_save_rtx
= gen_rtx_REG (SImode
, 12);
16333 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
16334 RTX_FRAME_RELATED_P (insn
) = 1;
16335 /* Now, there's no way that dwarf2out_frame_debug_expr is going
16336 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
16337 But that's OK. All we have to do is specify that _one_ condition
16338 code register is saved in this stack slot. The thrower's epilogue
16339 will then restore all the call-saved registers.
16340 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
16341 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
16342 gen_rtx_REG (SImode
, CR2_REGNO
));
16343 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
16346 /* Do any required saving of fpr's. If only one or two to save, do
16347 it ourselves. Otherwise, call function. */
16348 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
16351 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
16352 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
16353 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
16354 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
,
16355 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
16357 info
->first_fp_reg_save
+ i
,
16358 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
16361 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
16365 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
16366 info
->fp_save_offset
+ sp_offset
,
16368 /*savep=*/true, /*gpr=*/false,
16370 insn
= emit_insn (par
);
16371 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16372 NULL_RTX
, NULL_RTX
);
16375 /* Save GPRs. This is done as a PARALLEL if we are using
16376 the store-multiple instructions. */
16377 if (!WORLD_SAVE_P (info
)
16379 && info
->spe_64bit_regs_used
!= 0
16380 && info
->first_gp_reg_save
!= 32)
16383 rtx spe_save_area_ptr
;
16385 /* Determine whether we can address all of the registers that need
16386 to be saved with an offset from the stack pointer that fits in
16387 the small const field for SPE memory instructions. */
16388 int spe_regs_addressable_via_sp
16389 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
16390 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
16391 && saving_GPRs_inline
);
16394 if (spe_regs_addressable_via_sp
)
16396 spe_save_area_ptr
= frame_reg_rtx
;
16397 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
16401 /* Make r11 point to the start of the SPE save area. We need
16402 to be careful here if r11 is holding the static chain. If
16403 it is, then temporarily save it in r0. We would use r0 as
16404 our base register here, but using r0 as a base register in
16405 loads and stores means something different from what we
16407 int ool_adjust
= (saving_GPRs_inline
16409 : (info
->first_gp_reg_save
16410 - (FIRST_SAVRES_REGISTER
+1))*8);
16411 HOST_WIDE_INT offset
= (info
->spe_gp_save_offset
16412 + sp_offset
- ool_adjust
);
16414 if (using_static_chain_p
)
16416 rtx r0
= gen_rtx_REG (Pmode
, 0);
16417 gcc_assert (info
->first_gp_reg_save
> 11);
16419 emit_move_insn (r0
, gen_rtx_REG (Pmode
, 11));
16422 spe_save_area_ptr
= gen_rtx_REG (Pmode
, 11);
16423 insn
= emit_insn (gen_addsi3 (spe_save_area_ptr
,
16425 GEN_INT (offset
)));
16426 /* We need to make sure the move to r11 gets noted for
16427 properly outputting unwind information. */
16428 if (!saving_GPRs_inline
)
16429 rs6000_frame_related (insn
, frame_reg_rtx
, offset
,
16430 NULL_RTX
, NULL_RTX
);
16434 if (saving_GPRs_inline
)
16436 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16437 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
16439 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16440 rtx offset
, addr
, mem
;
16442 /* We're doing all this to ensure that the offset fits into
16443 the immediate offset of 'evstdd'. */
16444 gcc_assert (SPE_CONST_OFFSET_OK (reg_size
* i
+ spe_offset
));
16446 offset
= GEN_INT (reg_size
* i
+ spe_offset
);
16447 addr
= gen_rtx_PLUS (Pmode
, spe_save_area_ptr
, offset
);
16448 mem
= gen_rtx_MEM (V2SImode
, addr
);
16450 insn
= emit_move_insn (mem
, reg
);
16452 rs6000_frame_related (insn
, spe_save_area_ptr
,
16453 info
->spe_gp_save_offset
16454 + sp_offset
+ reg_size
* i
,
16455 offset
, const0_rtx
);
16462 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
16464 /*savep=*/true, /*gpr=*/true,
16466 insn
= emit_insn (par
);
16467 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16468 NULL_RTX
, NULL_RTX
);
16472 /* Move the static chain pointer back. */
16473 if (using_static_chain_p
&& !spe_regs_addressable_via_sp
)
16474 emit_move_insn (gen_rtx_REG (Pmode
, 11), gen_rtx_REG (Pmode
, 0));
16476 else if (!WORLD_SAVE_P (info
) && !saving_GPRs_inline
)
16480 /* Need to adjust r11 if we saved any FPRs. */
16481 if (info
->first_fp_reg_save
!= 64)
16483 rtx r11
= gen_rtx_REG (reg_mode
, 11);
16484 rtx offset
= GEN_INT (info
->total_size
16485 + (-8 * (64-info
->first_fp_reg_save
)));
16486 rtx ptr_reg
= (sp_reg_rtx
== frame_reg_rtx
16487 ? sp_reg_rtx
: r11
);
16489 emit_insn (TARGET_32BIT
16490 ? gen_addsi3 (r11
, ptr_reg
, offset
)
16491 : gen_adddi3 (r11
, ptr_reg
, offset
));
16494 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
16495 info
->gp_save_offset
+ sp_offset
,
16497 /*savep=*/true, /*gpr=*/true,
16499 insn
= emit_insn (par
);
16500 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16501 NULL_RTX
, NULL_RTX
);
16503 else if (!WORLD_SAVE_P (info
) && using_store_multiple
)
16507 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
16508 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16510 rtx addr
, reg
, mem
;
16511 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16512 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16513 GEN_INT (info
->gp_save_offset
16516 mem
= gen_frame_mem (reg_mode
, addr
);
16518 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
16520 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16521 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16522 NULL_RTX
, NULL_RTX
);
16524 else if (!WORLD_SAVE_P (info
))
16527 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16528 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
16530 rtx addr
, reg
, mem
;
16531 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16533 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16534 GEN_INT (info
->gp_save_offset
16537 mem
= gen_frame_mem (reg_mode
, addr
);
16539 insn
= emit_move_insn (mem
, reg
);
16540 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16541 NULL_RTX
, NULL_RTX
);
16545 /* ??? There's no need to emit actual instructions here, but it's the
16546 easiest way to get the frame unwind information emitted. */
16547 if (crtl
->calls_eh_return
)
16549 unsigned int i
, regno
;
16551 /* In AIX ABI we need to pretend we save r2 here. */
16554 rtx addr
, reg
, mem
;
16556 reg
= gen_rtx_REG (reg_mode
, 2);
16557 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16558 GEN_INT (sp_offset
+ 5 * reg_size
));
16559 mem
= gen_frame_mem (reg_mode
, addr
);
16561 insn
= emit_move_insn (mem
, reg
);
16562 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16563 NULL_RTX
, NULL_RTX
);
16564 PATTERN (insn
) = gen_blockage ();
16569 regno
= EH_RETURN_DATA_REGNO (i
);
16570 if (regno
== INVALID_REGNUM
)
16573 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
16574 info
->ehrd_offset
+ sp_offset
16575 + reg_size
* (int) i
,
16580 /* Save CR if we use any that must be preserved. */
16581 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
16583 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16584 GEN_INT (info
->cr_save_offset
+ sp_offset
));
16585 rtx mem
= gen_frame_mem (SImode
, addr
);
16586 /* See the large comment above about why CR2_REGNO is used. */
16587 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
16589 /* If r12 was used to hold the original sp, copy cr into r0 now
16591 if (REGNO (frame_reg_rtx
) == 12)
16595 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
16596 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
16597 RTX_FRAME_RELATED_P (insn
) = 1;
16598 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
16599 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, set
);
16601 insn
= emit_move_insn (mem
, cr_save_rtx
);
16603 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16604 NULL_RTX
, NULL_RTX
);
16607 /* Update stack and set back pointer unless this is V.4,
16608 for which it was done previously. */
16609 if (!WORLD_SAVE_P (info
) && info
->push_p
16610 && !(DEFAULT_ABI
== ABI_V4
|| crtl
->calls_eh_return
))
16612 if (info
->total_size
< 32767)
16613 sp_offset
= info
->total_size
;
16615 frame_reg_rtx
= frame_ptr_rtx
;
16616 rs6000_emit_allocate_stack (info
->total_size
,
16617 (frame_reg_rtx
!= sp_reg_rtx
16618 && ((info
->altivec_size
!= 0)
16619 || (info
->vrsave_mask
!= 0)
16622 if (frame_reg_rtx
!= sp_reg_rtx
)
16623 rs6000_emit_stack_tie ();
16626 /* Set frame pointer, if needed. */
16627 if (frame_pointer_needed
)
16629 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
16631 RTX_FRAME_RELATED_P (insn
) = 1;
16634 /* Save AltiVec registers if needed. Save here because the red zone does
16635 not include AltiVec registers. */
16636 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
16640 /* There should be a non inline version of this, for when we
16641 are saving lots of vector registers. */
16642 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
16643 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
16645 rtx areg
, savereg
, mem
;
16648 offset
= info
->altivec_save_offset
+ sp_offset
16649 + 16 * (i
- info
->first_altivec_reg_save
);
16651 savereg
= gen_rtx_REG (V4SImode
, i
);
16653 areg
= gen_rtx_REG (Pmode
, 0);
16654 emit_move_insn (areg
, GEN_INT (offset
));
16656 /* AltiVec addressing mode is [reg+reg]. */
16657 mem
= gen_frame_mem (V4SImode
,
16658 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
16660 insn
= emit_move_insn (mem
, savereg
);
16662 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16663 areg
, GEN_INT (offset
));
16667 /* VRSAVE is a bit vector representing which AltiVec registers
16668 are used. The OS uses this to determine which vector
16669 registers to save on a context switch. We need to save
16670 VRSAVE on the stack frame, add whatever AltiVec registers we
16671 used in this function, and do the corresponding magic in the
16674 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
16675 && info
->vrsave_mask
!= 0)
16677 rtx reg
, mem
, vrsave
;
16680 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
16681 as frame_reg_rtx and r11 as the static chain pointer for
16682 nested functions. */
16683 reg
= gen_rtx_REG (SImode
, 0);
16684 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
16686 emit_insn (gen_get_vrsave_internal (reg
));
16688 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
16690 if (!WORLD_SAVE_P (info
))
16693 offset
= info
->vrsave_save_offset
+ sp_offset
;
16694 mem
= gen_frame_mem (SImode
,
16695 gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16696 GEN_INT (offset
)));
16697 insn
= emit_move_insn (mem
, reg
);
16700 /* Include the registers in the mask. */
16701 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
16703 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
16706 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
16707 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
16708 || (DEFAULT_ABI
== ABI_V4
16709 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
16710 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
)))
16712 /* If emit_load_toc_table will use the link register, we need to save
16713 it. We use R12 for this purpose because emit_load_toc_table
16714 can use register 0. This allows us to use a plain 'blr' to return
16715 from the procedure more often. */
16716 int save_LR_around_toc_setup
= (TARGET_ELF
16717 && DEFAULT_ABI
!= ABI_AIX
16719 && ! info
->lr_save_p
16720 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
16721 if (save_LR_around_toc_setup
)
16723 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
16725 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
16726 RTX_FRAME_RELATED_P (insn
) = 1;
16728 rs6000_emit_load_toc_table (TRUE
);
16730 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
16731 RTX_FRAME_RELATED_P (insn
) = 1;
16734 rs6000_emit_load_toc_table (TRUE
);
16738 if (DEFAULT_ABI
== ABI_DARWIN
16739 && flag_pic
&& crtl
->uses_pic_offset_table
)
16741 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
16742 rtx src
= gen_rtx_SYMBOL_REF (Pmode
, MACHOPIC_FUNCTION_BASE_NAME
);
16744 /* Save and restore LR locally around this call (in R0). */
16745 if (!info
->lr_save_p
)
16746 emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
);
16748 emit_insn (gen_load_macho_picbase (src
));
16750 emit_move_insn (gen_rtx_REG (Pmode
,
16751 RS6000_PIC_OFFSET_TABLE_REGNUM
),
16754 if (!info
->lr_save_p
)
16755 emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0));
16760 /* Write function prologue. */
16763 rs6000_output_function_prologue (FILE *file
,
16764 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
16766 rs6000_stack_t
*info
= rs6000_stack_info ();
16768 if (TARGET_DEBUG_STACK
)
16769 debug_stack_info (info
);
16771 /* Write .extern for any function we will call to save and restore
16773 if (info
->first_fp_reg_save
< 64
16774 && !FP_SAVE_INLINE (info
->first_fp_reg_save
))
16775 fprintf (file
, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
16776 SAVE_FP_PREFIX
, info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
,
16777 RESTORE_FP_PREFIX
, info
->first_fp_reg_save
- 32, RESTORE_FP_SUFFIX
);
16779 /* Write .extern for AIX common mode routines, if needed. */
16780 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
16782 fputs ("\t.extern __mulh\n", file
);
16783 fputs ("\t.extern __mull\n", file
);
16784 fputs ("\t.extern __divss\n", file
);
16785 fputs ("\t.extern __divus\n", file
);
16786 fputs ("\t.extern __quoss\n", file
);
16787 fputs ("\t.extern __quous\n", file
);
16788 common_mode_defined
= 1;
16791 if (! HAVE_prologue
)
16795 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
16796 the "toplevel" insn chain. */
16797 emit_note (NOTE_INSN_DELETED
);
16798 rs6000_emit_prologue ();
16799 emit_note (NOTE_INSN_DELETED
);
16801 /* Expand INSN_ADDRESSES so final() doesn't crash. */
16805 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
16807 INSN_ADDRESSES_NEW (insn
, addr
);
16812 if (TARGET_DEBUG_STACK
)
16813 debug_rtx_list (get_insns (), 100);
16814 final (get_insns (), file
, FALSE
);
16818 rs6000_pic_labelno
++;
16821 /* Non-zero if vmx regs are restored before the frame pop, zero if
16822 we restore after the pop when possible. */
16823 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
16825 /* Reload CR from REG. */
16828 rs6000_restore_saved_cr (rtx reg
, int using_mfcr_multiple
)
16833 if (using_mfcr_multiple
)
16835 for (i
= 0; i
< 8; i
++)
16836 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
16838 gcc_assert (count
);
16841 if (using_mfcr_multiple
&& count
> 1)
16846 p
= rtvec_alloc (count
);
16849 for (i
= 0; i
< 8; i
++)
16850 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
16852 rtvec r
= rtvec_alloc (2);
16853 RTVEC_ELT (r
, 0) = reg
;
16854 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
16855 RTVEC_ELT (p
, ndx
) =
16856 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
16857 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
16860 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16861 gcc_assert (ndx
== count
);
16864 for (i
= 0; i
< 8; i
++)
16865 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
16867 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
16873 /* Emit function epilogue as insns.
16875 At present, dwarf2out_frame_debug_expr doesn't understand
16876 register restores, so we don't bother setting RTX_FRAME_RELATED_P
16877 anywhere in the epilogue. Most of the insns below would in any case
16878 need special notes to explain where r11 is in relation to the stack. */
16881 rs6000_emit_epilogue (int sibcall
)
16883 rs6000_stack_t
*info
;
16884 int restoring_GPRs_inline
;
16885 int restoring_FPRs_inline
;
16886 int using_load_multiple
;
16887 int using_mtcr_multiple
;
16888 int use_backchain_to_restore_sp
;
16892 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
16893 rtx frame_reg_rtx
= sp_reg_rtx
;
16894 enum machine_mode reg_mode
= Pmode
;
16895 int reg_size
= TARGET_32BIT
? 4 : 8;
16898 info
= rs6000_stack_info ();
16900 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
16902 reg_mode
= V2SImode
;
16906 strategy
= rs6000_savres_strategy (info
, /*savep=*/false,
16907 /*static_chain_p=*/0, sibcall
);
16908 using_load_multiple
= strategy
& SAVRES_MULTIPLE
;
16909 restoring_FPRs_inline
= strategy
& SAVRES_INLINE_FPRS
;
16910 restoring_GPRs_inline
= strategy
& SAVRES_INLINE_GPRS
;
16911 using_mtcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
16912 || rs6000_cpu
== PROCESSOR_PPC603
16913 || rs6000_cpu
== PROCESSOR_PPC750
16915 /* Restore via the backchain when we have a large frame, since this
16916 is more efficient than an addis, addi pair. The second condition
16917 here will not trigger at the moment; We don't actually need a
16918 frame pointer for alloca, but the generic parts of the compiler
16919 give us one anyway. */
16920 use_backchain_to_restore_sp
= (info
->total_size
> 32767
16921 || info
->total_size
16922 + (info
->lr_save_p
? info
->lr_save_offset
: 0)
16924 || (cfun
->calls_alloca
16925 && !frame_pointer_needed
));
16926 restore_lr
= (info
->lr_save_p
16927 && restoring_GPRs_inline
16928 && restoring_FPRs_inline
);
16930 if (WORLD_SAVE_P (info
))
16934 const char *alloc_rname
;
16937 /* eh_rest_world_r10 will return to the location saved in the LR
16938 stack slot (which is not likely to be our caller.)
16939 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
16940 rest_world is similar, except any R10 parameter is ignored.
16941 The exception-handling stuff that was here in 2.95 is no
16942 longer necessary. */
16946 + 32 - info
->first_gp_reg_save
16947 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
16948 + 63 + 1 - info
->first_fp_reg_save
);
16950 strcpy (rname
, ((crtl
->calls_eh_return
) ?
16951 "*eh_rest_world_r10" : "*rest_world"));
16952 alloc_rname
= ggc_strdup (rname
);
16955 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
16956 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
16957 gen_rtx_REG (Pmode
,
16960 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
16961 /* The instruction pattern requires a clobber here;
16962 it is shared with the restVEC helper. */
16964 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
16967 /* CR register traditionally saved as CR2. */
16968 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
16969 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16970 GEN_INT (info
->cr_save_offset
));
16971 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16973 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16976 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16978 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16979 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16980 GEN_INT (info
->gp_save_offset
16982 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16984 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16986 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
16988 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
16989 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16990 GEN_INT (info
->altivec_save_offset
16992 rtx mem
= gen_frame_mem (V4SImode
, addr
);
16994 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16996 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
16998 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
16999 ? DFmode
: SFmode
),
17000 info
->first_fp_reg_save
+ i
);
17001 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17002 GEN_INT (info
->fp_save_offset
17004 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
17005 ? DFmode
: SFmode
), addr
);
17007 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
17010 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
17012 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
17014 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
17016 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
17018 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
17019 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
17024 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
17026 sp_offset
= info
->total_size
;
17028 /* Restore AltiVec registers if we must do so before adjusting the
17030 if (TARGET_ALTIVEC_ABI
17031 && info
->altivec_size
!= 0
17032 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
17033 || (DEFAULT_ABI
!= ABI_V4
17034 && info
->altivec_save_offset
< (TARGET_32BIT
? -220 : -288))))
17038 if (use_backchain_to_restore_sp
)
17040 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
17041 emit_move_insn (frame_reg_rtx
,
17042 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
17045 else if (frame_pointer_needed
)
17046 frame_reg_rtx
= hard_frame_pointer_rtx
;
17048 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
17049 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
17051 rtx addr
, areg
, mem
;
17053 areg
= gen_rtx_REG (Pmode
, 0);
17055 (areg
, GEN_INT (info
->altivec_save_offset
17057 + 16 * (i
- info
->first_altivec_reg_save
)));
17059 /* AltiVec addressing mode is [reg+reg]. */
17060 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
17061 mem
= gen_frame_mem (V4SImode
, addr
);
17063 emit_move_insn (gen_rtx_REG (V4SImode
, i
), mem
);
17067 /* Restore VRSAVE if we must do so before adjusting the stack. */
17069 && TARGET_ALTIVEC_VRSAVE
17070 && info
->vrsave_mask
!= 0
17071 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
17072 || (DEFAULT_ABI
!= ABI_V4
17073 && info
->vrsave_save_offset
< (TARGET_32BIT
? -220 : -288))))
17075 rtx addr
, mem
, reg
;
17077 if (frame_reg_rtx
== sp_reg_rtx
)
17079 if (use_backchain_to_restore_sp
)
17081 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
17082 emit_move_insn (frame_reg_rtx
,
17083 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
17086 else if (frame_pointer_needed
)
17087 frame_reg_rtx
= hard_frame_pointer_rtx
;
17090 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17091 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
17092 mem
= gen_frame_mem (SImode
, addr
);
17093 reg
= gen_rtx_REG (SImode
, 12);
17094 emit_move_insn (reg
, mem
);
17096 emit_insn (generate_set_vrsave (reg
, info
, 1));
17099 /* If we have a large stack frame, restore the old stack pointer
17100 using the backchain. */
17101 if (use_backchain_to_restore_sp
)
17103 if (frame_reg_rtx
== sp_reg_rtx
)
17105 /* Under V.4, don't reset the stack pointer until after we're done
17106 loading the saved registers. */
17107 if (DEFAULT_ABI
== ABI_V4
)
17108 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
17110 emit_move_insn (frame_reg_rtx
,
17111 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
17114 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
17115 && DEFAULT_ABI
== ABI_V4
)
17116 /* frame_reg_rtx has been set up by the altivec restore. */
17120 emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
17121 frame_reg_rtx
= sp_reg_rtx
;
17124 /* If we have a frame pointer, we can restore the old stack pointer
17126 else if (frame_pointer_needed
)
17128 frame_reg_rtx
= sp_reg_rtx
;
17129 if (DEFAULT_ABI
== ABI_V4
)
17130 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
17132 emit_insn (TARGET_32BIT
17133 ? gen_addsi3 (frame_reg_rtx
, hard_frame_pointer_rtx
,
17134 GEN_INT (info
->total_size
))
17135 : gen_adddi3 (frame_reg_rtx
, hard_frame_pointer_rtx
,
17136 GEN_INT (info
->total_size
)));
17139 else if (info
->push_p
17140 && DEFAULT_ABI
!= ABI_V4
17141 && !crtl
->calls_eh_return
)
17143 emit_insn (TARGET_32BIT
17144 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
17145 GEN_INT (info
->total_size
))
17146 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
17147 GEN_INT (info
->total_size
)));
17151 /* Restore AltiVec registers if we have not done so already. */
17152 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
17153 && TARGET_ALTIVEC_ABI
17154 && info
->altivec_size
!= 0
17155 && (DEFAULT_ABI
== ABI_V4
17156 || info
->altivec_save_offset
>= (TARGET_32BIT
? -220 : -288)))
17160 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
17161 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
17163 rtx addr
, areg
, mem
;
17165 areg
= gen_rtx_REG (Pmode
, 0);
17167 (areg
, GEN_INT (info
->altivec_save_offset
17169 + 16 * (i
- info
->first_altivec_reg_save
)));
17171 /* AltiVec addressing mode is [reg+reg]. */
17172 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
17173 mem
= gen_frame_mem (V4SImode
, addr
);
17175 emit_move_insn (gen_rtx_REG (V4SImode
, i
), mem
);
17179 /* Restore VRSAVE if we have not done so already. */
17180 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
17182 && TARGET_ALTIVEC_VRSAVE
17183 && info
->vrsave_mask
!= 0
17184 && (DEFAULT_ABI
== ABI_V4
17185 || info
->vrsave_save_offset
>= (TARGET_32BIT
? -220 : -288)))
17187 rtx addr
, mem
, reg
;
17189 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17190 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
17191 mem
= gen_frame_mem (SImode
, addr
);
17192 reg
= gen_rtx_REG (SImode
, 12);
17193 emit_move_insn (reg
, mem
);
17195 emit_insn (generate_set_vrsave (reg
, info
, 1));
17198 /* Get the old lr if we saved it. If we are restoring registers
17199 out-of-line, then the out-of-line routines can do this for us. */
17202 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
17203 info
->lr_save_offset
+ sp_offset
);
17205 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
17208 /* Get the old cr if we saved it. */
17209 if (info
->cr_save_p
)
17211 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17212 GEN_INT (info
->cr_save_offset
+ sp_offset
));
17213 rtx mem
= gen_frame_mem (SImode
, addr
);
17215 emit_move_insn (gen_rtx_REG (SImode
, 12), mem
);
17218 /* Set LR here to try to overlap restores below. */
17220 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
17221 gen_rtx_REG (Pmode
, 0));
17223 /* Load exception handler data registers, if needed. */
17224 if (crtl
->calls_eh_return
)
17226 unsigned int i
, regno
;
17230 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17231 GEN_INT (sp_offset
+ 5 * reg_size
));
17232 rtx mem
= gen_frame_mem (reg_mode
, addr
);
17234 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
17241 regno
= EH_RETURN_DATA_REGNO (i
);
17242 if (regno
== INVALID_REGNUM
)
17245 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
17246 info
->ehrd_offset
+ sp_offset
17247 + reg_size
* (int) i
);
17249 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
17253 /* Restore GPRs. This is done as a PARALLEL if we are using
17254 the load-multiple instructions. */
17256 && info
->spe_64bit_regs_used
!= 0
17257 && info
->first_gp_reg_save
!= 32)
17259 /* Determine whether we can address all of the registers that need
17260 to be saved with an offset from the stack pointer that fits in
17261 the small const field for SPE memory instructions. */
17262 int spe_regs_addressable_via_sp
17263 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
17264 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
17265 && restoring_GPRs_inline
);
17268 if (spe_regs_addressable_via_sp
)
17269 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
17272 rtx old_frame_reg_rtx
= frame_reg_rtx
;
17273 /* Make r11 point to the start of the SPE save area. We worried about
17274 not clobbering it when we were saving registers in the prologue.
17275 There's no need to worry here because the static chain is passed
17276 anew to every function. */
17277 int ool_adjust
= (restoring_GPRs_inline
17279 : (info
->first_gp_reg_save
17280 - (FIRST_SAVRES_REGISTER
+1))*8);
17282 if (frame_reg_rtx
== sp_reg_rtx
)
17283 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
17284 emit_insn (gen_addsi3 (frame_reg_rtx
, old_frame_reg_rtx
,
17285 GEN_INT (info
->spe_gp_save_offset
17288 /* Keep the invariant that frame_reg_rtx + sp_offset points
17289 at the top of the stack frame. */
17290 sp_offset
= -info
->spe_gp_save_offset
;
17295 if (restoring_GPRs_inline
)
17297 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
17298 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
17300 rtx offset
, addr
, mem
;
17302 /* We're doing all this to ensure that the immediate offset
17303 fits into the immediate field of 'evldd'. */
17304 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset
+ reg_size
* i
));
17306 offset
= GEN_INT (spe_offset
+ reg_size
* i
);
17307 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, offset
);
17308 mem
= gen_rtx_MEM (V2SImode
, addr
);
17310 emit_move_insn (gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
),
17318 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
17320 /*savep=*/false, /*gpr=*/true,
17322 emit_jump_insn (par
);
17324 /* We don't want anybody else emitting things after we jumped
17329 else if (!restoring_GPRs_inline
)
17331 /* We are jumping to an out-of-line function. */
17332 bool can_use_exit
= info
->first_fp_reg_save
== 64;
17335 /* Emit stack reset code if we need it. */
17337 rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
17338 sp_offset
, can_use_exit
);
17340 emit_insn (gen_addsi3 (gen_rtx_REG (Pmode
, 11),
17342 GEN_INT (sp_offset
- info
->fp_size
)));
17344 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
17345 info
->gp_save_offset
, reg_mode
,
17346 /*savep=*/false, /*gpr=*/true,
17347 /*exitp=*/can_use_exit
);
17351 if (info
->cr_save_p
)
17352 rs6000_restore_saved_cr (gen_rtx_REG (SImode
, 12),
17353 using_mtcr_multiple
);
17355 emit_jump_insn (par
);
17357 /* We don't want anybody else emitting things after we jumped
17364 else if (using_load_multiple
)
17367 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
17368 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
17370 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17371 GEN_INT (info
->gp_save_offset
17374 rtx mem
= gen_frame_mem (reg_mode
, addr
);
17377 gen_rtx_SET (VOIDmode
,
17378 gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
),
17381 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
17385 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
17386 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
17388 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17389 GEN_INT (info
->gp_save_offset
17392 rtx mem
= gen_frame_mem (reg_mode
, addr
);
17394 emit_move_insn (gen_rtx_REG (reg_mode
,
17395 info
->first_gp_reg_save
+ i
), mem
);
17399 /* Restore fpr's if we need to do it without calling a function. */
17400 if (restoring_FPRs_inline
)
17401 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
17402 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
17403 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
17406 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17407 GEN_INT (info
->fp_save_offset
17410 mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
17411 ? DFmode
: SFmode
), addr
);
17413 emit_move_insn (gen_rtx_REG (((TARGET_HARD_FLOAT
17414 && TARGET_DOUBLE_FLOAT
)
17415 ? DFmode
: SFmode
),
17416 info
->first_fp_reg_save
+ i
),
17420 /* If we saved cr, restore it here. Just those that were used. */
17421 if (info
->cr_save_p
)
17422 rs6000_restore_saved_cr (gen_rtx_REG (SImode
, 12), using_mtcr_multiple
);
17424 /* If this is V.4, unwind the stack pointer after all of the loads
17426 rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
17427 sp_offset
, !restoring_FPRs_inline
);
17429 if (crtl
->calls_eh_return
)
17431 rtx sa
= EH_RETURN_STACKADJ_RTX
;
17432 emit_insn (TARGET_32BIT
17433 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
, sa
)
17434 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
, sa
));
17440 if (! restoring_FPRs_inline
)
17441 p
= rtvec_alloc (4 + 64 - info
->first_fp_reg_save
);
17443 p
= rtvec_alloc (2);
17445 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
17446 RTVEC_ELT (p
, 1) = (restoring_FPRs_inline
17447 ? gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 65))
17448 : gen_rtx_CLOBBER (VOIDmode
,
17449 gen_rtx_REG (Pmode
, 65)));
17451 /* If we have to restore more than two FP registers, branch to the
17452 restore function. It will return to our caller. */
17453 if (! restoring_FPRs_inline
)
17458 sym
= rs6000_savres_routine_sym (info
,
17462 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
, sym
);
17463 RTVEC_ELT (p
, 3) = gen_rtx_USE (VOIDmode
,
17464 gen_rtx_REG (Pmode
, 11));
17465 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
17468 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
17469 GEN_INT (info
->fp_save_offset
+ 8*i
));
17470 mem
= gen_frame_mem (DFmode
, addr
);
17472 RTVEC_ELT (p
, i
+4) =
17473 gen_rtx_SET (VOIDmode
,
17474 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
17479 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
17483 /* Write function epilogue. */
17486 rs6000_output_function_epilogue (FILE *file
,
17487 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
17489 if (! HAVE_epilogue
)
17491 rtx insn
= get_last_insn ();
17492 /* If the last insn was a BARRIER, we don't have to write anything except
17493 the trace table. */
17494 if (GET_CODE (insn
) == NOTE
)
17495 insn
= prev_nonnote_insn (insn
);
17496 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
17498 /* This is slightly ugly, but at least we don't have two
17499 copies of the epilogue-emitting code. */
17502 /* A NOTE_INSN_DELETED is supposed to be at the start
17503 and end of the "toplevel" insn chain. */
17504 emit_note (NOTE_INSN_DELETED
);
17505 rs6000_emit_epilogue (FALSE
);
17506 emit_note (NOTE_INSN_DELETED
);
17508 /* Expand INSN_ADDRESSES so final() doesn't crash. */
17512 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
17514 INSN_ADDRESSES_NEW (insn
, addr
);
17519 if (TARGET_DEBUG_STACK
)
17520 debug_rtx_list (get_insns (), 100);
17521 final (get_insns (), file
, FALSE
);
17527 macho_branch_islands ();
17528 /* Mach-O doesn't support labels at the end of objects, so if
17529 it looks like we might want one, insert a NOP. */
17531 rtx insn
= get_last_insn ();
17534 && NOTE_KIND (insn
) != NOTE_INSN_DELETED_LABEL
)
17535 insn
= PREV_INSN (insn
);
17539 && NOTE_KIND (insn
) == NOTE_INSN_DELETED_LABEL
)))
17540 fputs ("\tnop\n", file
);
17544 /* Output a traceback table here. See /usr/include/sys/debug.h for info
17547 We don't output a traceback table if -finhibit-size-directive was
17548 used. The documentation for -finhibit-size-directive reads
17549 ``don't output a @code{.size} assembler directive, or anything
17550 else that would cause trouble if the function is split in the
17551 middle, and the two halves are placed at locations far apart in
17552 memory.'' The traceback table has this property, since it
17553 includes the offset from the start of the function to the
17554 traceback table itself.
17556 System V.4 Powerpc's (and the embedded ABI derived from it) use a
17557 different traceback table. */
17558 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
17559 && rs6000_traceback
!= traceback_none
&& !cfun
->is_thunk
)
17561 const char *fname
= NULL
;
17562 const char *language_string
= lang_hooks
.name
;
17563 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
17565 int optional_tbtab
;
17566 rs6000_stack_t
*info
= rs6000_stack_info ();
17568 if (rs6000_traceback
== traceback_full
)
17569 optional_tbtab
= 1;
17570 else if (rs6000_traceback
== traceback_part
)
17571 optional_tbtab
= 0;
17573 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
17575 if (optional_tbtab
)
17577 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
17578 while (*fname
== '.') /* V.4 encodes . in the name */
17581 /* Need label immediately before tbtab, so we can compute
17582 its offset from the function start. */
17583 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
17584 ASM_OUTPUT_LABEL (file
, fname
);
17587 /* The .tbtab pseudo-op can only be used for the first eight
17588 expressions, since it can't handle the possibly variable
17589 length fields that follow. However, if you omit the optional
17590 fields, the assembler outputs zeros for all optional fields
17591 anyways, giving each variable length field is minimum length
17592 (as defined in sys/debug.h). Thus we can not use the .tbtab
17593 pseudo-op at all. */
17595 /* An all-zero word flags the start of the tbtab, for debuggers
17596 that have to find it by searching forward from the entry
17597 point or from the current pc. */
17598 fputs ("\t.long 0\n", file
);
17600 /* Tbtab format type. Use format type 0. */
17601 fputs ("\t.byte 0,", file
);
17603 /* Language type. Unfortunately, there does not seem to be any
17604 official way to discover the language being compiled, so we
17605 use language_string.
17606 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
17607 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
17608 a number, so for now use 9. */
17609 if (! strcmp (language_string
, "GNU C"))
17611 else if (! strcmp (language_string
, "GNU F77")
17612 || ! strcmp (language_string
, "GNU Fortran"))
17614 else if (! strcmp (language_string
, "GNU Pascal"))
17616 else if (! strcmp (language_string
, "GNU Ada"))
17618 else if (! strcmp (language_string
, "GNU C++")
17619 || ! strcmp (language_string
, "GNU Objective-C++"))
17621 else if (! strcmp (language_string
, "GNU Java"))
17623 else if (! strcmp (language_string
, "GNU Objective-C"))
17626 gcc_unreachable ();
17627 fprintf (file
, "%d,", i
);
17629 /* 8 single bit fields: global linkage (not set for C extern linkage,
17630 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
17631 from start of procedure stored in tbtab, internal function, function
17632 has controlled storage, function has no toc, function uses fp,
17633 function logs/aborts fp operations. */
17634 /* Assume that fp operations are used if any fp reg must be saved. */
17635 fprintf (file
, "%d,",
17636 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
17638 /* 6 bitfields: function is interrupt handler, name present in
17639 proc table, function calls alloca, on condition directives
17640 (controls stack walks, 3 bits), saves condition reg, saves
17642 /* The `function calls alloca' bit seems to be set whenever reg 31 is
17643 set up as a frame pointer, even when there is no alloca call. */
17644 fprintf (file
, "%d,",
17645 ((optional_tbtab
<< 6)
17646 | ((optional_tbtab
& frame_pointer_needed
) << 5)
17647 | (info
->cr_save_p
<< 1)
17648 | (info
->lr_save_p
)));
17650 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
17652 fprintf (file
, "%d,",
17653 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
17655 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
17656 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
17658 if (optional_tbtab
)
17660 /* Compute the parameter info from the function decl argument
17663 int next_parm_info_bit
= 31;
17665 for (decl
= DECL_ARGUMENTS (current_function_decl
);
17666 decl
; decl
= TREE_CHAIN (decl
))
17668 rtx parameter
= DECL_INCOMING_RTL (decl
);
17669 enum machine_mode mode
= GET_MODE (parameter
);
17671 if (GET_CODE (parameter
) == REG
)
17673 if (SCALAR_FLOAT_MODE_P (mode
))
17694 gcc_unreachable ();
17697 /* If only one bit will fit, don't or in this entry. */
17698 if (next_parm_info_bit
> 0)
17699 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
17700 next_parm_info_bit
-= 2;
17704 fixed_parms
+= ((GET_MODE_SIZE (mode
)
17705 + (UNITS_PER_WORD
- 1))
17707 next_parm_info_bit
-= 1;
17713 /* Number of fixed point parameters. */
17714 /* This is actually the number of words of fixed point parameters; thus
17715 an 8 byte struct counts as 2; and thus the maximum value is 8. */
17716 fprintf (file
, "%d,", fixed_parms
);
17718 /* 2 bitfields: number of floating point parameters (7 bits), parameters
17720 /* This is actually the number of fp registers that hold parameters;
17721 and thus the maximum value is 13. */
17722 /* Set parameters on stack bit if parameters are not in their original
17723 registers, regardless of whether they are on the stack? Xlc
17724 seems to set the bit when not optimizing. */
17725 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
17727 if (! optional_tbtab
)
17730 /* Optional fields follow. Some are variable length. */
17732 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
17733 11 double float. */
17734 /* There is an entry for each parameter in a register, in the order that
17735 they occur in the parameter list. Any intervening arguments on the
17736 stack are ignored. If the list overflows a long (max possible length
17737 34 bits) then completely leave off all elements that don't fit. */
17738 /* Only emit this long if there was at least one parameter. */
17739 if (fixed_parms
|| float_parms
)
17740 fprintf (file
, "\t.long %d\n", parm_info
);
17742 /* Offset from start of code to tb table. */
17743 fputs ("\t.long ", file
);
17744 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
17746 RS6000_OUTPUT_BASENAME (file
, fname
);
17748 assemble_name (file
, fname
);
17750 rs6000_output_function_entry (file
, fname
);
17753 /* Interrupt handler mask. */
17754 /* Omit this long, since we never set the interrupt handler bit
17757 /* Number of CTL (controlled storage) anchors. */
17758 /* Omit this long, since the has_ctl bit is never set above. */
17760 /* Displacement into stack of each CTL anchor. */
17761 /* Omit this list of longs, because there are no CTL anchors. */
17763 /* Length of function name. */
17766 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
17768 /* Function name. */
17769 assemble_string (fname
, strlen (fname
));
17771 /* Register for alloca automatic storage; this is always reg 31.
17772 Only emit this if the alloca bit was set above. */
17773 if (frame_pointer_needed
)
17774 fputs ("\t.byte 31\n", file
);
17776 fputs ("\t.align 2\n", file
);
17780 /* A C compound statement that outputs the assembler code for a thunk
17781 function, used to implement C++ virtual function calls with
17782 multiple inheritance. The thunk acts as a wrapper around a virtual
17783 function, adjusting the implicit object parameter before handing
17784 control off to the real function.
17786 First, emit code to add the integer DELTA to the location that
17787 contains the incoming first argument. Assume that this argument
17788 contains a pointer, and is the one used to pass the `this' pointer
17789 in C++. This is the incoming argument *before* the function
17790 prologue, e.g. `%o0' on a sparc. The addition must preserve the
17791 values of all other incoming arguments.
17793 After the addition, emit code to jump to FUNCTION, which is a
17794 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
17795 not touch the return address. Hence returning from FUNCTION will
17796 return to whoever called the current `thunk'.
17798 The effect must be as if FUNCTION had been called directly with the
17799 adjusted first argument. This macro is responsible for emitting
17800 all of the code for a thunk function; output_function_prologue()
17801 and output_function_epilogue() are not invoked.
17803 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
17804 been extracted from it.) It might possibly be useful on some
17805 targets, but probably not.
17807 If you do not define this macro, the target-independent code in the
17808 C++ frontend will generate a less efficient heavyweight thunk that
17809 calls FUNCTION instead of jumping to it. The generic approach does
17810 not support varargs. */
17813 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
17814 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
17817 rtx this_rtx
, insn
, funexp
;
17819 reload_completed
= 1;
17820 epilogue_completed
= 1;
17822 /* Mark the end of the (empty) prologue. */
17823 emit_note (NOTE_INSN_PROLOGUE_END
);
17825 /* Find the "this" pointer. If the function returns a structure,
17826 the structure return pointer is in r3. */
17827 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
17828 this_rtx
= gen_rtx_REG (Pmode
, 4);
17830 this_rtx
= gen_rtx_REG (Pmode
, 3);
17832 /* Apply the constant offset, if required. */
17835 rtx delta_rtx
= GEN_INT (delta
);
17836 emit_insn (TARGET_32BIT
17837 ? gen_addsi3 (this_rtx
, this_rtx
, delta_rtx
)
17838 : gen_adddi3 (this_rtx
, this_rtx
, delta_rtx
));
17841 /* Apply the offset from the vtable, if required. */
17844 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
17845 rtx tmp
= gen_rtx_REG (Pmode
, 12);
17847 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this_rtx
));
17848 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
17850 emit_insn (TARGET_32BIT
17851 ? gen_addsi3 (tmp
, tmp
, vcall_offset_rtx
)
17852 : gen_adddi3 (tmp
, tmp
, vcall_offset_rtx
));
17853 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
17857 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
17859 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
17861 emit_insn (TARGET_32BIT
17862 ? gen_addsi3 (this_rtx
, this_rtx
, tmp
)
17863 : gen_adddi3 (this_rtx
, this_rtx
, tmp
));
17866 /* Generate a tail call to the target function. */
17867 if (!TREE_USED (function
))
17869 assemble_external (function
);
17870 TREE_USED (function
) = 1;
17872 funexp
= XEXP (DECL_RTL (function
), 0);
17873 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
17876 if (MACHOPIC_INDIRECT
)
17877 funexp
= machopic_indirect_call_target (funexp
);
17880 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
17881 generate sibcall RTL explicitly. */
17882 insn
= emit_call_insn (
17883 gen_rtx_PARALLEL (VOIDmode
,
17885 gen_rtx_CALL (VOIDmode
,
17886 funexp
, const0_rtx
),
17887 gen_rtx_USE (VOIDmode
, const0_rtx
),
17888 gen_rtx_USE (VOIDmode
,
17889 gen_rtx_REG (SImode
,
17891 gen_rtx_RETURN (VOIDmode
))));
17892 SIBLING_CALL_P (insn
) = 1;
17895 /* Run just enough of rest_of_compilation to get the insns emitted.
17896 There's not really enough bulk here to make other passes such as
17897 instruction scheduling worth while. Note that use_thunk calls
17898 assemble_start_function and assemble_end_function. */
17899 insn
= get_insns ();
17900 insn_locators_alloc ();
17901 shorten_branches (insn
);
17902 final_start_function (insn
, file
, 1);
17903 final (insn
, file
, 1);
17904 final_end_function ();
17905 free_after_compilation (cfun
);
17907 reload_completed
= 0;
17908 epilogue_completed
= 0;
17911 /* A quick summary of the various types of 'constant-pool tables'
17914 Target Flags Name One table per
17915 AIX (none) AIX TOC object file
17916 AIX -mfull-toc AIX TOC object file
17917 AIX -mminimal-toc AIX minimal TOC translation unit
17918 SVR4/EABI (none) SVR4 SDATA object file
17919 SVR4/EABI -fpic SVR4 pic object file
17920 SVR4/EABI -fPIC SVR4 PIC translation unit
17921 SVR4/EABI -mrelocatable EABI TOC function
17922 SVR4/EABI -maix AIX TOC object file
17923 SVR4/EABI -maix -mminimal-toc
17924 AIX minimal TOC translation unit
17926 Name Reg. Set by entries contains:
17927 made by addrs? fp? sum?
17929 AIX TOC 2 crt0 as Y option option
17930 AIX minimal TOC 30 prolog gcc Y Y option
17931 SVR4 SDATA 13 crt0 gcc N Y N
17932 SVR4 pic 30 prolog ld Y not yet N
17933 SVR4 PIC 30 prolog gcc Y option option
17934 EABI TOC 30 prolog gcc Y option option
17938 /* Hash functions for the hash table. */
17941 rs6000_hash_constant (rtx k
)
17943 enum rtx_code code
= GET_CODE (k
);
17944 enum machine_mode mode
= GET_MODE (k
);
17945 unsigned result
= (code
<< 3) ^ mode
;
17946 const char *format
;
17949 format
= GET_RTX_FORMAT (code
);
17950 flen
= strlen (format
);
17956 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
17959 if (mode
!= VOIDmode
)
17960 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
17972 for (; fidx
< flen
; fidx
++)
17973 switch (format
[fidx
])
17978 const char *str
= XSTR (k
, fidx
);
17979 len
= strlen (str
);
17980 result
= result
* 613 + len
;
17981 for (i
= 0; i
< len
; i
++)
17982 result
= result
* 613 + (unsigned) str
[i
];
17987 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
17991 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
17994 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
17995 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
17999 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
18000 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
18007 gcc_unreachable ();
18014 toc_hash_function (const void *hash_entry
)
18016 const struct toc_hash_struct
*thc
=
18017 (const struct toc_hash_struct
*) hash_entry
;
18018 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
18021 /* Compare H1 and H2 for equivalence. */
18024 toc_hash_eq (const void *h1
, const void *h2
)
18026 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
18027 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
18029 if (((const struct toc_hash_struct
*) h1
)->key_mode
18030 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
18033 return rtx_equal_p (r1
, r2
);
18036 /* These are the names given by the C++ front-end to vtables, and
18037 vtable-like objects. Ideally, this logic should not be here;
18038 instead, there should be some programmatic way of inquiring as
18039 to whether or not an object is a vtable. */
18041 #define VTABLE_NAME_P(NAME) \
18042 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
18043 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
18044 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
18045 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
18046 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
18048 #ifdef NO_DOLLAR_IN_LABEL
18049 /* Return a GGC-allocated character string translating dollar signs in
18050 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
18053 rs6000_xcoff_strip_dollar (const char *name
)
18058 p
= strchr (name
, '$');
18060 if (p
== 0 || p
== name
)
18063 len
= strlen (name
);
18064 strip
= (char *) alloca (len
+ 1);
18065 strcpy (strip
, name
);
18066 p
= strchr (strip
, '$');
18070 p
= strchr (p
+ 1, '$');
18073 return ggc_alloc_string (strip
, len
);
18078 rs6000_output_symbol_ref (FILE *file
, rtx x
)
18080 /* Currently C++ toc references to vtables can be emitted before it
18081 is decided whether the vtable is public or private. If this is
18082 the case, then the linker will eventually complain that there is
18083 a reference to an unknown section. Thus, for vtables only,
18084 we emit the TOC reference to reference the symbol and not the
18086 const char *name
= XSTR (x
, 0);
18088 if (VTABLE_NAME_P (name
))
18090 RS6000_OUTPUT_BASENAME (file
, name
);
18093 assemble_name (file
, name
);
18096 /* Output a TOC entry. We derive the entry name from what is being
18100 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
18103 const char *name
= buf
;
18105 HOST_WIDE_INT offset
= 0;
18107 gcc_assert (!TARGET_NO_TOC
);
18109 /* When the linker won't eliminate them, don't output duplicate
18110 TOC entries (this happens on AIX if there is any kind of TOC,
18111 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
18113 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
18115 struct toc_hash_struct
*h
;
18118 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
18119 time because GGC is not initialized at that point. */
18120 if (toc_hash_table
== NULL
)
18121 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
18122 toc_hash_eq
, NULL
);
18124 h
= GGC_NEW (struct toc_hash_struct
);
18126 h
->key_mode
= mode
;
18127 h
->labelno
= labelno
;
18129 found
= htab_find_slot (toc_hash_table
, h
, INSERT
);
18130 if (*found
== NULL
)
18132 else /* This is indeed a duplicate.
18133 Set this label equal to that label. */
18135 fputs ("\t.set ", file
);
18136 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
18137 fprintf (file
, "%d,", labelno
);
18138 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
18139 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
18145 /* If we're going to put a double constant in the TOC, make sure it's
18146 aligned properly when strict alignment is on. */
18147 if (GET_CODE (x
) == CONST_DOUBLE
18148 && STRICT_ALIGNMENT
18149 && GET_MODE_BITSIZE (mode
) >= 64
18150 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
18151 ASM_OUTPUT_ALIGN (file
, 3);
18154 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
18156 /* Handle FP constants specially. Note that if we have a minimal
18157 TOC, things we put here aren't actually in the TOC, so we can allow
18159 if (GET_CODE (x
) == CONST_DOUBLE
&&
18160 (GET_MODE (x
) == TFmode
|| GET_MODE (x
) == TDmode
))
18162 REAL_VALUE_TYPE rv
;
18165 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
18166 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
18167 REAL_VALUE_TO_TARGET_DECIMAL128 (rv
, k
);
18169 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
18173 if (TARGET_MINIMAL_TOC
)
18174 fputs (DOUBLE_INT_ASM_OP
, file
);
18176 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
18177 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
18178 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
18179 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
18180 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
18181 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
18186 if (TARGET_MINIMAL_TOC
)
18187 fputs ("\t.long ", file
);
18189 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
18190 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
18191 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
18192 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
18193 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
18194 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
18198 else if (GET_CODE (x
) == CONST_DOUBLE
&&
18199 (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DDmode
))
18201 REAL_VALUE_TYPE rv
;
18204 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
18206 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
18207 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, k
);
18209 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
18213 if (TARGET_MINIMAL_TOC
)
18214 fputs (DOUBLE_INT_ASM_OP
, file
);
18216 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
18217 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
18218 fprintf (file
, "0x%lx%08lx\n",
18219 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
18224 if (TARGET_MINIMAL_TOC
)
18225 fputs ("\t.long ", file
);
18227 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
18228 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
18229 fprintf (file
, "0x%lx,0x%lx\n",
18230 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
18234 else if (GET_CODE (x
) == CONST_DOUBLE
&&
18235 (GET_MODE (x
) == SFmode
|| GET_MODE (x
) == SDmode
))
18237 REAL_VALUE_TYPE rv
;
18240 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
18241 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
18242 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
18244 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
18248 if (TARGET_MINIMAL_TOC
)
18249 fputs (DOUBLE_INT_ASM_OP
, file
);
18251 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
18252 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
18257 if (TARGET_MINIMAL_TOC
)
18258 fputs ("\t.long ", file
);
18260 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
18261 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
18265 else if (GET_MODE (x
) == VOIDmode
18266 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
18268 unsigned HOST_WIDE_INT low
;
18269 HOST_WIDE_INT high
;
18271 if (GET_CODE (x
) == CONST_DOUBLE
)
18273 low
= CONST_DOUBLE_LOW (x
);
18274 high
= CONST_DOUBLE_HIGH (x
);
18277 #if HOST_BITS_PER_WIDE_INT == 32
18280 high
= (low
& 0x80000000) ? ~0 : 0;
18284 low
= INTVAL (x
) & 0xffffffff;
18285 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
18289 /* TOC entries are always Pmode-sized, but since this
18290 is a bigendian machine then if we're putting smaller
18291 integer constants in the TOC we have to pad them.
18292 (This is still a win over putting the constants in
18293 a separate constant pool, because then we'd have
18294 to have both a TOC entry _and_ the actual constant.)
18296 For a 32-bit target, CONST_INT values are loaded and shifted
18297 entirely within `low' and can be stored in one TOC entry. */
18299 /* It would be easy to make this work, but it doesn't now. */
18300 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
18302 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
18304 #if HOST_BITS_PER_WIDE_INT == 32
18305 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
18306 POINTER_SIZE
, &low
, &high
, 0);
18309 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
18310 high
= (HOST_WIDE_INT
) low
>> 32;
18317 if (TARGET_MINIMAL_TOC
)
18318 fputs (DOUBLE_INT_ASM_OP
, file
);
18320 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
18321 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
18322 fprintf (file
, "0x%lx%08lx\n",
18323 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
18328 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
18330 if (TARGET_MINIMAL_TOC
)
18331 fputs ("\t.long ", file
);
18333 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
18334 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
18335 fprintf (file
, "0x%lx,0x%lx\n",
18336 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
18340 if (TARGET_MINIMAL_TOC
)
18341 fputs ("\t.long ", file
);
18343 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
18344 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
18350 if (GET_CODE (x
) == CONST
)
18352 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
);
18354 base
= XEXP (XEXP (x
, 0), 0);
18355 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
18358 switch (GET_CODE (base
))
18361 name
= XSTR (base
, 0);
18365 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
18366 CODE_LABEL_NUMBER (XEXP (base
, 0)));
18370 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
18374 gcc_unreachable ();
18377 if (TARGET_MINIMAL_TOC
)
18378 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
18381 fputs ("\t.tc ", file
);
18382 RS6000_OUTPUT_BASENAME (file
, name
);
18385 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
18387 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
18389 fputs ("[TC],", file
);
18392 /* Currently C++ toc references to vtables can be emitted before it
18393 is decided whether the vtable is public or private. If this is
18394 the case, then the linker will eventually complain that there is
18395 a TOC reference to an unknown section. Thus, for vtables only,
18396 we emit the TOC reference to reference the symbol and not the
18398 if (VTABLE_NAME_P (name
))
18400 RS6000_OUTPUT_BASENAME (file
, name
);
18402 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
18403 else if (offset
> 0)
18404 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
18407 output_addr_const (file
, x
);
18411 /* Output an assembler pseudo-op to write an ASCII string of N characters
18412 starting at P to FILE.
18414 On the RS/6000, we have to do this using the .byte operation and
18415 write out special characters outside the quoted string.
18416 Also, the assembler is broken; very long strings are truncated,
18417 so we must artificially break them up early. */
18420 output_ascii (FILE *file
, const char *p
, int n
)
18423 int i
, count_string
;
18424 const char *for_string
= "\t.byte \"";
18425 const char *for_decimal
= "\t.byte ";
18426 const char *to_close
= NULL
;
18429 for (i
= 0; i
< n
; i
++)
18432 if (c
>= ' ' && c
< 0177)
18435 fputs (for_string
, file
);
18438 /* Write two quotes to get one. */
18446 for_decimal
= "\"\n\t.byte ";
18450 if (count_string
>= 512)
18452 fputs (to_close
, file
);
18454 for_string
= "\t.byte \"";
18455 for_decimal
= "\t.byte ";
18463 fputs (for_decimal
, file
);
18464 fprintf (file
, "%d", c
);
18466 for_string
= "\n\t.byte \"";
18467 for_decimal
= ", ";
18473 /* Now close the string if we have written one. Then end the line. */
18475 fputs (to_close
, file
);
18478 /* Generate a unique section name for FILENAME for a section type
18479 represented by SECTION_DESC. Output goes into BUF.
18481 SECTION_DESC can be any string, as long as it is different for each
18482 possible section type.
18484 We name the section in the same manner as xlc. The name begins with an
18485 underscore followed by the filename (after stripping any leading directory
18486 names) with the last period replaced by the string SECTION_DESC. If
18487 FILENAME does not contain a period, SECTION_DESC is appended to the end of
18491 rs6000_gen_section_name (char **buf
, const char *filename
,
18492 const char *section_desc
)
18494 const char *q
, *after_last_slash
, *last_period
= 0;
18498 after_last_slash
= filename
;
18499 for (q
= filename
; *q
; q
++)
18502 after_last_slash
= q
+ 1;
18503 else if (*q
== '.')
18507 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
18508 *buf
= (char *) xmalloc (len
);
18513 for (q
= after_last_slash
; *q
; q
++)
18515 if (q
== last_period
)
18517 strcpy (p
, section_desc
);
18518 p
+= strlen (section_desc
);
18522 else if (ISALNUM (*q
))
18526 if (last_period
== 0)
18527 strcpy (p
, section_desc
);
18532 /* Emit profile function. */
18535 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
18537 /* Non-standard profiling for kernels, which just saves LR then calls
18538 _mcount without worrying about arg saves. The idea is to change
18539 the function prologue as little as possible as it isn't easy to
18540 account for arg save/restore code added just for _mcount. */
18541 if (TARGET_PROFILE_KERNEL
)
18544 if (DEFAULT_ABI
== ABI_AIX
)
18546 #ifndef NO_PROFILE_COUNTERS
18547 # define NO_PROFILE_COUNTERS 0
18549 if (NO_PROFILE_COUNTERS
)
18550 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
18551 LCT_NORMAL
, VOIDmode
, 0);
18555 const char *label_name
;
18558 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
18559 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
18560 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
18562 emit_library_call (init_one_libfunc (RS6000_MCOUNT
),
18563 LCT_NORMAL
, VOIDmode
, 1, fun
, Pmode
);
18566 else if (DEFAULT_ABI
== ABI_DARWIN
)
18568 const char *mcount_name
= RS6000_MCOUNT
;
18569 int caller_addr_regno
= LR_REGNO
;
18571 /* Be conservative and always set this, at least for now. */
18572 crtl
->uses_pic_offset_table
= 1;
18575 /* For PIC code, set up a stub and collect the caller's address
18576 from r0, which is where the prologue puts it. */
18577 if (MACHOPIC_INDIRECT
18578 && crtl
->uses_pic_offset_table
)
18579 caller_addr_regno
= 0;
18581 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
18582 LCT_NORMAL
, VOIDmode
, 1,
18583 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
18587 /* Write function profiler code. */
18590 output_function_profiler (FILE *file
, int labelno
)
18594 switch (DEFAULT_ABI
)
18597 gcc_unreachable ();
18602 warning (0, "no profiling of 64-bit code for this ABI");
18605 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
18606 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
18607 if (NO_PROFILE_COUNTERS
)
18609 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
18610 reg_names
[0], reg_names
[1]);
18612 else if (TARGET_SECURE_PLT
&& flag_pic
)
18614 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
18615 reg_names
[0], reg_names
[1]);
18616 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
18617 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
18618 reg_names
[12], reg_names
[12]);
18619 assemble_name (file
, buf
);
18620 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
18621 assemble_name (file
, buf
);
18622 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
18624 else if (flag_pic
== 1)
18626 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
18627 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
18628 reg_names
[0], reg_names
[1]);
18629 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
18630 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
18631 assemble_name (file
, buf
);
18632 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
18634 else if (flag_pic
> 1)
18636 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
18637 reg_names
[0], reg_names
[1]);
18638 /* Now, we need to get the address of the label. */
18639 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
18640 assemble_name (file
, buf
);
18641 fputs ("-.\n1:", file
);
18642 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
18643 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
18644 reg_names
[0], reg_names
[11]);
18645 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
18646 reg_names
[0], reg_names
[0], reg_names
[11]);
18650 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
18651 assemble_name (file
, buf
);
18652 fputs ("@ha\n", file
);
18653 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
18654 reg_names
[0], reg_names
[1]);
18655 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
18656 assemble_name (file
, buf
);
18657 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
18660 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
18661 fprintf (file
, "\tbl %s%s\n",
18662 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
18667 if (!TARGET_PROFILE_KERNEL
)
18669 /* Don't do anything, done in output_profile_hook (). */
18673 gcc_assert (!TARGET_32BIT
);
18675 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
18676 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
18678 if (cfun
->static_chain_decl
!= NULL
)
18680 asm_fprintf (file
, "\tstd %s,24(%s)\n",
18681 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
18682 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
18683 asm_fprintf (file
, "\tld %s,24(%s)\n",
18684 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
18687 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
18695 /* The following variable value is the last issued insn. */
18697 static rtx last_scheduled_insn
;
18699 /* The following variable helps to balance issuing of load and
18700 store instructions */
18702 static int load_store_pendulum
;
18704 /* Power4 load update and store update instructions are cracked into a
18705 load or store and an integer insn which are executed in the same cycle.
18706 Branches have their own dispatch slot which does not count against the
18707 GCC issue rate, but it changes the program flow so there are no other
18708 instructions to issue in this cycle. */
18711 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED
,
18712 int verbose ATTRIBUTE_UNUSED
,
18713 rtx insn
, int more
)
18715 last_scheduled_insn
= insn
;
18716 if (GET_CODE (PATTERN (insn
)) == USE
18717 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18719 cached_can_issue_more
= more
;
18720 return cached_can_issue_more
;
18723 if (insn_terminates_group_p (insn
, current_group
))
18725 cached_can_issue_more
= 0;
18726 return cached_can_issue_more
;
18729 /* If no reservation, but reach here */
18730 if (recog_memoized (insn
) < 0)
18733 if (rs6000_sched_groups
)
18735 if (is_microcoded_insn (insn
))
18736 cached_can_issue_more
= 0;
18737 else if (is_cracked_insn (insn
))
18738 cached_can_issue_more
= more
> 2 ? more
- 2 : 0;
18740 cached_can_issue_more
= more
- 1;
18742 return cached_can_issue_more
;
18745 if (rs6000_cpu_attr
== CPU_CELL
&& is_nonpipeline_insn (insn
))
18748 cached_can_issue_more
= more
- 1;
18749 return cached_can_issue_more
;
18752 /* Adjust the cost of a scheduling dependency. Return the new cost of
18753 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
18756 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
18758 enum attr_type attr_type
;
18760 if (! recog_memoized (insn
))
18763 switch (REG_NOTE_KIND (link
))
18767 /* Data dependency; DEP_INSN writes a register that INSN reads
18768 some cycles later. */
18770 /* Separate a load from a narrower, dependent store. */
18771 if (rs6000_sched_groups
18772 && GET_CODE (PATTERN (insn
)) == SET
18773 && GET_CODE (PATTERN (dep_insn
)) == SET
18774 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
18775 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
18776 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
18777 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
18780 attr_type
= get_attr_type (insn
);
18785 /* Tell the first scheduling pass about the latency between
18786 a mtctr and bctr (and mtlr and br/blr). The first
18787 scheduling pass will not know about this latency since
18788 the mtctr instruction, which has the latency associated
18789 to it, will be generated by reload. */
18790 return TARGET_POWER
? 5 : 4;
18792 /* Leave some extra cycles between a compare and its
18793 dependent branch, to inhibit expensive mispredicts. */
18794 if ((rs6000_cpu_attr
== CPU_PPC603
18795 || rs6000_cpu_attr
== CPU_PPC604
18796 || rs6000_cpu_attr
== CPU_PPC604E
18797 || rs6000_cpu_attr
== CPU_PPC620
18798 || rs6000_cpu_attr
== CPU_PPC630
18799 || rs6000_cpu_attr
== CPU_PPC750
18800 || rs6000_cpu_attr
== CPU_PPC7400
18801 || rs6000_cpu_attr
== CPU_PPC7450
18802 || rs6000_cpu_attr
== CPU_POWER4
18803 || rs6000_cpu_attr
== CPU_POWER5
18804 || rs6000_cpu_attr
== CPU_CELL
)
18805 && recog_memoized (dep_insn
)
18806 && (INSN_CODE (dep_insn
) >= 0))
18808 switch (get_attr_type (dep_insn
))
18812 case TYPE_DELAYED_COMPARE
:
18813 case TYPE_IMUL_COMPARE
:
18814 case TYPE_LMUL_COMPARE
:
18815 case TYPE_FPCOMPARE
:
18816 case TYPE_CR_LOGICAL
:
18817 case TYPE_DELAYED_CR
:
18826 case TYPE_STORE_UX
:
18828 case TYPE_FPSTORE_U
:
18829 case TYPE_FPSTORE_UX
:
18830 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18831 && recog_memoized (dep_insn
)
18832 && (INSN_CODE (dep_insn
) >= 0))
18835 if (GET_CODE (PATTERN (insn
)) != SET
)
18836 /* If this happens, we have to extend this to schedule
18837 optimally. Return default for now. */
18840 /* Adjust the cost for the case where the value written
18841 by a fixed point operation is used as the address
18842 gen value on a store. */
18843 switch (get_attr_type (dep_insn
))
18850 if (! store_data_bypass_p (dep_insn
, insn
))
18854 case TYPE_LOAD_EXT
:
18855 case TYPE_LOAD_EXT_U
:
18856 case TYPE_LOAD_EXT_UX
:
18857 case TYPE_VAR_SHIFT_ROTATE
:
18858 case TYPE_VAR_DELAYED_COMPARE
:
18860 if (! store_data_bypass_p (dep_insn
, insn
))
18866 case TYPE_FAST_COMPARE
:
18869 case TYPE_INSERT_WORD
:
18870 case TYPE_INSERT_DWORD
:
18871 case TYPE_FPLOAD_U
:
18872 case TYPE_FPLOAD_UX
:
18874 case TYPE_STORE_UX
:
18875 case TYPE_FPSTORE_U
:
18876 case TYPE_FPSTORE_UX
:
18878 if (! store_data_bypass_p (dep_insn
, insn
))
18886 case TYPE_IMUL_COMPARE
:
18887 case TYPE_LMUL_COMPARE
:
18889 if (! store_data_bypass_p (dep_insn
, insn
))
18895 if (! store_data_bypass_p (dep_insn
, insn
))
18901 if (! store_data_bypass_p (dep_insn
, insn
))
18914 case TYPE_LOAD_EXT
:
18915 case TYPE_LOAD_EXT_U
:
18916 case TYPE_LOAD_EXT_UX
:
18917 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18918 && recog_memoized (dep_insn
)
18919 && (INSN_CODE (dep_insn
) >= 0))
18922 /* Adjust the cost for the case where the value written
18923 by a fixed point instruction is used within the address
18924 gen portion of a subsequent load(u)(x) */
18925 switch (get_attr_type (dep_insn
))
18932 if (set_to_load_agen (dep_insn
, insn
))
18936 case TYPE_LOAD_EXT
:
18937 case TYPE_LOAD_EXT_U
:
18938 case TYPE_LOAD_EXT_UX
:
18939 case TYPE_VAR_SHIFT_ROTATE
:
18940 case TYPE_VAR_DELAYED_COMPARE
:
18942 if (set_to_load_agen (dep_insn
, insn
))
18948 case TYPE_FAST_COMPARE
:
18951 case TYPE_INSERT_WORD
:
18952 case TYPE_INSERT_DWORD
:
18953 case TYPE_FPLOAD_U
:
18954 case TYPE_FPLOAD_UX
:
18956 case TYPE_STORE_UX
:
18957 case TYPE_FPSTORE_U
:
18958 case TYPE_FPSTORE_UX
:
18960 if (set_to_load_agen (dep_insn
, insn
))
18968 case TYPE_IMUL_COMPARE
:
18969 case TYPE_LMUL_COMPARE
:
18971 if (set_to_load_agen (dep_insn
, insn
))
18977 if (set_to_load_agen (dep_insn
, insn
))
18983 if (set_to_load_agen (dep_insn
, insn
))
18994 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18995 && recog_memoized (dep_insn
)
18996 && (INSN_CODE (dep_insn
) >= 0)
18997 && (get_attr_type (dep_insn
) == TYPE_MFFGPR
))
19004 /* Fall out to return default cost. */
19008 case REG_DEP_OUTPUT
:
19009 /* Output dependency; DEP_INSN writes a register that INSN writes some
19011 if ((rs6000_cpu
== PROCESSOR_POWER6
)
19012 && recog_memoized (dep_insn
)
19013 && (INSN_CODE (dep_insn
) >= 0))
19015 attr_type
= get_attr_type (insn
);
19020 if (get_attr_type (dep_insn
) == TYPE_FP
)
19024 if (get_attr_type (dep_insn
) == TYPE_MFFGPR
)
19032 /* Anti dependency; DEP_INSN reads a register that INSN writes some
19037 gcc_unreachable ();
19043 /* The function returns a true if INSN is microcoded.
19044 Return false otherwise. */
19047 is_microcoded_insn (rtx insn
)
19049 if (!insn
|| !INSN_P (insn
)
19050 || GET_CODE (PATTERN (insn
)) == USE
19051 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19054 if (rs6000_cpu_attr
== CPU_CELL
)
19055 return get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
;
19057 if (rs6000_sched_groups
)
19059 enum attr_type type
= get_attr_type (insn
);
19060 if (type
== TYPE_LOAD_EXT_U
19061 || type
== TYPE_LOAD_EXT_UX
19062 || type
== TYPE_LOAD_UX
19063 || type
== TYPE_STORE_UX
19064 || type
== TYPE_MFCR
)
19071 /* The function returns true if INSN is cracked into 2 instructions
19072 by the processor (and therefore occupies 2 issue slots). */
19075 is_cracked_insn (rtx insn
)
19077 if (!insn
|| !INSN_P (insn
)
19078 || GET_CODE (PATTERN (insn
)) == USE
19079 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19082 if (rs6000_sched_groups
)
19084 enum attr_type type
= get_attr_type (insn
);
19085 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
19086 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
19087 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
19088 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
19089 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
19090 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
19091 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
19092 || type
== TYPE_INSERT_WORD
)
19099 /* The function returns true if INSN can be issued only from
19100 the branch slot. */
19103 is_branch_slot_insn (rtx insn
)
19105 if (!insn
|| !INSN_P (insn
)
19106 || GET_CODE (PATTERN (insn
)) == USE
19107 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19110 if (rs6000_sched_groups
)
19112 enum attr_type type
= get_attr_type (insn
);
19113 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
19121 /* The function returns true if out_inst sets a value that is
19122 used in the address generation computation of in_insn */
19124 set_to_load_agen (rtx out_insn
, rtx in_insn
)
19126 rtx out_set
, in_set
;
19128 /* For performance reasons, only handle the simple case where
19129 both loads are a single_set. */
19130 out_set
= single_set (out_insn
);
19133 in_set
= single_set (in_insn
);
19135 return reg_mentioned_p (SET_DEST (out_set
), SET_SRC (in_set
));
19141 /* The function returns true if the target storage location of
19142 out_insn is adjacent to the target storage location of in_insn */
19143 /* Return 1 if memory locations are adjacent. */
19146 adjacent_mem_locations (rtx insn1
, rtx insn2
)
19149 rtx a
= get_store_dest (PATTERN (insn1
));
19150 rtx b
= get_store_dest (PATTERN (insn2
));
19152 if ((GET_CODE (XEXP (a
, 0)) == REG
19153 || (GET_CODE (XEXP (a
, 0)) == PLUS
19154 && GET_CODE (XEXP (XEXP (a
, 0), 1)) == CONST_INT
))
19155 && (GET_CODE (XEXP (b
, 0)) == REG
19156 || (GET_CODE (XEXP (b
, 0)) == PLUS
19157 && GET_CODE (XEXP (XEXP (b
, 0), 1)) == CONST_INT
)))
19159 HOST_WIDE_INT val0
= 0, val1
= 0, val_diff
;
19162 if (GET_CODE (XEXP (a
, 0)) == PLUS
)
19164 reg0
= XEXP (XEXP (a
, 0), 0);
19165 val0
= INTVAL (XEXP (XEXP (a
, 0), 1));
19168 reg0
= XEXP (a
, 0);
19170 if (GET_CODE (XEXP (b
, 0)) == PLUS
)
19172 reg1
= XEXP (XEXP (b
, 0), 0);
19173 val1
= INTVAL (XEXP (XEXP (b
, 0), 1));
19176 reg1
= XEXP (b
, 0);
19178 val_diff
= val1
- val0
;
19180 return ((REGNO (reg0
) == REGNO (reg1
))
19181 && ((MEM_SIZE (a
) && val_diff
== INTVAL (MEM_SIZE (a
)))
19182 || (MEM_SIZE (b
) && val_diff
== -INTVAL (MEM_SIZE (b
)))));
19188 /* A C statement (sans semicolon) to update the integer scheduling
19189 priority INSN_PRIORITY (INSN). Increase the priority to execute the
19190 INSN earlier, reduce the priority to execute INSN later. Do not
19191 define this macro if you do not need to adjust the scheduling
19192 priorities of insns. */
19195 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
19197 /* On machines (like the 750) which have asymmetric integer units,
19198 where one integer unit can do multiply and divides and the other
19199 can't, reduce the priority of multiply/divide so it is scheduled
19200 before other integer operations. */
19203 if (! INSN_P (insn
))
19206 if (GET_CODE (PATTERN (insn
)) == USE
)
19209 switch (rs6000_cpu_attr
) {
19211 switch (get_attr_type (insn
))
19218 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
19219 priority
, priority
);
19220 if (priority
>= 0 && priority
< 0x01000000)
19227 if (insn_must_be_first_in_group (insn
)
19228 && reload_completed
19229 && current_sched_info
->sched_max_insns_priority
19230 && rs6000_sched_restricted_insns_priority
)
19233 /* Prioritize insns that can be dispatched only in the first
19235 if (rs6000_sched_restricted_insns_priority
== 1)
19236 /* Attach highest priority to insn. This means that in
19237 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
19238 precede 'priority' (critical path) considerations. */
19239 return current_sched_info
->sched_max_insns_priority
;
19240 else if (rs6000_sched_restricted_insns_priority
== 2)
19241 /* Increase priority of insn by a minimal amount. This means that in
19242 haifa-sched.c:ready_sort(), only 'priority' (critical path)
19243 considerations precede dispatch-slot restriction considerations. */
19244 return (priority
+ 1);
19247 if (rs6000_cpu
== PROCESSOR_POWER6
19248 && ((load_store_pendulum
== -2 && is_load_insn (insn
))
19249 || (load_store_pendulum
== 2 && is_store_insn (insn
))))
19250 /* Attach highest priority to insn if the scheduler has just issued two
19251 stores and this instruction is a load, or two loads and this instruction
19252 is a store. Power6 wants loads and stores scheduled alternately
19254 return current_sched_info
->sched_max_insns_priority
;
19259 /* Return true if the instruction is nonpipelined on the Cell. */
19261 is_nonpipeline_insn (rtx insn
)
19263 enum attr_type type
;
19264 if (!insn
|| !INSN_P (insn
)
19265 || GET_CODE (PATTERN (insn
)) == USE
19266 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19269 type
= get_attr_type (insn
);
19270 if (type
== TYPE_IMUL
19271 || type
== TYPE_IMUL2
19272 || type
== TYPE_IMUL3
19273 || type
== TYPE_LMUL
19274 || type
== TYPE_IDIV
19275 || type
== TYPE_LDIV
19276 || type
== TYPE_SDIV
19277 || type
== TYPE_DDIV
19278 || type
== TYPE_SSQRT
19279 || type
== TYPE_DSQRT
19280 || type
== TYPE_MFCR
19281 || type
== TYPE_MFCRF
19282 || type
== TYPE_MFJMPR
)
19290 /* Return how many instructions the machine can issue per cycle. */
19293 rs6000_issue_rate (void)
19295 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
19296 if (!reload_completed
)
19299 switch (rs6000_cpu_attr
) {
19300 case CPU_RIOS1
: /* ? */
19302 case CPU_PPC601
: /* ? */
19311 case CPU_PPCE300C2
:
19312 case CPU_PPCE300C3
:
19313 case CPU_PPCE500MC
:
19330 /* Return how many instructions to look ahead for better insn
19334 rs6000_use_sched_lookahead (void)
19336 if (rs6000_cpu_attr
== CPU_PPC8540
)
19338 if (rs6000_cpu_attr
== CPU_CELL
)
19339 return (reload_completed
? 8 : 0);
19343 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
19345 rs6000_use_sched_lookahead_guard (rtx insn
)
19347 if (rs6000_cpu_attr
!= CPU_CELL
)
19350 if (insn
== NULL_RTX
|| !INSN_P (insn
))
19353 if (!reload_completed
19354 || is_nonpipeline_insn (insn
)
19355 || is_microcoded_insn (insn
))
19361 /* Determine is PAT refers to memory. */
19364 is_mem_ref (rtx pat
)
19370 /* stack_tie does not produce any real memory traffic. */
19371 if (GET_CODE (pat
) == UNSPEC
19372 && XINT (pat
, 1) == UNSPEC_TIE
)
19375 if (GET_CODE (pat
) == MEM
)
19378 /* Recursively process the pattern. */
19379 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
19381 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
19384 ret
|= is_mem_ref (XEXP (pat
, i
));
19385 else if (fmt
[i
] == 'E')
19386 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
19387 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
19393 /* Determine if PAT is a PATTERN of a load insn. */
19396 is_load_insn1 (rtx pat
)
19398 if (!pat
|| pat
== NULL_RTX
)
19401 if (GET_CODE (pat
) == SET
)
19402 return is_mem_ref (SET_SRC (pat
));
19404 if (GET_CODE (pat
) == PARALLEL
)
19408 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
19409 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
19416 /* Determine if INSN loads from memory. */
19419 is_load_insn (rtx insn
)
19421 if (!insn
|| !INSN_P (insn
))
19424 if (GET_CODE (insn
) == CALL_INSN
)
19427 return is_load_insn1 (PATTERN (insn
));
19430 /* Determine if PAT is a PATTERN of a store insn. */
19433 is_store_insn1 (rtx pat
)
19435 if (!pat
|| pat
== NULL_RTX
)
19438 if (GET_CODE (pat
) == SET
)
19439 return is_mem_ref (SET_DEST (pat
));
19441 if (GET_CODE (pat
) == PARALLEL
)
19445 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
19446 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
19453 /* Determine if INSN stores to memory. */
19456 is_store_insn (rtx insn
)
19458 if (!insn
|| !INSN_P (insn
))
19461 return is_store_insn1 (PATTERN (insn
));
19464 /* Return the dest of a store insn. */
19467 get_store_dest (rtx pat
)
19469 gcc_assert (is_store_insn1 (pat
));
19471 if (GET_CODE (pat
) == SET
)
19472 return SET_DEST (pat
);
19473 else if (GET_CODE (pat
) == PARALLEL
)
19477 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
19479 rtx inner_pat
= XVECEXP (pat
, 0, i
);
19480 if (GET_CODE (inner_pat
) == SET
19481 && is_mem_ref (SET_DEST (inner_pat
)))
19485 /* We shouldn't get here, because we should have either a simple
19486 store insn or a store with update which are covered above. */
19490 /* Returns whether the dependence between INSN and NEXT is considered
19491 costly by the given target. */
19494 rs6000_is_costly_dependence (dep_t dep
, int cost
, int distance
)
19499 /* If the flag is not enabled - no dependence is considered costly;
19500 allow all dependent insns in the same group.
19501 This is the most aggressive option. */
19502 if (rs6000_sched_costly_dep
== no_dep_costly
)
19505 /* If the flag is set to 1 - a dependence is always considered costly;
19506 do not allow dependent instructions in the same group.
19507 This is the most conservative option. */
19508 if (rs6000_sched_costly_dep
== all_deps_costly
)
19511 insn
= DEP_PRO (dep
);
19512 next
= DEP_CON (dep
);
19514 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
19515 && is_load_insn (next
)
19516 && is_store_insn (insn
))
19517 /* Prevent load after store in the same group. */
19520 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
19521 && is_load_insn (next
)
19522 && is_store_insn (insn
)
19523 && DEP_TYPE (dep
) == REG_DEP_TRUE
)
19524 /* Prevent load after store in the same group if it is a true
19528 /* The flag is set to X; dependences with latency >= X are considered costly,
19529 and will not be scheduled in the same group. */
19530 if (rs6000_sched_costly_dep
<= max_dep_latency
19531 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
19537 /* Return the next insn after INSN that is found before TAIL is reached,
19538 skipping any "non-active" insns - insns that will not actually occupy
19539 an issue slot. Return NULL_RTX if such an insn is not found. */
19542 get_next_active_insn (rtx insn
, rtx tail
)
19544 if (insn
== NULL_RTX
|| insn
== tail
)
19549 insn
= NEXT_INSN (insn
);
19550 if (insn
== NULL_RTX
|| insn
== tail
)
19555 || (NONJUMP_INSN_P (insn
)
19556 && GET_CODE (PATTERN (insn
)) != USE
19557 && GET_CODE (PATTERN (insn
)) != CLOBBER
19558 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
19564 /* We are about to begin issuing insns for this clock cycle. */
19567 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED
, int sched_verbose
,
19568 rtx
*ready ATTRIBUTE_UNUSED
,
19569 int *pn_ready ATTRIBUTE_UNUSED
,
19570 int clock_var ATTRIBUTE_UNUSED
)
19572 int n_ready
= *pn_ready
;
19575 fprintf (dump
, "// rs6000_sched_reorder :\n");
19577 /* Reorder the ready list, if the second to last ready insn
19578 is a nonepipeline insn. */
19579 if (rs6000_cpu_attr
== CPU_CELL
&& n_ready
> 1)
19581 if (is_nonpipeline_insn (ready
[n_ready
- 1])
19582 && (recog_memoized (ready
[n_ready
- 2]) > 0))
19583 /* Simply swap first two insns. */
19585 rtx tmp
= ready
[n_ready
- 1];
19586 ready
[n_ready
- 1] = ready
[n_ready
- 2];
19587 ready
[n_ready
- 2] = tmp
;
19591 if (rs6000_cpu
== PROCESSOR_POWER6
)
19592 load_store_pendulum
= 0;
19594 return rs6000_issue_rate ();
19597 /* Like rs6000_sched_reorder, but called after issuing each insn. */
19600 rs6000_sched_reorder2 (FILE *dump
, int sched_verbose
, rtx
*ready
,
19601 int *pn_ready
, int clock_var ATTRIBUTE_UNUSED
)
19604 fprintf (dump
, "// rs6000_sched_reorder2 :\n");
19606 /* For Power6, we need to handle some special cases to try and keep the
19607 store queue from overflowing and triggering expensive flushes.
19609 This code monitors how load and store instructions are being issued
19610 and skews the ready list one way or the other to increase the likelihood
19611 that a desired instruction is issued at the proper time.
19613 A couple of things are done. First, we maintain a "load_store_pendulum"
19614 to track the current state of load/store issue.
19616 - If the pendulum is at zero, then no loads or stores have been
19617 issued in the current cycle so we do nothing.
19619 - If the pendulum is 1, then a single load has been issued in this
19620 cycle and we attempt to locate another load in the ready list to
19623 - If the pendulum is -2, then two stores have already been
19624 issued in this cycle, so we increase the priority of the first load
19625 in the ready list to increase it's likelihood of being chosen first
19628 - If the pendulum is -1, then a single store has been issued in this
19629 cycle and we attempt to locate another store in the ready list to
19630 issue with it, preferring a store to an adjacent memory location to
19631 facilitate store pairing in the store queue.
19633 - If the pendulum is 2, then two loads have already been
19634 issued in this cycle, so we increase the priority of the first store
19635 in the ready list to increase it's likelihood of being chosen first
19638 - If the pendulum < -2 or > 2, then do nothing.
19640 Note: This code covers the most common scenarios. There exist non
19641 load/store instructions which make use of the LSU and which
19642 would need to be accounted for to strictly model the behavior
19643 of the machine. Those instructions are currently unaccounted
19644 for to help minimize compile time overhead of this code.
19646 if (rs6000_cpu
== PROCESSOR_POWER6
&& last_scheduled_insn
)
19652 if (is_store_insn (last_scheduled_insn
))
19653 /* Issuing a store, swing the load_store_pendulum to the left */
19654 load_store_pendulum
--;
19655 else if (is_load_insn (last_scheduled_insn
))
19656 /* Issuing a load, swing the load_store_pendulum to the right */
19657 load_store_pendulum
++;
19659 return cached_can_issue_more
;
19661 /* If the pendulum is balanced, or there is only one instruction on
19662 the ready list, then all is well, so return. */
19663 if ((load_store_pendulum
== 0) || (*pn_ready
<= 1))
19664 return cached_can_issue_more
;
19666 if (load_store_pendulum
== 1)
19668 /* A load has been issued in this cycle. Scan the ready list
19669 for another load to issue with it */
19674 if (is_load_insn (ready
[pos
]))
19676 /* Found a load. Move it to the head of the ready list,
19677 and adjust it's priority so that it is more likely to
19680 for (i
=pos
; i
<*pn_ready
-1; i
++)
19681 ready
[i
] = ready
[i
+ 1];
19682 ready
[*pn_ready
-1] = tmp
;
19684 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
19685 INSN_PRIORITY (tmp
)++;
19691 else if (load_store_pendulum
== -2)
19693 /* Two stores have been issued in this cycle. Increase the
19694 priority of the first load in the ready list to favor it for
19695 issuing in the next cycle. */
19700 if (is_load_insn (ready
[pos
])
19702 && INSN_PRIORITY_KNOWN (ready
[pos
]))
19704 INSN_PRIORITY (ready
[pos
])++;
19706 /* Adjust the pendulum to account for the fact that a load
19707 was found and increased in priority. This is to prevent
19708 increasing the priority of multiple loads */
19709 load_store_pendulum
--;
19716 else if (load_store_pendulum
== -1)
19718 /* A store has been issued in this cycle. Scan the ready list for
19719 another store to issue with it, preferring a store to an adjacent
19721 int first_store_pos
= -1;
19727 if (is_store_insn (ready
[pos
]))
19729 /* Maintain the index of the first store found on the
19731 if (first_store_pos
== -1)
19732 first_store_pos
= pos
;
19734 if (is_store_insn (last_scheduled_insn
)
19735 && adjacent_mem_locations (last_scheduled_insn
,ready
[pos
]))
19737 /* Found an adjacent store. Move it to the head of the
19738 ready list, and adjust it's priority so that it is
19739 more likely to stay there */
19741 for (i
=pos
; i
<*pn_ready
-1; i
++)
19742 ready
[i
] = ready
[i
+ 1];
19743 ready
[*pn_ready
-1] = tmp
;
19745 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
19746 INSN_PRIORITY (tmp
)++;
19748 first_store_pos
= -1;
19756 if (first_store_pos
>= 0)
19758 /* An adjacent store wasn't found, but a non-adjacent store was,
19759 so move the non-adjacent store to the front of the ready
19760 list, and adjust its priority so that it is more likely to
19762 tmp
= ready
[first_store_pos
];
19763 for (i
=first_store_pos
; i
<*pn_ready
-1; i
++)
19764 ready
[i
] = ready
[i
+ 1];
19765 ready
[*pn_ready
-1] = tmp
;
19766 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
19767 INSN_PRIORITY (tmp
)++;
19770 else if (load_store_pendulum
== 2)
19772 /* Two loads have been issued in this cycle. Increase the priority
19773 of the first store in the ready list to favor it for issuing in
19779 if (is_store_insn (ready
[pos
])
19781 && INSN_PRIORITY_KNOWN (ready
[pos
]))
19783 INSN_PRIORITY (ready
[pos
])++;
19785 /* Adjust the pendulum to account for the fact that a store
19786 was found and increased in priority. This is to prevent
19787 increasing the priority of multiple stores */
19788 load_store_pendulum
++;
19797 return cached_can_issue_more
;
19800 /* Return whether the presence of INSN causes a dispatch group termination
19801 of group WHICH_GROUP.
19803 If WHICH_GROUP == current_group, this function will return true if INSN
19804 causes the termination of the current group (i.e, the dispatch group to
19805 which INSN belongs). This means that INSN will be the last insn in the
19806 group it belongs to.
19808 If WHICH_GROUP == previous_group, this function will return true if INSN
19809 causes the termination of the previous group (i.e, the dispatch group that
19810 precedes the group to which INSN belongs). This means that INSN will be
19811 the first insn in the group it belongs to). */
19814 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
19821 first
= insn_must_be_first_in_group (insn
);
19822 last
= insn_must_be_last_in_group (insn
);
19827 if (which_group
== current_group
)
19829 else if (which_group
== previous_group
)
19837 insn_must_be_first_in_group (rtx insn
)
19839 enum attr_type type
;
19842 || insn
== NULL_RTX
19843 || GET_CODE (insn
) == NOTE
19844 || GET_CODE (PATTERN (insn
)) == USE
19845 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19848 switch (rs6000_cpu
)
19850 case PROCESSOR_POWER5
:
19851 if (is_cracked_insn (insn
))
19853 case PROCESSOR_POWER4
:
19854 if (is_microcoded_insn (insn
))
19857 if (!rs6000_sched_groups
)
19860 type
= get_attr_type (insn
);
19867 case TYPE_DELAYED_CR
:
19868 case TYPE_CR_LOGICAL
:
19882 case PROCESSOR_POWER6
:
19883 type
= get_attr_type (insn
);
19887 case TYPE_INSERT_DWORD
:
19891 case TYPE_VAR_SHIFT_ROTATE
:
19898 case TYPE_INSERT_WORD
:
19899 case TYPE_DELAYED_COMPARE
:
19900 case TYPE_IMUL_COMPARE
:
19901 case TYPE_LMUL_COMPARE
:
19902 case TYPE_FPCOMPARE
:
19913 case TYPE_LOAD_EXT_UX
:
19915 case TYPE_STORE_UX
:
19916 case TYPE_FPLOAD_U
:
19917 case TYPE_FPLOAD_UX
:
19918 case TYPE_FPSTORE_U
:
19919 case TYPE_FPSTORE_UX
:
19933 insn_must_be_last_in_group (rtx insn
)
19935 enum attr_type type
;
19938 || insn
== NULL_RTX
19939 || GET_CODE (insn
) == NOTE
19940 || GET_CODE (PATTERN (insn
)) == USE
19941 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19944 switch (rs6000_cpu
) {
19945 case PROCESSOR_POWER4
:
19946 case PROCESSOR_POWER5
:
19947 if (is_microcoded_insn (insn
))
19950 if (is_branch_slot_insn (insn
))
19954 case PROCESSOR_POWER6
:
19955 type
= get_attr_type (insn
);
19962 case TYPE_VAR_SHIFT_ROTATE
:
19969 case TYPE_DELAYED_COMPARE
:
19970 case TYPE_IMUL_COMPARE
:
19971 case TYPE_LMUL_COMPARE
:
19972 case TYPE_FPCOMPARE
:
19993 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
19994 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
19997 is_costly_group (rtx
*group_insns
, rtx next_insn
)
20000 int issue_rate
= rs6000_issue_rate ();
20002 for (i
= 0; i
< issue_rate
; i
++)
20004 sd_iterator_def sd_it
;
20006 rtx insn
= group_insns
[i
];
20011 FOR_EACH_DEP (insn
, SD_LIST_FORW
, sd_it
, dep
)
20013 rtx next
= DEP_CON (dep
);
20015 if (next
== next_insn
20016 && rs6000_is_costly_dependence (dep
, dep_cost (dep
), 0))
20024 /* Utility of the function redefine_groups.
20025 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
20026 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
20027 to keep it "far" (in a separate group) from GROUP_INSNS, following
20028 one of the following schemes, depending on the value of the flag
20029 -minsert_sched_nops = X:
20030 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
20031 in order to force NEXT_INSN into a separate group.
20032 (2) X < sched_finish_regroup_exact: insert exactly X nops.
20033 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
20034 insertion (has a group just ended, how many vacant issue slots remain in the
20035 last group, and how many dispatch groups were encountered so far). */
20038 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
20039 rtx next_insn
, bool *group_end
, int can_issue_more
,
20044 int issue_rate
= rs6000_issue_rate ();
20045 bool end
= *group_end
;
20048 if (next_insn
== NULL_RTX
)
20049 return can_issue_more
;
20051 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
20052 return can_issue_more
;
20054 force
= is_costly_group (group_insns
, next_insn
);
20056 return can_issue_more
;
20058 if (sched_verbose
> 6)
20059 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
20060 *group_count
,can_issue_more
);
20062 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
20065 can_issue_more
= 0;
20067 /* Since only a branch can be issued in the last issue_slot, it is
20068 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
20069 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
20070 in this case the last nop will start a new group and the branch
20071 will be forced to the new group. */
20072 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
20075 while (can_issue_more
> 0)
20078 emit_insn_before (nop
, next_insn
);
20086 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
20088 int n_nops
= rs6000_sched_insert_nops
;
20090 /* Nops can't be issued from the branch slot, so the effective
20091 issue_rate for nops is 'issue_rate - 1'. */
20092 if (can_issue_more
== 0)
20093 can_issue_more
= issue_rate
;
20095 if (can_issue_more
== 0)
20097 can_issue_more
= issue_rate
- 1;
20100 for (i
= 0; i
< issue_rate
; i
++)
20102 group_insns
[i
] = 0;
20109 emit_insn_before (nop
, next_insn
);
20110 if (can_issue_more
== issue_rate
- 1) /* new group begins */
20113 if (can_issue_more
== 0)
20115 can_issue_more
= issue_rate
- 1;
20118 for (i
= 0; i
< issue_rate
; i
++)
20120 group_insns
[i
] = 0;
20126 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
20129 /* Is next_insn going to start a new group? */
20132 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
20133 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
20134 || (can_issue_more
< issue_rate
&&
20135 insn_terminates_group_p (next_insn
, previous_group
)));
20136 if (*group_end
&& end
)
20139 if (sched_verbose
> 6)
20140 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
20141 *group_count
, can_issue_more
);
20142 return can_issue_more
;
20145 return can_issue_more
;
20148 /* This function tries to synch the dispatch groups that the compiler "sees"
20149 with the dispatch groups that the processor dispatcher is expected to
20150 form in practice. It tries to achieve this synchronization by forcing the
20151 estimated processor grouping on the compiler (as opposed to the function
20152 'pad_goups' which tries to force the scheduler's grouping on the processor).
20154 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
20155 examines the (estimated) dispatch groups that will be formed by the processor
20156 dispatcher. It marks these group boundaries to reflect the estimated
20157 processor grouping, overriding the grouping that the scheduler had marked.
20158 Depending on the value of the flag '-minsert-sched-nops' this function can
20159 force certain insns into separate groups or force a certain distance between
20160 them by inserting nops, for example, if there exists a "costly dependence"
20163 The function estimates the group boundaries that the processor will form as
20164 follows: It keeps track of how many vacant issue slots are available after
20165 each insn. A subsequent insn will start a new group if one of the following
20167 - no more vacant issue slots remain in the current dispatch group.
20168 - only the last issue slot, which is the branch slot, is vacant, but the next
20169 insn is not a branch.
20170 - only the last 2 or less issue slots, including the branch slot, are vacant,
20171 which means that a cracked insn (which occupies two issue slots) can't be
20172 issued in this group.
20173 - less than 'issue_rate' slots are vacant, and the next insn always needs to
20174 start a new group. */
20177 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
20179 rtx insn
, next_insn
;
20181 int can_issue_more
;
20184 int group_count
= 0;
20188 issue_rate
= rs6000_issue_rate ();
20189 group_insns
= XALLOCAVEC (rtx
, issue_rate
);
20190 for (i
= 0; i
< issue_rate
; i
++)
20192 group_insns
[i
] = 0;
20194 can_issue_more
= issue_rate
;
20196 insn
= get_next_active_insn (prev_head_insn
, tail
);
20199 while (insn
!= NULL_RTX
)
20201 slot
= (issue_rate
- can_issue_more
);
20202 group_insns
[slot
] = insn
;
20204 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
20205 if (insn_terminates_group_p (insn
, current_group
))
20206 can_issue_more
= 0;
20208 next_insn
= get_next_active_insn (insn
, tail
);
20209 if (next_insn
== NULL_RTX
)
20210 return group_count
+ 1;
20212 /* Is next_insn going to start a new group? */
20214 = (can_issue_more
== 0
20215 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
20216 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
20217 || (can_issue_more
< issue_rate
&&
20218 insn_terminates_group_p (next_insn
, previous_group
)));
20220 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
20221 next_insn
, &group_end
, can_issue_more
,
20227 can_issue_more
= 0;
20228 for (i
= 0; i
< issue_rate
; i
++)
20230 group_insns
[i
] = 0;
20234 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
20235 PUT_MODE (next_insn
, VOIDmode
);
20236 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
20237 PUT_MODE (next_insn
, TImode
);
20240 if (can_issue_more
== 0)
20241 can_issue_more
= issue_rate
;
20244 return group_count
;
20247 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
20248 dispatch group boundaries that the scheduler had marked. Pad with nops
20249 any dispatch groups which have vacant issue slots, in order to force the
20250 scheduler's grouping on the processor dispatcher. The function
20251 returns the number of dispatch groups found. */
20254 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
20256 rtx insn
, next_insn
;
20259 int can_issue_more
;
20261 int group_count
= 0;
20263 /* Initialize issue_rate. */
20264 issue_rate
= rs6000_issue_rate ();
20265 can_issue_more
= issue_rate
;
20267 insn
= get_next_active_insn (prev_head_insn
, tail
);
20268 next_insn
= get_next_active_insn (insn
, tail
);
20270 while (insn
!= NULL_RTX
)
20273 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
20275 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
20277 if (next_insn
== NULL_RTX
)
20282 /* If the scheduler had marked group termination at this location
20283 (between insn and next_insn), and neither insn nor next_insn will
20284 force group termination, pad the group with nops to force group
20287 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
20288 && !insn_terminates_group_p (insn
, current_group
)
20289 && !insn_terminates_group_p (next_insn
, previous_group
))
20291 if (!is_branch_slot_insn (next_insn
))
20294 while (can_issue_more
)
20297 emit_insn_before (nop
, next_insn
);
20302 can_issue_more
= issue_rate
;
20307 next_insn
= get_next_active_insn (insn
, tail
);
20310 return group_count
;
20313 /* We're beginning a new block. Initialize data structures as necessary. */
20316 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED
,
20317 int sched_verbose ATTRIBUTE_UNUSED
,
20318 int max_ready ATTRIBUTE_UNUSED
)
20320 last_scheduled_insn
= NULL_RTX
;
20321 load_store_pendulum
= 0;
20324 /* The following function is called at the end of scheduling BB.
20325 After reload, it inserts nops at insn group bundling. */
20328 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
20333 fprintf (dump
, "=== Finishing schedule.\n");
20335 if (reload_completed
&& rs6000_sched_groups
)
20337 /* Do not run sched_finish hook when selective scheduling enabled. */
20338 if (sel_sched_p ())
20341 if (rs6000_sched_insert_nops
== sched_finish_none
)
20344 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
20345 n_groups
= pad_groups (dump
, sched_verbose
,
20346 current_sched_info
->prev_head
,
20347 current_sched_info
->next_tail
);
20349 n_groups
= redefine_groups (dump
, sched_verbose
,
20350 current_sched_info
->prev_head
,
20351 current_sched_info
->next_tail
);
20353 if (sched_verbose
>= 6)
20355 fprintf (dump
, "ngroups = %d\n", n_groups
);
20356 print_rtl (dump
, current_sched_info
->prev_head
);
20357 fprintf (dump
, "Done finish_sched\n");
20362 struct _rs6000_sched_context
20364 short cached_can_issue_more
;
20365 rtx last_scheduled_insn
;
20366 int load_store_pendulum
;
20369 typedef struct _rs6000_sched_context rs6000_sched_context_def
;
20370 typedef rs6000_sched_context_def
*rs6000_sched_context_t
;
20372 /* Allocate store for new scheduling context. */
20374 rs6000_alloc_sched_context (void)
20376 return xmalloc (sizeof (rs6000_sched_context_def
));
20379 /* If CLEAN_P is true then initializes _SC with clean data,
20380 and from the global context otherwise. */
20382 rs6000_init_sched_context (void *_sc
, bool clean_p
)
20384 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
20388 sc
->cached_can_issue_more
= 0;
20389 sc
->last_scheduled_insn
= NULL_RTX
;
20390 sc
->load_store_pendulum
= 0;
20394 sc
->cached_can_issue_more
= cached_can_issue_more
;
20395 sc
->last_scheduled_insn
= last_scheduled_insn
;
20396 sc
->load_store_pendulum
= load_store_pendulum
;
20400 /* Sets the global scheduling context to the one pointed to by _SC. */
20402 rs6000_set_sched_context (void *_sc
)
20404 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
20406 gcc_assert (sc
!= NULL
);
20408 cached_can_issue_more
= sc
->cached_can_issue_more
;
20409 last_scheduled_insn
= sc
->last_scheduled_insn
;
20410 load_store_pendulum
= sc
->load_store_pendulum
;
20415 rs6000_free_sched_context (void *_sc
)
20417 gcc_assert (_sc
!= NULL
);
20423 /* Length in units of the trampoline for entering a nested function. */
20426 rs6000_trampoline_size (void)
20430 switch (DEFAULT_ABI
)
20433 gcc_unreachable ();
20436 ret
= (TARGET_32BIT
) ? 12 : 24;
20441 ret
= (TARGET_32BIT
) ? 40 : 48;
20448 /* Emit RTL insns to initialize the variable parts of a trampoline.
20449 FNADDR is an RTX for the address of the function's pure code.
20450 CXT is an RTX for the static chain value for the function. */
20453 rs6000_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
20455 int regsize
= (TARGET_32BIT
) ? 4 : 8;
20456 rtx ctx_reg
= force_reg (Pmode
, cxt
);
20458 switch (DEFAULT_ABI
)
20461 gcc_unreachable ();
20463 /* Macros to shorten the code expansions below. */
20464 #define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
20465 #define MEM_PLUS(addr,offset) \
20466 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
20468 /* Under AIX, just build the 3 word function descriptor */
20471 rtx fn_reg
= gen_reg_rtx (Pmode
);
20472 rtx toc_reg
= gen_reg_rtx (Pmode
);
20473 emit_move_insn (fn_reg
, MEM_DEREF (fnaddr
));
20474 emit_move_insn (toc_reg
, MEM_PLUS (fnaddr
, regsize
));
20475 emit_move_insn (MEM_DEREF (addr
), fn_reg
);
20476 emit_move_insn (MEM_PLUS (addr
, regsize
), toc_reg
);
20477 emit_move_insn (MEM_PLUS (addr
, 2*regsize
), ctx_reg
);
20481 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
20484 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__trampoline_setup"),
20485 LCT_NORMAL
, VOIDmode
, 4,
20487 GEN_INT (rs6000_trampoline_size ()), SImode
,
20497 /* Table of valid machine attributes. */
20499 const struct attribute_spec rs6000_attribute_table
[] =
20501 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
20502 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
},
20503 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
20504 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
20505 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
20506 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
20507 #ifdef SUBTARGET_ATTRIBUTE_TABLE
20508 SUBTARGET_ATTRIBUTE_TABLE
,
20510 { NULL
, 0, 0, false, false, false, NULL
}
20513 /* Handle the "altivec" attribute. The attribute may have
20514 arguments as follows:
20516 __attribute__((altivec(vector__)))
20517 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
20518 __attribute__((altivec(bool__))) (always followed by 'unsigned')
20520 and may appear more than once (e.g., 'vector bool char') in a
20521 given declaration. */
20524 rs6000_handle_altivec_attribute (tree
*node
,
20525 tree name ATTRIBUTE_UNUSED
,
20527 int flags ATTRIBUTE_UNUSED
,
20528 bool *no_add_attrs
)
20530 tree type
= *node
, result
= NULL_TREE
;
20531 enum machine_mode mode
;
20534 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
20535 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
20536 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
20539 while (POINTER_TYPE_P (type
)
20540 || TREE_CODE (type
) == FUNCTION_TYPE
20541 || TREE_CODE (type
) == METHOD_TYPE
20542 || TREE_CODE (type
) == ARRAY_TYPE
)
20543 type
= TREE_TYPE (type
);
20545 mode
= TYPE_MODE (type
);
20547 /* Check for invalid AltiVec type qualifiers. */
20548 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
20551 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
20552 else if (rs6000_warn_altivec_long
)
20553 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
20555 else if (type
== long_long_unsigned_type_node
20556 || type
== long_long_integer_type_node
)
20557 error ("use of %<long long%> in AltiVec types is invalid");
20558 else if (type
== double_type_node
)
20559 error ("use of %<double%> in AltiVec types is invalid");
20560 else if (type
== long_double_type_node
)
20561 error ("use of %<long double%> in AltiVec types is invalid");
20562 else if (type
== boolean_type_node
)
20563 error ("use of boolean types in AltiVec types is invalid");
20564 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
20565 error ("use of %<complex%> in AltiVec types is invalid");
20566 else if (DECIMAL_FLOAT_MODE_P (mode
))
20567 error ("use of decimal floating point types in AltiVec types is invalid");
20569 switch (altivec_type
)
20572 unsigned_p
= TYPE_UNSIGNED (type
);
20576 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
20579 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
20582 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
20584 case SFmode
: result
= V4SF_type_node
; break;
20585 /* If the user says 'vector int bool', we may be handed the 'bool'
20586 attribute _before_ the 'vector' attribute, and so select the
20587 proper type in the 'b' case below. */
20588 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
20596 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
20597 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
20598 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
20605 case V8HImode
: result
= pixel_V8HI_type_node
;
20611 /* Propagate qualifiers attached to the element type
20612 onto the vector type. */
20613 if (result
&& result
!= type
&& TYPE_QUALS (type
))
20614 result
= build_qualified_type (result
, TYPE_QUALS (type
));
20616 *no_add_attrs
= true; /* No need to hang on to the attribute. */
20619 *node
= lang_hooks
.types
.reconstruct_complex_type (*node
, result
);
20624 /* AltiVec defines four built-in scalar types that serve as vector
20625 elements; we must teach the compiler how to mangle them. */
20627 static const char *
20628 rs6000_mangle_type (const_tree type
)
20630 type
= TYPE_MAIN_VARIANT (type
);
20632 if (TREE_CODE (type
) != VOID_TYPE
&& TREE_CODE (type
) != BOOLEAN_TYPE
20633 && TREE_CODE (type
) != INTEGER_TYPE
&& TREE_CODE (type
) != REAL_TYPE
)
20636 if (type
== bool_char_type_node
) return "U6__boolc";
20637 if (type
== bool_short_type_node
) return "U6__bools";
20638 if (type
== pixel_type_node
) return "u7__pixel";
20639 if (type
== bool_int_type_node
) return "U6__booli";
20641 /* Mangle IBM extended float long double as `g' (__float128) on
20642 powerpc*-linux where long-double-64 previously was the default. */
20643 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
20645 && TARGET_LONG_DOUBLE_128
20646 && !TARGET_IEEEQUAD
)
20649 /* For all other types, use normal C++ mangling. */
20653 /* Handle a "longcall" or "shortcall" attribute; arguments as in
20654 struct attribute_spec.handler. */
20657 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
20658 tree args ATTRIBUTE_UNUSED
,
20659 int flags ATTRIBUTE_UNUSED
,
20660 bool *no_add_attrs
)
20662 if (TREE_CODE (*node
) != FUNCTION_TYPE
20663 && TREE_CODE (*node
) != FIELD_DECL
20664 && TREE_CODE (*node
) != TYPE_DECL
)
20666 warning (OPT_Wattributes
, "%qs attribute only applies to functions",
20667 IDENTIFIER_POINTER (name
));
20668 *no_add_attrs
= true;
20674 /* Set longcall attributes on all functions declared when
20675 rs6000_default_long_calls is true. */
20677 rs6000_set_default_type_attributes (tree type
)
20679 if (rs6000_default_long_calls
20680 && (TREE_CODE (type
) == FUNCTION_TYPE
20681 || TREE_CODE (type
) == METHOD_TYPE
))
20682 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
20684 TYPE_ATTRIBUTES (type
));
20687 darwin_set_default_type_attributes (type
);
20691 /* Return a reference suitable for calling a function with the
20692 longcall attribute. */
20695 rs6000_longcall_ref (rtx call_ref
)
20697 const char *call_name
;
20700 if (GET_CODE (call_ref
) != SYMBOL_REF
)
20703 /* System V adds '.' to the internal name, so skip them. */
20704 call_name
= XSTR (call_ref
, 0);
20705 if (*call_name
== '.')
20707 while (*call_name
== '.')
20710 node
= get_identifier (call_name
);
20711 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
20714 return force_reg (Pmode
, call_ref
);
20717 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
20718 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
20721 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
20722 struct attribute_spec.handler. */
20724 rs6000_handle_struct_attribute (tree
*node
, tree name
,
20725 tree args ATTRIBUTE_UNUSED
,
20726 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
20729 if (DECL_P (*node
))
20731 if (TREE_CODE (*node
) == TYPE_DECL
)
20732 type
= &TREE_TYPE (*node
);
20737 if (!(type
&& (TREE_CODE (*type
) == RECORD_TYPE
20738 || TREE_CODE (*type
) == UNION_TYPE
)))
20740 warning (OPT_Wattributes
, "%qs attribute ignored", IDENTIFIER_POINTER (name
));
20741 *no_add_attrs
= true;
20744 else if ((is_attribute_p ("ms_struct", name
)
20745 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type
)))
20746 || ((is_attribute_p ("gcc_struct", name
)
20747 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type
)))))
20749 warning (OPT_Wattributes
, "%qs incompatible attribute ignored",
20750 IDENTIFIER_POINTER (name
));
20751 *no_add_attrs
= true;
20758 rs6000_ms_bitfield_layout_p (const_tree record_type
)
20760 return (TARGET_USE_MS_BITFIELD_LAYOUT
&&
20761 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type
)))
20762 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type
));
20765 #ifdef USING_ELFOS_H
20767 /* A get_unnamed_section callback, used for switching to toc_section. */
20770 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
20772 if (DEFAULT_ABI
== ABI_AIX
20773 && TARGET_MINIMAL_TOC
20774 && !TARGET_RELOCATABLE
)
20776 if (!toc_initialized
)
20778 toc_initialized
= 1;
20779 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
20780 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LCTOC", 0);
20781 fprintf (asm_out_file
, "\t.tc ");
20782 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1[TC],");
20783 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
20784 fprintf (asm_out_file
, "\n");
20786 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
20787 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
20788 fprintf (asm_out_file
, " = .+32768\n");
20791 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
20793 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_RELOCATABLE
)
20794 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
20797 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
20798 if (!toc_initialized
)
20800 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
20801 fprintf (asm_out_file
, " = .+32768\n");
20802 toc_initialized
= 1;
20807 /* Implement TARGET_ASM_INIT_SECTIONS. */
20810 rs6000_elf_asm_init_sections (void)
20813 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op
, NULL
);
20816 = get_unnamed_section (SECTION_WRITE
, output_section_asm_op
,
20817 SDATA2_SECTION_ASM_OP
);
20820 /* Implement TARGET_SELECT_RTX_SECTION. */
20823 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
20824 unsigned HOST_WIDE_INT align
)
20826 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
20827 return toc_section
;
20829 return default_elf_select_rtx_section (mode
, x
, align
);
20832 /* For a SYMBOL_REF, set generic flags and then perform some
20833 target-specific processing.
20835 When the AIX ABI is requested on a non-AIX system, replace the
20836 function name with the real name (with a leading .) rather than the
20837 function descriptor name. This saves a lot of overriding code to
20838 read the prefixes. */
20841 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
20843 default_encode_section_info (decl
, rtl
, first
);
20846 && TREE_CODE (decl
) == FUNCTION_DECL
20848 && DEFAULT_ABI
== ABI_AIX
)
20850 rtx sym_ref
= XEXP (rtl
, 0);
20851 size_t len
= strlen (XSTR (sym_ref
, 0));
20852 char *str
= XALLOCAVEC (char, len
+ 2);
20854 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
20855 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
20860 compare_section_name (const char *section
, const char *templ
)
20864 len
= strlen (templ
);
20865 return (strncmp (section
, templ
, len
) == 0
20866 && (section
[len
] == 0 || section
[len
] == '.'));
20870 rs6000_elf_in_small_data_p (const_tree decl
)
20872 if (rs6000_sdata
== SDATA_NONE
)
20875 /* We want to merge strings, so we never consider them small data. */
20876 if (TREE_CODE (decl
) == STRING_CST
)
20879 /* Functions are never in the small data area. */
20880 if (TREE_CODE (decl
) == FUNCTION_DECL
)
20883 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
20885 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
20886 if (compare_section_name (section
, ".sdata")
20887 || compare_section_name (section
, ".sdata2")
20888 || compare_section_name (section
, ".gnu.linkonce.s")
20889 || compare_section_name (section
, ".sbss")
20890 || compare_section_name (section
, ".sbss2")
20891 || compare_section_name (section
, ".gnu.linkonce.sb")
20892 || strcmp (section
, ".PPC.EMB.sdata0") == 0
20893 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
20898 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
20901 && (unsigned HOST_WIDE_INT
) size
<= g_switch_value
20902 /* If it's not public, and we're not going to reference it there,
20903 there's no need to put it in the small data section. */
20904 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
20911 #endif /* USING_ELFOS_H */
20913 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
20916 rs6000_use_blocks_for_constant_p (enum machine_mode mode
, const_rtx x
)
20918 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
);
20921 /* Return a REG that occurs in ADDR with coefficient 1.
20922 ADDR can be effectively incremented by incrementing REG.
20924 r0 is special and we must not select it as an address
20925 register by this routine since our caller will try to
20926 increment the returned register via an "la" instruction. */
20929 find_addr_reg (rtx addr
)
20931 while (GET_CODE (addr
) == PLUS
)
20933 if (GET_CODE (XEXP (addr
, 0)) == REG
20934 && REGNO (XEXP (addr
, 0)) != 0)
20935 addr
= XEXP (addr
, 0);
20936 else if (GET_CODE (XEXP (addr
, 1)) == REG
20937 && REGNO (XEXP (addr
, 1)) != 0)
20938 addr
= XEXP (addr
, 1);
20939 else if (CONSTANT_P (XEXP (addr
, 0)))
20940 addr
= XEXP (addr
, 1);
20941 else if (CONSTANT_P (XEXP (addr
, 1)))
20942 addr
= XEXP (addr
, 0);
20944 gcc_unreachable ();
20946 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
20951 rs6000_fatal_bad_address (rtx op
)
20953 fatal_insn ("bad address", op
);
20958 static tree branch_island_list
= 0;
20960 /* Remember to generate a branch island for far calls to the given
20964 add_compiler_branch_island (tree label_name
, tree function_name
,
20967 tree branch_island
= build_tree_list (function_name
, label_name
);
20968 TREE_TYPE (branch_island
) = build_int_cst (NULL_TREE
, line_number
);
20969 TREE_CHAIN (branch_island
) = branch_island_list
;
20970 branch_island_list
= branch_island
;
20973 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
20974 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
20975 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
20976 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
20978 /* Generate far-jump branch islands for everything on the
20979 branch_island_list. Invoked immediately after the last instruction
20980 of the epilogue has been emitted; the branch-islands must be
20981 appended to, and contiguous with, the function body. Mach-O stubs
20982 are generated in machopic_output_stub(). */
20985 macho_branch_islands (void)
20988 tree branch_island
;
20990 for (branch_island
= branch_island_list
;
20992 branch_island
= TREE_CHAIN (branch_island
))
20994 const char *label
=
20995 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island
));
20997 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island
));
20998 char name_buf
[512];
20999 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
21000 if (name
[0] == '*' || name
[0] == '&')
21001 strcpy (name_buf
, name
+1);
21005 strcpy (name_buf
+1, name
);
21007 strcpy (tmp_buf
, "\n");
21008 strcat (tmp_buf
, label
);
21009 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
21010 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
21011 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
21012 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
21015 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
21016 strcat (tmp_buf
, label
);
21017 strcat (tmp_buf
, "_pic\n");
21018 strcat (tmp_buf
, label
);
21019 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
21021 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
21022 strcat (tmp_buf
, name_buf
);
21023 strcat (tmp_buf
, " - ");
21024 strcat (tmp_buf
, label
);
21025 strcat (tmp_buf
, "_pic)\n");
21027 strcat (tmp_buf
, "\tmtlr r0\n");
21029 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
21030 strcat (tmp_buf
, name_buf
);
21031 strcat (tmp_buf
, " - ");
21032 strcat (tmp_buf
, label
);
21033 strcat (tmp_buf
, "_pic)\n");
21035 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
21039 strcat (tmp_buf
, ":\nlis r12,hi16(");
21040 strcat (tmp_buf
, name_buf
);
21041 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
21042 strcat (tmp_buf
, name_buf
);
21043 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
21045 output_asm_insn (tmp_buf
, 0);
21046 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
21047 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
21048 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
21049 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
21052 branch_island_list
= 0;
21055 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
21056 already there or not. */
21059 no_previous_def (tree function_name
)
21061 tree branch_island
;
21062 for (branch_island
= branch_island_list
;
21064 branch_island
= TREE_CHAIN (branch_island
))
21065 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
21070 /* GET_PREV_LABEL gets the label name from the previous definition of
21074 get_prev_label (tree function_name
)
21076 tree branch_island
;
21077 for (branch_island
= branch_island_list
;
21079 branch_island
= TREE_CHAIN (branch_island
))
21080 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
21081 return BRANCH_ISLAND_LABEL_NAME (branch_island
);
21085 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
21086 #define DARWIN_LINKER_GENERATES_ISLANDS 0
21089 /* KEXTs still need branch islands. */
21090 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
21091 || flag_mkernel || flag_apple_kext)
21093 /* INSN is either a function call or a millicode call. It may have an
21094 unconditional jump in its delay slot.
21096 CALL_DEST is the routine we are calling. */
21099 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
21100 int cookie_operand_number
)
21102 static char buf
[256];
21103 if (DARWIN_GENERATE_ISLANDS
21104 && GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
21105 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
21108 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
21110 if (no_previous_def (funname
))
21112 rtx label_rtx
= gen_label_rtx ();
21113 char *label_buf
, temp_buf
[256];
21114 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
21115 CODE_LABEL_NUMBER (label_rtx
));
21116 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
21117 labelname
= get_identifier (label_buf
);
21118 add_compiler_branch_island (labelname
, funname
, insn_line (insn
));
21121 labelname
= get_prev_label (funname
);
21123 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
21124 instruction will reach 'foo', otherwise link as 'bl L42'".
21125 "L42" should be a 'branch island', that will do a far jump to
21126 'foo'. Branch islands are generated in
21127 macho_branch_islands(). */
21128 sprintf (buf
, "jbsr %%z%d,%.246s",
21129 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
21132 sprintf (buf
, "bl %%z%d", dest_operand_number
);
21136 /* Generate PIC and indirect symbol stubs. */
21139 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
21141 unsigned int length
;
21142 char *symbol_name
, *lazy_ptr_name
;
21143 char *local_label_0
;
21144 static int label
= 0;
21146 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
21147 symb
= (*targetm
.strip_name_encoding
) (symb
);
21150 length
= strlen (symb
);
21151 symbol_name
= XALLOCAVEC (char, length
+ 32);
21152 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
21154 lazy_ptr_name
= XALLOCAVEC (char, length
+ 32);
21155 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
21158 switch_to_section (darwin_sections
[machopic_picsymbol_stub1_section
]);
21160 switch_to_section (darwin_sections
[machopic_symbol_stub1_section
]);
21164 fprintf (file
, "\t.align 5\n");
21166 fprintf (file
, "%s:\n", stub
);
21167 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
21170 local_label_0
= XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
21171 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
21173 fprintf (file
, "\tmflr r0\n");
21174 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
21175 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
21176 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
21177 lazy_ptr_name
, local_label_0
);
21178 fprintf (file
, "\tmtlr r0\n");
21179 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
21180 (TARGET_64BIT
? "ldu" : "lwzu"),
21181 lazy_ptr_name
, local_label_0
);
21182 fprintf (file
, "\tmtctr r12\n");
21183 fprintf (file
, "\tbctr\n");
21187 fprintf (file
, "\t.align 4\n");
21189 fprintf (file
, "%s:\n", stub
);
21190 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
21192 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
21193 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
21194 (TARGET_64BIT
? "ldu" : "lwzu"),
21196 fprintf (file
, "\tmtctr r12\n");
21197 fprintf (file
, "\tbctr\n");
21200 switch_to_section (darwin_sections
[machopic_lazy_symbol_ptr_section
]);
21201 fprintf (file
, "%s:\n", lazy_ptr_name
);
21202 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
21203 fprintf (file
, "%sdyld_stub_binding_helper\n",
21204 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
21207 /* Legitimize PIC addresses. If the address is already
21208 position-independent, we return ORIG. Newly generated
21209 position-independent addresses go into a reg. This is REG if non
21210 zero, otherwise we allocate register(s) as necessary. */
21212 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
21215 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
21220 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
21221 reg
= gen_reg_rtx (Pmode
);
21223 if (GET_CODE (orig
) == CONST
)
21227 if (GET_CODE (XEXP (orig
, 0)) == PLUS
21228 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
21231 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
21233 /* Use a different reg for the intermediate value, as
21234 it will be marked UNCHANGING. */
21235 reg_temp
= !can_create_pseudo_p () ? reg
: gen_reg_rtx (Pmode
);
21236 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
21239 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
21242 if (GET_CODE (offset
) == CONST_INT
)
21244 if (SMALL_INT (offset
))
21245 return plus_constant (base
, INTVAL (offset
));
21246 else if (! reload_in_progress
&& ! reload_completed
)
21247 offset
= force_reg (Pmode
, offset
);
21250 rtx mem
= force_const_mem (Pmode
, orig
);
21251 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
21254 return gen_rtx_PLUS (Pmode
, base
, offset
);
21257 /* Fall back on generic machopic code. */
21258 return machopic_legitimize_pic_address (orig
, mode
, reg
);
21261 /* Output a .machine directive for the Darwin assembler, and call
21262 the generic start_file routine. */
21265 rs6000_darwin_file_start (void)
21267 static const struct
21273 { "ppc64", "ppc64", MASK_64BIT
},
21274 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
21275 { "power4", "ppc970", 0 },
21276 { "G5", "ppc970", 0 },
21277 { "7450", "ppc7450", 0 },
21278 { "7400", "ppc7400", MASK_ALTIVEC
},
21279 { "G4", "ppc7400", 0 },
21280 { "750", "ppc750", 0 },
21281 { "740", "ppc750", 0 },
21282 { "G3", "ppc750", 0 },
21283 { "604e", "ppc604e", 0 },
21284 { "604", "ppc604", 0 },
21285 { "603e", "ppc603", 0 },
21286 { "603", "ppc603", 0 },
21287 { "601", "ppc601", 0 },
21288 { NULL
, "ppc", 0 } };
21289 const char *cpu_id
= "";
21292 rs6000_file_start ();
21293 darwin_file_start ();
21295 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
21296 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
21297 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
21298 && rs6000_select
[i
].string
[0] != '\0')
21299 cpu_id
= rs6000_select
[i
].string
;
21301 /* Look through the mapping array. Pick the first name that either
21302 matches the argument, has a bit set in IF_SET that is also set
21303 in the target flags, or has a NULL name. */
21306 while (mapping
[i
].arg
!= NULL
21307 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
21308 && (mapping
[i
].if_set
& target_flags
) == 0)
21311 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
21314 #endif /* TARGET_MACHO */
21318 rs6000_elf_reloc_rw_mask (void)
21322 else if (DEFAULT_ABI
== ABI_AIX
)
21328 /* Record an element in the table of global constructors. SYMBOL is
21329 a SYMBOL_REF of the function to be called; PRIORITY is a number
21330 between 0 and MAX_INIT_PRIORITY.
21332 This differs from default_named_section_asm_out_constructor in
21333 that we have special handling for -mrelocatable. */
21336 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
21338 const char *section
= ".ctors";
21341 if (priority
!= DEFAULT_INIT_PRIORITY
)
21343 sprintf (buf
, ".ctors.%.5u",
21344 /* Invert the numbering so the linker puts us in the proper
21345 order; constructors are run from right to left, and the
21346 linker sorts in increasing order. */
21347 MAX_INIT_PRIORITY
- priority
);
21351 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
21352 assemble_align (POINTER_SIZE
);
21354 if (TARGET_RELOCATABLE
)
21356 fputs ("\t.long (", asm_out_file
);
21357 output_addr_const (asm_out_file
, symbol
);
21358 fputs (")@fixup\n", asm_out_file
);
21361 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
21365 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
21367 const char *section
= ".dtors";
21370 if (priority
!= DEFAULT_INIT_PRIORITY
)
21372 sprintf (buf
, ".dtors.%.5u",
21373 /* Invert the numbering so the linker puts us in the proper
21374 order; constructors are run from right to left, and the
21375 linker sorts in increasing order. */
21376 MAX_INIT_PRIORITY
- priority
);
21380 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
21381 assemble_align (POINTER_SIZE
);
21383 if (TARGET_RELOCATABLE
)
21385 fputs ("\t.long (", asm_out_file
);
21386 output_addr_const (asm_out_file
, symbol
);
21387 fputs (")@fixup\n", asm_out_file
);
21390 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
21394 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
21398 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
21399 ASM_OUTPUT_LABEL (file
, name
);
21400 fputs (DOUBLE_INT_ASM_OP
, file
);
21401 rs6000_output_function_entry (file
, name
);
21402 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
21405 fputs ("\t.size\t", file
);
21406 assemble_name (file
, name
);
21407 fputs (",24\n\t.type\t.", file
);
21408 assemble_name (file
, name
);
21409 fputs (",@function\n", file
);
21410 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
21412 fputs ("\t.globl\t.", file
);
21413 assemble_name (file
, name
);
21418 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
21419 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
21420 rs6000_output_function_entry (file
, name
);
21421 fputs (":\n", file
);
21425 if (TARGET_RELOCATABLE
21426 && !TARGET_SECURE_PLT
21427 && (get_pool_size () != 0 || crtl
->profile
)
21432 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
21434 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
21435 fprintf (file
, "\t.long ");
21436 assemble_name (file
, buf
);
21438 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
21439 assemble_name (file
, buf
);
21443 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
21444 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
21446 if (DEFAULT_ABI
== ABI_AIX
)
21448 const char *desc_name
, *orig_name
;
21450 orig_name
= (*targetm
.strip_name_encoding
) (name
);
21451 desc_name
= orig_name
;
21452 while (*desc_name
== '.')
21455 if (TREE_PUBLIC (decl
))
21456 fprintf (file
, "\t.globl %s\n", desc_name
);
21458 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
21459 fprintf (file
, "%s:\n", desc_name
);
21460 fprintf (file
, "\t.long %s\n", orig_name
);
21461 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
21462 if (DEFAULT_ABI
== ABI_AIX
)
21463 fputs ("\t.long 0\n", file
);
21464 fprintf (file
, "\t.previous\n");
21466 ASM_OUTPUT_LABEL (file
, name
);
21470 rs6000_elf_end_indicate_exec_stack (void)
21473 file_end_indicate_exec_stack ();
21479 rs6000_xcoff_asm_output_anchor (rtx symbol
)
21483 sprintf (buffer
, "$ + " HOST_WIDE_INT_PRINT_DEC
,
21484 SYMBOL_REF_BLOCK_OFFSET (symbol
));
21485 ASM_OUTPUT_DEF (asm_out_file
, XSTR (symbol
, 0), buffer
);
21489 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
21491 fputs (GLOBAL_ASM_OP
, stream
);
21492 RS6000_OUTPUT_BASENAME (stream
, name
);
21493 putc ('\n', stream
);
21496 /* A get_unnamed_decl callback, used for read-only sections. PTR
21497 points to the section string variable. */
21500 rs6000_xcoff_output_readonly_section_asm_op (const void *directive
)
21502 fprintf (asm_out_file
, "\t.csect %s[RO],%s\n",
21503 *(const char *const *) directive
,
21504 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
21507 /* Likewise for read-write sections. */
21510 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive
)
21512 fprintf (asm_out_file
, "\t.csect %s[RW],%s\n",
21513 *(const char *const *) directive
,
21514 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
21517 /* A get_unnamed_section callback, used for switching to toc_section. */
21520 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
21522 if (TARGET_MINIMAL_TOC
)
21524 /* toc_section is always selected at least once from
21525 rs6000_xcoff_file_start, so this is guaranteed to
21526 always be defined once and only once in each file. */
21527 if (!toc_initialized
)
21529 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file
);
21530 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file
);
21531 toc_initialized
= 1;
21533 fprintf (asm_out_file
, "\t.csect toc_table[RW]%s\n",
21534 (TARGET_32BIT
? "" : ",3"));
21537 fputs ("\t.toc\n", asm_out_file
);
21540 /* Implement TARGET_ASM_INIT_SECTIONS. */
21543 rs6000_xcoff_asm_init_sections (void)
21545 read_only_data_section
21546 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
21547 &xcoff_read_only_section_name
);
21549 private_data_section
21550 = get_unnamed_section (SECTION_WRITE
,
21551 rs6000_xcoff_output_readwrite_section_asm_op
,
21552 &xcoff_private_data_section_name
);
21554 read_only_private_data_section
21555 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
21556 &xcoff_private_data_section_name
);
21559 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op
, NULL
);
21561 readonly_data_section
= read_only_data_section
;
21562 exception_section
= data_section
;
21566 rs6000_xcoff_reloc_rw_mask (void)
21572 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
21573 tree decl ATTRIBUTE_UNUSED
)
21576 static const char * const suffix
[3] = { "PR", "RO", "RW" };
21578 if (flags
& SECTION_CODE
)
21580 else if (flags
& SECTION_WRITE
)
21585 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
21586 (flags
& SECTION_CODE
) ? "." : "",
21587 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
21591 rs6000_xcoff_select_section (tree decl
, int reloc
,
21592 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
21594 if (decl_readonly_section (decl
, reloc
))
21596 if (TREE_PUBLIC (decl
))
21597 return read_only_data_section
;
21599 return read_only_private_data_section
;
21603 if (TREE_PUBLIC (decl
))
21604 return data_section
;
21606 return private_data_section
;
21611 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
21615 /* Use select_section for private and uninitialized data. */
21616 if (!TREE_PUBLIC (decl
)
21617 || DECL_COMMON (decl
)
21618 || DECL_INITIAL (decl
) == NULL_TREE
21619 || DECL_INITIAL (decl
) == error_mark_node
21620 || (flag_zero_initialized_in_bss
21621 && initializer_zerop (DECL_INITIAL (decl
))))
21624 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
21625 name
= (*targetm
.strip_name_encoding
) (name
);
21626 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
21629 /* Select section for constant in constant pool.
21631 On RS/6000, all constants are in the private read-only data area.
21632 However, if this is being placed in the TOC it must be output as a
21636 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
21637 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
21639 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
21640 return toc_section
;
21642 return read_only_private_data_section
;
21645 /* Remove any trailing [DS] or the like from the symbol name. */
21647 static const char *
21648 rs6000_xcoff_strip_name_encoding (const char *name
)
21653 len
= strlen (name
);
21654 if (name
[len
- 1] == ']')
21655 return ggc_alloc_string (name
, len
- 4);
21660 /* Section attributes. AIX is always PIC. */
21662 static unsigned int
21663 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
21665 unsigned int align
;
21666 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
21668 /* Align to at least UNIT size. */
21669 if (flags
& SECTION_CODE
)
21670 align
= MIN_UNITS_PER_WORD
;
21672 /* Increase alignment of large objects if not already stricter. */
21673 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
21674 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
21675 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
21677 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
21680 /* Output at beginning of assembler file.
21682 Initialize the section names for the RS/6000 at this point.
21684 Specify filename, including full path, to assembler.
21686 We want to go into the TOC section so at least one .toc will be emitted.
21687 Also, in order to output proper .bs/.es pairs, we need at least one static
21688 [RW] section emitted.
21690 Finally, declare mcount when profiling to make the assembler happy. */
21693 rs6000_xcoff_file_start (void)
21695 rs6000_gen_section_name (&xcoff_bss_section_name
,
21696 main_input_filename
, ".bss_");
21697 rs6000_gen_section_name (&xcoff_private_data_section_name
,
21698 main_input_filename
, ".rw_");
21699 rs6000_gen_section_name (&xcoff_read_only_section_name
,
21700 main_input_filename
, ".ro_");
21702 fputs ("\t.file\t", asm_out_file
);
21703 output_quoted_string (asm_out_file
, main_input_filename
);
21704 fputc ('\n', asm_out_file
);
21705 if (write_symbols
!= NO_DEBUG
)
21706 switch_to_section (private_data_section
);
21707 switch_to_section (text_section
);
21709 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
21710 rs6000_file_start ();
21713 /* Output at end of assembler file.
21714 On the RS/6000, referencing data should automatically pull in text. */
21717 rs6000_xcoff_file_end (void)
21719 switch_to_section (text_section
);
21720 fputs ("_section_.text:\n", asm_out_file
);
21721 switch_to_section (data_section
);
21722 fputs (TARGET_32BIT
21723 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
21726 #endif /* TARGET_XCOFF */
21728 /* Compute a (partial) cost for rtx X. Return true if the complete
21729 cost has been computed, and false if subexpressions should be
21730 scanned. In either case, *TOTAL contains the cost result. */
21733 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
21736 enum machine_mode mode
= GET_MODE (x
);
21740 /* On the RS/6000, if it is valid in the insn, it is free. */
21742 if (((outer_code
== SET
21743 || outer_code
== PLUS
21744 || outer_code
== MINUS
)
21745 && (satisfies_constraint_I (x
)
21746 || satisfies_constraint_L (x
)))
21747 || (outer_code
== AND
21748 && (satisfies_constraint_K (x
)
21750 ? satisfies_constraint_L (x
)
21751 : satisfies_constraint_J (x
))
21752 || mask_operand (x
, mode
)
21754 && mask64_operand (x
, DImode
))))
21755 || ((outer_code
== IOR
|| outer_code
== XOR
)
21756 && (satisfies_constraint_K (x
)
21758 ? satisfies_constraint_L (x
)
21759 : satisfies_constraint_J (x
))))
21760 || outer_code
== ASHIFT
21761 || outer_code
== ASHIFTRT
21762 || outer_code
== LSHIFTRT
21763 || outer_code
== ROTATE
21764 || outer_code
== ROTATERT
21765 || outer_code
== ZERO_EXTRACT
21766 || (outer_code
== MULT
21767 && satisfies_constraint_I (x
))
21768 || ((outer_code
== DIV
|| outer_code
== UDIV
21769 || outer_code
== MOD
|| outer_code
== UMOD
)
21770 && exact_log2 (INTVAL (x
)) >= 0)
21771 || (outer_code
== COMPARE
21772 && (satisfies_constraint_I (x
)
21773 || satisfies_constraint_K (x
)))
21774 || (outer_code
== EQ
21775 && (satisfies_constraint_I (x
)
21776 || satisfies_constraint_K (x
)
21778 ? satisfies_constraint_L (x
)
21779 : satisfies_constraint_J (x
))))
21780 || (outer_code
== GTU
21781 && satisfies_constraint_I (x
))
21782 || (outer_code
== LTU
21783 && satisfies_constraint_P (x
)))
21788 else if ((outer_code
== PLUS
21789 && reg_or_add_cint_operand (x
, VOIDmode
))
21790 || (outer_code
== MINUS
21791 && reg_or_sub_cint_operand (x
, VOIDmode
))
21792 || ((outer_code
== SET
21793 || outer_code
== IOR
21794 || outer_code
== XOR
)
21796 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
21798 *total
= COSTS_N_INSNS (1);
21804 if (mode
== DImode
&& code
== CONST_DOUBLE
)
21806 if ((outer_code
== IOR
|| outer_code
== XOR
)
21807 && CONST_DOUBLE_HIGH (x
) == 0
21808 && (CONST_DOUBLE_LOW (x
)
21809 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)
21814 else if ((outer_code
== AND
&& and64_2_operand (x
, DImode
))
21815 || ((outer_code
== SET
21816 || outer_code
== IOR
21817 || outer_code
== XOR
)
21818 && CONST_DOUBLE_HIGH (x
) == 0))
21820 *total
= COSTS_N_INSNS (1);
21830 /* When optimizing for size, MEM should be slightly more expensive
21831 than generating address, e.g., (plus (reg) (const)).
21832 L1 cache latency is about two instructions. */
21833 *total
= !speed
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
21841 if (mode
== DFmode
)
21843 if (GET_CODE (XEXP (x
, 0)) == MULT
)
21845 /* FNMA accounted in outer NEG. */
21846 if (outer_code
== NEG
)
21847 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
21849 *total
= rs6000_cost
->dmul
;
21852 *total
= rs6000_cost
->fp
;
21854 else if (mode
== SFmode
)
21856 /* FNMA accounted in outer NEG. */
21857 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
21860 *total
= rs6000_cost
->fp
;
21863 *total
= COSTS_N_INSNS (1);
21867 if (mode
== DFmode
)
21869 if (GET_CODE (XEXP (x
, 0)) == MULT
21870 || GET_CODE (XEXP (x
, 1)) == MULT
)
21872 /* FNMA accounted in outer NEG. */
21873 if (outer_code
== NEG
)
21874 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
21876 *total
= rs6000_cost
->dmul
;
21879 *total
= rs6000_cost
->fp
;
21881 else if (mode
== SFmode
)
21883 /* FNMA accounted in outer NEG. */
21884 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
21887 *total
= rs6000_cost
->fp
;
21890 *total
= COSTS_N_INSNS (1);
21894 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
21895 && satisfies_constraint_I (XEXP (x
, 1)))
21897 if (INTVAL (XEXP (x
, 1)) >= -256
21898 && INTVAL (XEXP (x
, 1)) <= 255)
21899 *total
= rs6000_cost
->mulsi_const9
;
21901 *total
= rs6000_cost
->mulsi_const
;
21903 /* FMA accounted in outer PLUS/MINUS. */
21904 else if ((mode
== DFmode
|| mode
== SFmode
)
21905 && (outer_code
== PLUS
|| outer_code
== MINUS
))
21907 else if (mode
== DFmode
)
21908 *total
= rs6000_cost
->dmul
;
21909 else if (mode
== SFmode
)
21910 *total
= rs6000_cost
->fp
;
21911 else if (mode
== DImode
)
21912 *total
= rs6000_cost
->muldi
;
21914 *total
= rs6000_cost
->mulsi
;
21919 if (FLOAT_MODE_P (mode
))
21921 *total
= mode
== DFmode
? rs6000_cost
->ddiv
21922 : rs6000_cost
->sdiv
;
21929 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
21930 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
21932 if (code
== DIV
|| code
== MOD
)
21934 *total
= COSTS_N_INSNS (2);
21937 *total
= COSTS_N_INSNS (1);
21941 if (GET_MODE (XEXP (x
, 1)) == DImode
)
21942 *total
= rs6000_cost
->divdi
;
21944 *total
= rs6000_cost
->divsi
;
21946 /* Add in shift and subtract for MOD. */
21947 if (code
== MOD
|| code
== UMOD
)
21948 *total
+= COSTS_N_INSNS (2);
21953 *total
= COSTS_N_INSNS (4);
21957 *total
= COSTS_N_INSNS (6);
21961 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
21973 *total
= COSTS_N_INSNS (1);
21981 /* Handle mul_highpart. */
21982 if (outer_code
== TRUNCATE
21983 && GET_CODE (XEXP (x
, 0)) == MULT
)
21985 if (mode
== DImode
)
21986 *total
= rs6000_cost
->muldi
;
21988 *total
= rs6000_cost
->mulsi
;
21991 else if (outer_code
== AND
)
21994 *total
= COSTS_N_INSNS (1);
21999 if (GET_CODE (XEXP (x
, 0)) == MEM
)
22002 *total
= COSTS_N_INSNS (1);
22008 if (!FLOAT_MODE_P (mode
))
22010 *total
= COSTS_N_INSNS (1);
22016 case UNSIGNED_FLOAT
:
22019 case FLOAT_TRUNCATE
:
22020 *total
= rs6000_cost
->fp
;
22024 if (mode
== DFmode
)
22027 *total
= rs6000_cost
->fp
;
22031 switch (XINT (x
, 1))
22034 *total
= rs6000_cost
->fp
;
22046 *total
= COSTS_N_INSNS (1);
22049 else if (FLOAT_MODE_P (mode
)
22050 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
22052 *total
= rs6000_cost
->fp
;
22060 /* Carry bit requires mode == Pmode.
22061 NEG or PLUS already counted so only add one. */
22063 && (outer_code
== NEG
|| outer_code
== PLUS
))
22065 *total
= COSTS_N_INSNS (1);
22068 if (outer_code
== SET
)
22070 if (XEXP (x
, 1) == const0_rtx
)
22072 *total
= COSTS_N_INSNS (2);
22075 else if (mode
== Pmode
)
22077 *total
= COSTS_N_INSNS (3);
22086 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
22088 *total
= COSTS_N_INSNS (2);
22092 if (outer_code
== COMPARE
)
22106 /* A C expression returning the cost of moving data from a register of class
22107 CLASS1 to one of CLASS2. */
22110 rs6000_register_move_cost (enum machine_mode mode
,
22111 enum reg_class from
, enum reg_class to
)
22113 /* Moves from/to GENERAL_REGS. */
22114 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
22115 || reg_classes_intersect_p (from
, GENERAL_REGS
))
22117 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
22120 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
)
22121 return (rs6000_memory_move_cost (mode
, from
, 0)
22122 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, 0));
22124 /* It's more expensive to move CR_REGS than CR0_REGS because of the
22126 else if (from
== CR_REGS
)
22129 /* Power6 has slower LR/CTR moves so make them more expensive than
22130 memory in order to bias spills to memory .*/
22131 else if (rs6000_cpu
== PROCESSOR_POWER6
22132 && reg_classes_intersect_p (from
, LINK_OR_CTR_REGS
))
22133 return 6 * hard_regno_nregs
[0][mode
];
22136 /* A move will cost one instruction per GPR moved. */
22137 return 2 * hard_regno_nregs
[0][mode
];
22140 /* Moving between two similar registers is just one instruction. */
22141 else if (reg_classes_intersect_p (to
, from
))
22142 return (mode
== TFmode
|| mode
== TDmode
) ? 4 : 2;
22144 /* Everything else has to go through GENERAL_REGS. */
22146 return (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
22147 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
22150 /* A C expressions returning the cost of moving data of MODE from a register to
22154 rs6000_memory_move_cost (enum machine_mode mode
, enum reg_class rclass
,
22155 int in ATTRIBUTE_UNUSED
)
22157 if (reg_classes_intersect_p (rclass
, GENERAL_REGS
))
22158 return 4 * hard_regno_nregs
[0][mode
];
22159 else if (reg_classes_intersect_p (rclass
, FLOAT_REGS
))
22160 return 4 * hard_regno_nregs
[32][mode
];
22161 else if (reg_classes_intersect_p (rclass
, ALTIVEC_REGS
))
22162 return 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
22164 return 4 + rs6000_register_move_cost (mode
, rclass
, GENERAL_REGS
);
22167 /* Returns a code for a target-specific builtin that implements
22168 reciprocal of the function, or NULL_TREE if not available. */
22171 rs6000_builtin_reciprocal (unsigned int fn
, bool md_fn
,
22172 bool sqrt ATTRIBUTE_UNUSED
)
22174 if (! (TARGET_RECIP
&& TARGET_PPC_GFXOPT
&& !optimize_size
22175 && flag_finite_math_only
&& !flag_trapping_math
22176 && flag_unsafe_math_optimizations
))
22184 case BUILT_IN_SQRTF
:
22185 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRTF
];
22192 /* Newton-Raphson approximation of single-precision floating point divide n/d.
22193 Assumes no trapping math and finite arguments. */
22196 rs6000_emit_swdivsf (rtx dst
, rtx n
, rtx d
)
22198 rtx x0
, e0
, e1
, y1
, u0
, v0
, one
;
22200 x0
= gen_reg_rtx (SFmode
);
22201 e0
= gen_reg_rtx (SFmode
);
22202 e1
= gen_reg_rtx (SFmode
);
22203 y1
= gen_reg_rtx (SFmode
);
22204 u0
= gen_reg_rtx (SFmode
);
22205 v0
= gen_reg_rtx (SFmode
);
22206 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
22208 /* x0 = 1./d estimate */
22209 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
22210 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, d
),
22212 /* e0 = 1. - d * x0 */
22213 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
22214 gen_rtx_MINUS (SFmode
, one
,
22215 gen_rtx_MULT (SFmode
, d
, x0
))));
22216 /* e1 = e0 + e0 * e0 */
22217 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
22218 gen_rtx_PLUS (SFmode
,
22219 gen_rtx_MULT (SFmode
, e0
, e0
), e0
)));
22220 /* y1 = x0 + e1 * x0 */
22221 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
22222 gen_rtx_PLUS (SFmode
,
22223 gen_rtx_MULT (SFmode
, e1
, x0
), x0
)));
22225 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
22226 gen_rtx_MULT (SFmode
, n
, y1
)));
22227 /* v0 = n - d * u0 */
22228 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
22229 gen_rtx_MINUS (SFmode
, n
,
22230 gen_rtx_MULT (SFmode
, d
, u0
))));
22231 /* dst = u0 + v0 * y1 */
22232 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
22233 gen_rtx_PLUS (SFmode
,
22234 gen_rtx_MULT (SFmode
, v0
, y1
), u0
)));
22237 /* Newton-Raphson approximation of double-precision floating point divide n/d.
22238 Assumes no trapping math and finite arguments. */
22241 rs6000_emit_swdivdf (rtx dst
, rtx n
, rtx d
)
22243 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
22245 x0
= gen_reg_rtx (DFmode
);
22246 e0
= gen_reg_rtx (DFmode
);
22247 e1
= gen_reg_rtx (DFmode
);
22248 e2
= gen_reg_rtx (DFmode
);
22249 y1
= gen_reg_rtx (DFmode
);
22250 y2
= gen_reg_rtx (DFmode
);
22251 y3
= gen_reg_rtx (DFmode
);
22252 u0
= gen_reg_rtx (DFmode
);
22253 v0
= gen_reg_rtx (DFmode
);
22254 one
= force_reg (DFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, DFmode
));
22256 /* x0 = 1./d estimate */
22257 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
22258 gen_rtx_UNSPEC (DFmode
, gen_rtvec (1, d
),
22260 /* e0 = 1. - d * x0 */
22261 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
22262 gen_rtx_MINUS (DFmode
, one
,
22263 gen_rtx_MULT (SFmode
, d
, x0
))));
22264 /* y1 = x0 + e0 * x0 */
22265 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
22266 gen_rtx_PLUS (DFmode
,
22267 gen_rtx_MULT (DFmode
, e0
, x0
), x0
)));
22269 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
22270 gen_rtx_MULT (DFmode
, e0
, e0
)));
22271 /* y2 = y1 + e1 * y1 */
22272 emit_insn (gen_rtx_SET (VOIDmode
, y2
,
22273 gen_rtx_PLUS (DFmode
,
22274 gen_rtx_MULT (DFmode
, e1
, y1
), y1
)));
22276 emit_insn (gen_rtx_SET (VOIDmode
, e2
,
22277 gen_rtx_MULT (DFmode
, e1
, e1
)));
22278 /* y3 = y2 + e2 * y2 */
22279 emit_insn (gen_rtx_SET (VOIDmode
, y3
,
22280 gen_rtx_PLUS (DFmode
,
22281 gen_rtx_MULT (DFmode
, e2
, y2
), y2
)));
22283 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
22284 gen_rtx_MULT (DFmode
, n
, y3
)));
22285 /* v0 = n - d * u0 */
22286 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
22287 gen_rtx_MINUS (DFmode
, n
,
22288 gen_rtx_MULT (DFmode
, d
, u0
))));
22289 /* dst = u0 + v0 * y3 */
22290 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
22291 gen_rtx_PLUS (DFmode
,
22292 gen_rtx_MULT (DFmode
, v0
, y3
), u0
)));
22296 /* Newton-Raphson approximation of single-precision floating point rsqrt.
22297 Assumes no trapping math and finite arguments. */
22300 rs6000_emit_swrsqrtsf (rtx dst
, rtx src
)
22302 rtx x0
, x1
, x2
, y1
, u0
, u1
, u2
, v0
, v1
, v2
, t0
,
22303 half
, one
, halfthree
, c1
, cond
, label
;
22305 x0
= gen_reg_rtx (SFmode
);
22306 x1
= gen_reg_rtx (SFmode
);
22307 x2
= gen_reg_rtx (SFmode
);
22308 y1
= gen_reg_rtx (SFmode
);
22309 u0
= gen_reg_rtx (SFmode
);
22310 u1
= gen_reg_rtx (SFmode
);
22311 u2
= gen_reg_rtx (SFmode
);
22312 v0
= gen_reg_rtx (SFmode
);
22313 v1
= gen_reg_rtx (SFmode
);
22314 v2
= gen_reg_rtx (SFmode
);
22315 t0
= gen_reg_rtx (SFmode
);
22316 halfthree
= gen_reg_rtx (SFmode
);
22317 cond
= gen_rtx_REG (CCFPmode
, CR1_REGNO
);
22318 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
22320 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
22321 emit_insn (gen_rtx_SET (VOIDmode
, t0
,
22322 gen_rtx_MULT (SFmode
, src
, src
)));
22324 emit_insn (gen_rtx_SET (VOIDmode
, cond
,
22325 gen_rtx_COMPARE (CCFPmode
, t0
, src
)));
22326 c1
= gen_rtx_EQ (VOIDmode
, cond
, const0_rtx
);
22327 emit_unlikely_jump (c1
, label
);
22329 half
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf
, SFmode
));
22330 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
22332 /* halfthree = 1.5 = 1.0 + 0.5 */
22333 emit_insn (gen_rtx_SET (VOIDmode
, halfthree
,
22334 gen_rtx_PLUS (SFmode
, one
, half
)));
22336 /* x0 = rsqrt estimate */
22337 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
22338 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, src
),
22341 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
22342 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
22343 gen_rtx_MINUS (SFmode
,
22344 gen_rtx_MULT (SFmode
, src
, halfthree
),
22347 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
22348 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
22349 gen_rtx_MULT (SFmode
, x0
, x0
)));
22350 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
22351 gen_rtx_MINUS (SFmode
,
22353 gen_rtx_MULT (SFmode
, y1
, u0
))));
22354 emit_insn (gen_rtx_SET (VOIDmode
, x1
,
22355 gen_rtx_MULT (SFmode
, x0
, v0
)));
22357 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
22358 emit_insn (gen_rtx_SET (VOIDmode
, u1
,
22359 gen_rtx_MULT (SFmode
, x1
, x1
)));
22360 emit_insn (gen_rtx_SET (VOIDmode
, v1
,
22361 gen_rtx_MINUS (SFmode
,
22363 gen_rtx_MULT (SFmode
, y1
, u1
))));
22364 emit_insn (gen_rtx_SET (VOIDmode
, x2
,
22365 gen_rtx_MULT (SFmode
, x1
, v1
)));
22367 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
22368 emit_insn (gen_rtx_SET (VOIDmode
, u2
,
22369 gen_rtx_MULT (SFmode
, x2
, x2
)));
22370 emit_insn (gen_rtx_SET (VOIDmode
, v2
,
22371 gen_rtx_MINUS (SFmode
,
22373 gen_rtx_MULT (SFmode
, y1
, u2
))));
22374 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
22375 gen_rtx_MULT (SFmode
, x2
, v2
)));
22377 emit_label (XEXP (label
, 0));
22380 /* Emit popcount intrinsic on TARGET_POPCNTB targets. DST is the
22381 target, and SRC is the argument operand. */
22384 rs6000_emit_popcount (rtx dst
, rtx src
)
22386 enum machine_mode mode
= GET_MODE (dst
);
22389 tmp1
= gen_reg_rtx (mode
);
22391 if (mode
== SImode
)
22393 emit_insn (gen_popcntbsi2 (tmp1
, src
));
22394 tmp2
= expand_mult (SImode
, tmp1
, GEN_INT (0x01010101),
22396 tmp2
= force_reg (SImode
, tmp2
);
22397 emit_insn (gen_lshrsi3 (dst
, tmp2
, GEN_INT (24)));
22401 emit_insn (gen_popcntbdi2 (tmp1
, src
));
22402 tmp2
= expand_mult (DImode
, tmp1
,
22403 GEN_INT ((HOST_WIDE_INT
)
22404 0x01010101 << 32 | 0x01010101),
22406 tmp2
= force_reg (DImode
, tmp2
);
22407 emit_insn (gen_lshrdi3 (dst
, tmp2
, GEN_INT (56)));
22412 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
22413 target, and SRC is the argument operand. */
22416 rs6000_emit_parity (rtx dst
, rtx src
)
22418 enum machine_mode mode
= GET_MODE (dst
);
22421 tmp
= gen_reg_rtx (mode
);
22422 if (mode
== SImode
)
22424 /* Is mult+shift >= shift+xor+shift+xor? */
22425 if (rs6000_cost
->mulsi_const
>= COSTS_N_INSNS (3))
22427 rtx tmp1
, tmp2
, tmp3
, tmp4
;
22429 tmp1
= gen_reg_rtx (SImode
);
22430 emit_insn (gen_popcntbsi2 (tmp1
, src
));
22432 tmp2
= gen_reg_rtx (SImode
);
22433 emit_insn (gen_lshrsi3 (tmp2
, tmp1
, GEN_INT (16)));
22434 tmp3
= gen_reg_rtx (SImode
);
22435 emit_insn (gen_xorsi3 (tmp3
, tmp1
, tmp2
));
22437 tmp4
= gen_reg_rtx (SImode
);
22438 emit_insn (gen_lshrsi3 (tmp4
, tmp3
, GEN_INT (8)));
22439 emit_insn (gen_xorsi3 (tmp
, tmp3
, tmp4
));
22442 rs6000_emit_popcount (tmp
, src
);
22443 emit_insn (gen_andsi3 (dst
, tmp
, const1_rtx
));
22447 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
22448 if (rs6000_cost
->muldi
>= COSTS_N_INSNS (5))
22450 rtx tmp1
, tmp2
, tmp3
, tmp4
, tmp5
, tmp6
;
22452 tmp1
= gen_reg_rtx (DImode
);
22453 emit_insn (gen_popcntbdi2 (tmp1
, src
));
22455 tmp2
= gen_reg_rtx (DImode
);
22456 emit_insn (gen_lshrdi3 (tmp2
, tmp1
, GEN_INT (32)));
22457 tmp3
= gen_reg_rtx (DImode
);
22458 emit_insn (gen_xordi3 (tmp3
, tmp1
, tmp2
));
22460 tmp4
= gen_reg_rtx (DImode
);
22461 emit_insn (gen_lshrdi3 (tmp4
, tmp3
, GEN_INT (16)));
22462 tmp5
= gen_reg_rtx (DImode
);
22463 emit_insn (gen_xordi3 (tmp5
, tmp3
, tmp4
));
22465 tmp6
= gen_reg_rtx (DImode
);
22466 emit_insn (gen_lshrdi3 (tmp6
, tmp5
, GEN_INT (8)));
22467 emit_insn (gen_xordi3 (tmp
, tmp5
, tmp6
));
22470 rs6000_emit_popcount (tmp
, src
);
22471 emit_insn (gen_anddi3 (dst
, tmp
, const1_rtx
));
22475 /* Return an RTX representing where to find the function value of a
22476 function returning MODE. */
22478 rs6000_complex_function_value (enum machine_mode mode
)
22480 unsigned int regno
;
22482 enum machine_mode inner
= GET_MODE_INNER (mode
);
22483 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
22485 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
22486 regno
= FP_ARG_RETURN
;
22489 regno
= GP_ARG_RETURN
;
22491 /* 32-bit is OK since it'll go in r3/r4. */
22492 if (TARGET_32BIT
&& inner_bytes
>= 4)
22493 return gen_rtx_REG (mode
, regno
);
22496 if (inner_bytes
>= 8)
22497 return gen_rtx_REG (mode
, regno
);
22499 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
22501 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
22502 GEN_INT (inner_bytes
));
22503 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
22506 /* Define how to find the value returned by a function.
22507 VALTYPE is the data type of the value (as a tree).
22508 If the precise function being called is known, FUNC is its FUNCTION_DECL;
22509 otherwise, FUNC is 0.
22511 On the SPE, both FPs and vectors are returned in r3.
22513 On RS/6000 an integer value is in r3 and a floating-point value is in
22514 fp1, unless -msoft-float. */
22517 rs6000_function_value (const_tree valtype
, const_tree func ATTRIBUTE_UNUSED
)
22519 enum machine_mode mode
;
22520 unsigned int regno
;
22522 /* Special handling for structs in darwin64. */
22523 if (rs6000_darwin64_abi
22524 && TYPE_MODE (valtype
) == BLKmode
22525 && TREE_CODE (valtype
) == RECORD_TYPE
22526 && int_size_in_bytes (valtype
) > 0)
22528 CUMULATIVE_ARGS valcum
;
22532 valcum
.fregno
= FP_ARG_MIN_REG
;
22533 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
22534 /* Do a trial code generation as if this were going to be passed as
22535 an argument; if any part goes in memory, we return NULL. */
22536 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, 1, true);
22539 /* Otherwise fall through to standard ABI rules. */
22542 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
22544 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
22545 return gen_rtx_PARALLEL (DImode
,
22547 gen_rtx_EXPR_LIST (VOIDmode
,
22548 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
22550 gen_rtx_EXPR_LIST (VOIDmode
,
22551 gen_rtx_REG (SImode
,
22552 GP_ARG_RETURN
+ 1),
22555 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
22557 return gen_rtx_PARALLEL (DCmode
,
22559 gen_rtx_EXPR_LIST (VOIDmode
,
22560 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
22562 gen_rtx_EXPR_LIST (VOIDmode
,
22563 gen_rtx_REG (SImode
,
22564 GP_ARG_RETURN
+ 1),
22566 gen_rtx_EXPR_LIST (VOIDmode
,
22567 gen_rtx_REG (SImode
,
22568 GP_ARG_RETURN
+ 2),
22570 gen_rtx_EXPR_LIST (VOIDmode
,
22571 gen_rtx_REG (SImode
,
22572 GP_ARG_RETURN
+ 3),
22576 mode
= TYPE_MODE (valtype
);
22577 if ((INTEGRAL_TYPE_P (valtype
) && GET_MODE_BITSIZE (mode
) < BITS_PER_WORD
)
22578 || POINTER_TYPE_P (valtype
))
22579 mode
= TARGET_32BIT
? SImode
: DImode
;
22581 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
22582 /* _Decimal128 must use an even/odd register pair. */
22583 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
22584 else if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
22585 && ((TARGET_SINGLE_FLOAT
&& (mode
== SFmode
)) || TARGET_DOUBLE_FLOAT
))
22586 regno
= FP_ARG_RETURN
;
22587 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
22588 && targetm
.calls
.split_complex_arg
)
22589 return rs6000_complex_function_value (mode
);
22590 else if (TREE_CODE (valtype
) == VECTOR_TYPE
22591 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
22592 && ALTIVEC_VECTOR_MODE (mode
))
22593 regno
= ALTIVEC_ARG_RETURN
;
22594 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
22595 && (mode
== DFmode
|| mode
== DCmode
22596 || mode
== TFmode
|| mode
== TCmode
))
22597 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
22599 regno
= GP_ARG_RETURN
;
22601 return gen_rtx_REG (mode
, regno
);
22604 /* Define how to find the value returned by a library function
22605 assuming the value has mode MODE. */
22607 rs6000_libcall_value (enum machine_mode mode
)
22609 unsigned int regno
;
22611 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
22613 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
22614 return gen_rtx_PARALLEL (DImode
,
22616 gen_rtx_EXPR_LIST (VOIDmode
,
22617 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
22619 gen_rtx_EXPR_LIST (VOIDmode
,
22620 gen_rtx_REG (SImode
,
22621 GP_ARG_RETURN
+ 1),
22625 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
22626 /* _Decimal128 must use an even/odd register pair. */
22627 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
22628 else if (SCALAR_FLOAT_MODE_P (mode
)
22629 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
22630 regno
= FP_ARG_RETURN
;
22631 else if (ALTIVEC_VECTOR_MODE (mode
)
22632 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
22633 regno
= ALTIVEC_ARG_RETURN
;
22634 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
22635 return rs6000_complex_function_value (mode
);
22636 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
22637 && (mode
== DFmode
|| mode
== DCmode
22638 || mode
== TFmode
|| mode
== TCmode
))
22639 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
22641 regno
= GP_ARG_RETURN
;
22643 return gen_rtx_REG (mode
, regno
);
22646 /* Define the offset between two registers, FROM to be eliminated and its
22647 replacement TO, at the start of a routine. */
22649 rs6000_initial_elimination_offset (int from
, int to
)
22651 rs6000_stack_t
*info
= rs6000_stack_info ();
22652 HOST_WIDE_INT offset
;
22654 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
22655 offset
= info
->push_p
? 0 : -info
->total_size
;
22656 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
22658 offset
= info
->push_p
? 0 : -info
->total_size
;
22659 if (FRAME_GROWS_DOWNWARD
)
22660 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
22662 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
22663 offset
= FRAME_GROWS_DOWNWARD
22664 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
22666 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
22667 offset
= info
->total_size
;
22668 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
22669 offset
= info
->push_p
? info
->total_size
: 0;
22670 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
22673 gcc_unreachable ();
22679 rs6000_dwarf_register_span (rtx reg
)
22683 unsigned regno
= REGNO (reg
);
22684 enum machine_mode mode
= GET_MODE (reg
);
22688 && (SPE_VECTOR_MODE (GET_MODE (reg
))
22689 || (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
)
22690 && mode
!= SFmode
&& mode
!= SDmode
&& mode
!= SCmode
)))
22695 regno
= REGNO (reg
);
22697 /* The duality of the SPE register size wreaks all kinds of havoc.
22698 This is a way of distinguishing r0 in 32-bits from r0 in
22700 words
= (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
22701 gcc_assert (words
<= 4);
22702 for (i
= 0; i
< words
; i
++, regno
++)
22704 if (BYTES_BIG_ENDIAN
)
22706 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
+ 1200);
22707 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
);
22711 parts
[2 * i
] = gen_rtx_REG (SImode
, regno
);
22712 parts
[2 * i
+ 1] = gen_rtx_REG (SImode
, regno
+ 1200);
22716 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (words
* 2, parts
));
22719 /* Fill in sizes for SPE register high parts in table used by unwinder. */
22722 rs6000_init_dwarf_reg_sizes_extra (tree address
)
22727 enum machine_mode mode
= TYPE_MODE (char_type_node
);
22728 rtx addr
= expand_expr (address
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
22729 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
22730 rtx value
= gen_int_mode (4, mode
);
22732 for (i
= 1201; i
< 1232; i
++)
22734 int column
= DWARF_REG_TO_UNWIND_COLUMN (i
);
22735 HOST_WIDE_INT offset
22736 = DWARF_FRAME_REGNUM (column
) * GET_MODE_SIZE (mode
);
22738 emit_move_insn (adjust_address (mem
, mode
, offset
), value
);
22743 /* Map internal gcc register numbers to DWARF2 register numbers. */
22746 rs6000_dbx_register_number (unsigned int regno
)
22748 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
22750 if (regno
== MQ_REGNO
)
22752 if (regno
== LR_REGNO
)
22754 if (regno
== CTR_REGNO
)
22756 if (CR_REGNO_P (regno
))
22757 return regno
- CR0_REGNO
+ 86;
22758 if (regno
== XER_REGNO
)
22760 if (ALTIVEC_REGNO_P (regno
))
22761 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
22762 if (regno
== VRSAVE_REGNO
)
22764 if (regno
== VSCR_REGNO
)
22766 if (regno
== SPE_ACC_REGNO
)
22768 if (regno
== SPEFSCR_REGNO
)
22770 /* SPE high reg number. We get these values of regno from
22771 rs6000_dwarf_register_span. */
22772 gcc_assert (regno
>= 1200 && regno
< 1232);
22776 /* target hook eh_return_filter_mode */
22777 static enum machine_mode
22778 rs6000_eh_return_filter_mode (void)
22780 return TARGET_32BIT
? SImode
: word_mode
;
22783 /* Target hook for scalar_mode_supported_p. */
22785 rs6000_scalar_mode_supported_p (enum machine_mode mode
)
22787 if (DECIMAL_FLOAT_MODE_P (mode
))
22790 return default_scalar_mode_supported_p (mode
);
22793 /* Target hook for vector_mode_supported_p. */
22795 rs6000_vector_mode_supported_p (enum machine_mode mode
)
22798 if (TARGET_PAIRED_FLOAT
&& PAIRED_VECTOR_MODE (mode
))
22801 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
22804 else if (TARGET_ALTIVEC
&& ALTIVEC_VECTOR_MODE (mode
))
22811 /* Target hook for invalid_arg_for_unprototyped_fn. */
22812 static const char *
22813 invalid_arg_for_unprototyped_fn (const_tree typelist
, const_tree funcdecl
, const_tree val
)
22815 return (!rs6000_darwin64_abi
22817 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
22818 && (funcdecl
== NULL_TREE
22819 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
22820 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
22821 ? N_("AltiVec argument passed to unprototyped function")
22825 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
22826 setup by using __stack_chk_fail_local hidden function instead of
22827 calling __stack_chk_fail directly. Otherwise it is better to call
22828 __stack_chk_fail directly. */
22831 rs6000_stack_protect_fail (void)
22833 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
22834 ? default_hidden_stack_protect_fail ()
22835 : default_external_stack_protect_fail ();
22839 rs6000_final_prescan_insn (rtx insn
, rtx
*operand ATTRIBUTE_UNUSED
,
22840 int num_operands ATTRIBUTE_UNUSED
)
22842 if (rs6000_warn_cell_microcode
)
22845 int insn_code_number
= recog_memoized (insn
);
22846 location_t location
= locator_location (INSN_LOCATOR (insn
));
22848 /* Punt on insns we cannot recognize. */
22849 if (insn_code_number
< 0)
22852 temp
= get_insn_template (insn_code_number
, insn
);
22854 if (get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
)
22855 warning_at (location
, OPT_mwarn_cell_microcode
,
22856 "emitting microcode insn %s\t[%s] #%d",
22857 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
22858 else if (get_attr_cell_micro (insn
) == CELL_MICRO_CONDITIONAL
)
22859 warning_at (location
, OPT_mwarn_cell_microcode
,
22860 "emitting conditional microcode insn %s\t[%s] #%d",
22861 temp
, insn_data
[INSN_CODE (insn
)].name
, INSN_UID (insn
));
22865 #include "gt-rs6000.h"