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
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 machine_function
GTY(())
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 static GTY(()) bool rs6000_cell_dont_microcode
;
148 /* Always emit branch hint bits. */
149 static GTY(()) bool rs6000_always_hint
;
151 /* Schedule instructions for group formation. */
152 static GTY(()) bool rs6000_sched_groups
;
154 /* Align branch targets. */
155 static GTY(()) bool rs6000_align_branch_targets
;
157 /* Support for -msched-costly-dep option. */
158 const char *rs6000_sched_costly_dep_str
;
159 enum rs6000_dependence_cost rs6000_sched_costly_dep
;
161 /* Support for -minsert-sched-nops option. */
162 const char *rs6000_sched_insert_nops_str
;
163 enum rs6000_nop_insertion rs6000_sched_insert_nops
;
165 /* Support targetm.vectorize.builtin_mask_for_load. */
166 static GTY(()) tree altivec_builtin_mask_for_load
;
168 /* Size of long double. */
169 int rs6000_long_double_type_size
;
171 /* IEEE quad extended precision long double. */
174 /* Nonzero to use AltiVec ABI. */
175 int rs6000_altivec_abi
;
177 /* Nonzero if we want SPE SIMD instructions. */
180 /* Nonzero if we want SPE ABI extensions. */
183 /* Nonzero to use isel instructions. */
186 /* Nonzero if floating point operations are done in the GPRs. */
187 int rs6000_float_gprs
= 0;
189 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
190 int rs6000_darwin64_abi
;
192 /* Set to nonzero once AIX common-mode calls have been defined. */
193 static GTY(()) int common_mode_defined
;
195 /* Save information from a "cmpxx" operation until the branch or scc is
197 rtx rs6000_compare_op0
, rs6000_compare_op1
;
198 int rs6000_compare_fp_p
;
200 /* Label number of label created for -mrelocatable, to call to so we can
201 get the address of the GOT section */
202 int rs6000_pic_labelno
;
205 /* Which abi to adhere to */
206 const char *rs6000_abi_name
;
208 /* Semantics of the small data area */
209 enum rs6000_sdata_type rs6000_sdata
= SDATA_DATA
;
211 /* Which small data model to use */
212 const char *rs6000_sdata_name
= (char *)0;
214 /* Counter for labels which are to be placed in .fixup. */
215 int fixuplabelno
= 0;
218 /* Bit size of immediate TLS offsets and string from which it is decoded. */
219 int rs6000_tls_size
= 32;
220 const char *rs6000_tls_size_string
;
222 /* ABI enumeration available for subtarget to use. */
223 enum rs6000_abi rs6000_current_abi
;
225 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
229 const char *rs6000_debug_name
;
230 int rs6000_debug_stack
; /* debug stack applications */
231 int rs6000_debug_arg
; /* debug argument handling */
233 /* Value is TRUE if register/mode pair is acceptable. */
234 bool rs6000_hard_regno_mode_ok_p
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
236 /* Built in types. */
238 tree rs6000_builtin_types
[RS6000_BTI_MAX
];
239 tree rs6000_builtin_decls
[RS6000_BUILTIN_COUNT
];
241 const char *rs6000_traceback_name
;
243 traceback_default
= 0,
249 /* Flag to say the TOC is initialized */
251 char toc_label_name
[10];
253 /* Cached value of rs6000_variable_issue. This is cached in
254 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
255 static short cached_can_issue_more
;
257 static GTY(()) section
*read_only_data_section
;
258 static GTY(()) section
*private_data_section
;
259 static GTY(()) section
*read_only_private_data_section
;
260 static GTY(()) section
*sdata2_section
;
261 static GTY(()) section
*toc_section
;
263 /* Control alignment for fields within structures. */
264 /* String from -malign-XXXXX. */
265 int rs6000_alignment_flags
;
267 /* True for any options that were explicitly set. */
269 bool aix_struct_ret
; /* True if -maix-struct-ret was used. */
270 bool alignment
; /* True if -malign- was used. */
271 bool spe_abi
; /* True if -mabi=spe/no-spe was used. */
272 bool altivec_abi
; /* True if -mabi=altivec/no-altivec used. */
273 bool spe
; /* True if -mspe= was used. */
274 bool float_gprs
; /* True if -mfloat-gprs= was used. */
275 bool isel
; /* True if -misel was used. */
276 bool long_double
; /* True if -mlong-double- was used. */
277 bool ieee
; /* True if -mabi=ieee/ibmlongdouble used. */
278 bool vrsave
; /* True if -mvrsave was used. */
279 } rs6000_explicit_options
;
281 struct builtin_description
283 /* mask is not const because we're going to alter it below. This
284 nonsense will go away when we rewrite the -march infrastructure
285 to give us more target flag bits. */
287 const enum insn_code icode
;
288 const char *const name
;
289 const enum rs6000_builtins code
;
292 /* Target cpu costs. */
294 struct processor_costs
{
295 const int mulsi
; /* cost of SImode multiplication. */
296 const int mulsi_const
; /* cost of SImode multiplication by constant. */
297 const int mulsi_const9
; /* cost of SImode mult by short constant. */
298 const int muldi
; /* cost of DImode multiplication. */
299 const int divsi
; /* cost of SImode division. */
300 const int divdi
; /* cost of DImode division. */
301 const int fp
; /* cost of simple SFmode and DFmode insns. */
302 const int dmul
; /* cost of DFmode multiplication (and fmadd). */
303 const int sdiv
; /* cost of SFmode division (fdivs). */
304 const int ddiv
; /* cost of DFmode division (fdiv). */
305 const int cache_line_size
; /* cache line size in bytes. */
306 const int l1_cache_size
; /* size of l1 cache, in kilobytes. */
307 const int l2_cache_size
; /* size of l2 cache, in kilobytes. */
308 const int simultaneous_prefetches
; /* number of parallel prefetch
312 const struct processor_costs
*rs6000_cost
;
314 /* Processor costs (relative to an add) */
316 /* Instruction size costs on 32bit processors. */
318 struct processor_costs size32_cost
= {
319 COSTS_N_INSNS (1), /* mulsi */
320 COSTS_N_INSNS (1), /* mulsi_const */
321 COSTS_N_INSNS (1), /* mulsi_const9 */
322 COSTS_N_INSNS (1), /* muldi */
323 COSTS_N_INSNS (1), /* divsi */
324 COSTS_N_INSNS (1), /* divdi */
325 COSTS_N_INSNS (1), /* fp */
326 COSTS_N_INSNS (1), /* dmul */
327 COSTS_N_INSNS (1), /* sdiv */
328 COSTS_N_INSNS (1), /* ddiv */
335 /* Instruction size costs on 64bit processors. */
337 struct processor_costs size64_cost
= {
338 COSTS_N_INSNS (1), /* mulsi */
339 COSTS_N_INSNS (1), /* mulsi_const */
340 COSTS_N_INSNS (1), /* mulsi_const9 */
341 COSTS_N_INSNS (1), /* muldi */
342 COSTS_N_INSNS (1), /* divsi */
343 COSTS_N_INSNS (1), /* divdi */
344 COSTS_N_INSNS (1), /* fp */
345 COSTS_N_INSNS (1), /* dmul */
346 COSTS_N_INSNS (1), /* sdiv */
347 COSTS_N_INSNS (1), /* ddiv */
354 /* Instruction costs on RIOS1 processors. */
356 struct processor_costs rios1_cost
= {
357 COSTS_N_INSNS (5), /* mulsi */
358 COSTS_N_INSNS (4), /* mulsi_const */
359 COSTS_N_INSNS (3), /* mulsi_const9 */
360 COSTS_N_INSNS (5), /* muldi */
361 COSTS_N_INSNS (19), /* divsi */
362 COSTS_N_INSNS (19), /* divdi */
363 COSTS_N_INSNS (2), /* fp */
364 COSTS_N_INSNS (2), /* dmul */
365 COSTS_N_INSNS (19), /* sdiv */
366 COSTS_N_INSNS (19), /* ddiv */
367 128, /* cache line size */
373 /* Instruction costs on RIOS2 processors. */
375 struct processor_costs rios2_cost
= {
376 COSTS_N_INSNS (2), /* mulsi */
377 COSTS_N_INSNS (2), /* mulsi_const */
378 COSTS_N_INSNS (2), /* mulsi_const9 */
379 COSTS_N_INSNS (2), /* muldi */
380 COSTS_N_INSNS (13), /* divsi */
381 COSTS_N_INSNS (13), /* divdi */
382 COSTS_N_INSNS (2), /* fp */
383 COSTS_N_INSNS (2), /* dmul */
384 COSTS_N_INSNS (17), /* sdiv */
385 COSTS_N_INSNS (17), /* ddiv */
386 256, /* cache line size */
392 /* Instruction costs on RS64A processors. */
394 struct processor_costs rs64a_cost
= {
395 COSTS_N_INSNS (20), /* mulsi */
396 COSTS_N_INSNS (12), /* mulsi_const */
397 COSTS_N_INSNS (8), /* mulsi_const9 */
398 COSTS_N_INSNS (34), /* muldi */
399 COSTS_N_INSNS (65), /* divsi */
400 COSTS_N_INSNS (67), /* divdi */
401 COSTS_N_INSNS (4), /* fp */
402 COSTS_N_INSNS (4), /* dmul */
403 COSTS_N_INSNS (31), /* sdiv */
404 COSTS_N_INSNS (31), /* ddiv */
405 128, /* cache line size */
411 /* Instruction costs on MPCCORE processors. */
413 struct processor_costs mpccore_cost
= {
414 COSTS_N_INSNS (2), /* mulsi */
415 COSTS_N_INSNS (2), /* mulsi_const */
416 COSTS_N_INSNS (2), /* mulsi_const9 */
417 COSTS_N_INSNS (2), /* muldi */
418 COSTS_N_INSNS (6), /* divsi */
419 COSTS_N_INSNS (6), /* divdi */
420 COSTS_N_INSNS (4), /* fp */
421 COSTS_N_INSNS (5), /* dmul */
422 COSTS_N_INSNS (10), /* sdiv */
423 COSTS_N_INSNS (17), /* ddiv */
424 32, /* cache line size */
430 /* Instruction costs on PPC403 processors. */
432 struct processor_costs ppc403_cost
= {
433 COSTS_N_INSNS (4), /* mulsi */
434 COSTS_N_INSNS (4), /* mulsi_const */
435 COSTS_N_INSNS (4), /* mulsi_const9 */
436 COSTS_N_INSNS (4), /* muldi */
437 COSTS_N_INSNS (33), /* divsi */
438 COSTS_N_INSNS (33), /* divdi */
439 COSTS_N_INSNS (11), /* fp */
440 COSTS_N_INSNS (11), /* dmul */
441 COSTS_N_INSNS (11), /* sdiv */
442 COSTS_N_INSNS (11), /* ddiv */
443 32, /* cache line size */
449 /* Instruction costs on PPC405 processors. */
451 struct processor_costs ppc405_cost
= {
452 COSTS_N_INSNS (5), /* mulsi */
453 COSTS_N_INSNS (4), /* mulsi_const */
454 COSTS_N_INSNS (3), /* mulsi_const9 */
455 COSTS_N_INSNS (5), /* muldi */
456 COSTS_N_INSNS (35), /* divsi */
457 COSTS_N_INSNS (35), /* divdi */
458 COSTS_N_INSNS (11), /* fp */
459 COSTS_N_INSNS (11), /* dmul */
460 COSTS_N_INSNS (11), /* sdiv */
461 COSTS_N_INSNS (11), /* ddiv */
462 32, /* cache line size */
468 /* Instruction costs on PPC440 processors. */
470 struct processor_costs ppc440_cost
= {
471 COSTS_N_INSNS (3), /* mulsi */
472 COSTS_N_INSNS (2), /* mulsi_const */
473 COSTS_N_INSNS (2), /* mulsi_const9 */
474 COSTS_N_INSNS (3), /* muldi */
475 COSTS_N_INSNS (34), /* divsi */
476 COSTS_N_INSNS (34), /* divdi */
477 COSTS_N_INSNS (5), /* fp */
478 COSTS_N_INSNS (5), /* dmul */
479 COSTS_N_INSNS (19), /* sdiv */
480 COSTS_N_INSNS (33), /* ddiv */
481 32, /* cache line size */
487 /* Instruction costs on PPC601 processors. */
489 struct processor_costs ppc601_cost
= {
490 COSTS_N_INSNS (5), /* mulsi */
491 COSTS_N_INSNS (5), /* mulsi_const */
492 COSTS_N_INSNS (5), /* mulsi_const9 */
493 COSTS_N_INSNS (5), /* muldi */
494 COSTS_N_INSNS (36), /* divsi */
495 COSTS_N_INSNS (36), /* divdi */
496 COSTS_N_INSNS (4), /* fp */
497 COSTS_N_INSNS (5), /* dmul */
498 COSTS_N_INSNS (17), /* sdiv */
499 COSTS_N_INSNS (31), /* ddiv */
500 32, /* cache line size */
506 /* Instruction costs on PPC603 processors. */
508 struct processor_costs ppc603_cost
= {
509 COSTS_N_INSNS (5), /* mulsi */
510 COSTS_N_INSNS (3), /* mulsi_const */
511 COSTS_N_INSNS (2), /* mulsi_const9 */
512 COSTS_N_INSNS (5), /* muldi */
513 COSTS_N_INSNS (37), /* divsi */
514 COSTS_N_INSNS (37), /* divdi */
515 COSTS_N_INSNS (3), /* fp */
516 COSTS_N_INSNS (4), /* dmul */
517 COSTS_N_INSNS (18), /* sdiv */
518 COSTS_N_INSNS (33), /* ddiv */
519 32, /* cache line size */
525 /* Instruction costs on PPC604 processors. */
527 struct processor_costs ppc604_cost
= {
528 COSTS_N_INSNS (4), /* mulsi */
529 COSTS_N_INSNS (4), /* mulsi_const */
530 COSTS_N_INSNS (4), /* mulsi_const9 */
531 COSTS_N_INSNS (4), /* muldi */
532 COSTS_N_INSNS (20), /* divsi */
533 COSTS_N_INSNS (20), /* divdi */
534 COSTS_N_INSNS (3), /* fp */
535 COSTS_N_INSNS (3), /* dmul */
536 COSTS_N_INSNS (18), /* sdiv */
537 COSTS_N_INSNS (32), /* ddiv */
538 32, /* cache line size */
544 /* Instruction costs on PPC604e processors. */
546 struct processor_costs ppc604e_cost
= {
547 COSTS_N_INSNS (2), /* mulsi */
548 COSTS_N_INSNS (2), /* mulsi_const */
549 COSTS_N_INSNS (2), /* mulsi_const9 */
550 COSTS_N_INSNS (2), /* muldi */
551 COSTS_N_INSNS (20), /* divsi */
552 COSTS_N_INSNS (20), /* divdi */
553 COSTS_N_INSNS (3), /* fp */
554 COSTS_N_INSNS (3), /* dmul */
555 COSTS_N_INSNS (18), /* sdiv */
556 COSTS_N_INSNS (32), /* ddiv */
557 32, /* cache line size */
563 /* Instruction costs on PPC620 processors. */
565 struct processor_costs ppc620_cost
= {
566 COSTS_N_INSNS (5), /* mulsi */
567 COSTS_N_INSNS (4), /* mulsi_const */
568 COSTS_N_INSNS (3), /* mulsi_const9 */
569 COSTS_N_INSNS (7), /* muldi */
570 COSTS_N_INSNS (21), /* divsi */
571 COSTS_N_INSNS (37), /* divdi */
572 COSTS_N_INSNS (3), /* fp */
573 COSTS_N_INSNS (3), /* dmul */
574 COSTS_N_INSNS (18), /* sdiv */
575 COSTS_N_INSNS (32), /* ddiv */
576 128, /* cache line size */
582 /* Instruction costs on PPC630 processors. */
584 struct processor_costs ppc630_cost
= {
585 COSTS_N_INSNS (5), /* mulsi */
586 COSTS_N_INSNS (4), /* mulsi_const */
587 COSTS_N_INSNS (3), /* mulsi_const9 */
588 COSTS_N_INSNS (7), /* muldi */
589 COSTS_N_INSNS (21), /* divsi */
590 COSTS_N_INSNS (37), /* divdi */
591 COSTS_N_INSNS (3), /* fp */
592 COSTS_N_INSNS (3), /* dmul */
593 COSTS_N_INSNS (17), /* sdiv */
594 COSTS_N_INSNS (21), /* ddiv */
595 128, /* cache line size */
601 /* Instruction costs on Cell processor. */
602 /* COSTS_N_INSNS (1) ~ one add. */
604 struct processor_costs ppccell_cost
= {
605 COSTS_N_INSNS (9/2)+2, /* mulsi */
606 COSTS_N_INSNS (6/2), /* mulsi_const */
607 COSTS_N_INSNS (6/2), /* mulsi_const9 */
608 COSTS_N_INSNS (15/2)+2, /* muldi */
609 COSTS_N_INSNS (38/2), /* divsi */
610 COSTS_N_INSNS (70/2), /* divdi */
611 COSTS_N_INSNS (10/2), /* fp */
612 COSTS_N_INSNS (10/2), /* dmul */
613 COSTS_N_INSNS (74/2), /* sdiv */
614 COSTS_N_INSNS (74/2), /* ddiv */
615 128, /* cache line size */
621 /* Instruction costs on PPC750 and PPC7400 processors. */
623 struct processor_costs ppc750_cost
= {
624 COSTS_N_INSNS (5), /* mulsi */
625 COSTS_N_INSNS (3), /* mulsi_const */
626 COSTS_N_INSNS (2), /* mulsi_const9 */
627 COSTS_N_INSNS (5), /* muldi */
628 COSTS_N_INSNS (17), /* divsi */
629 COSTS_N_INSNS (17), /* divdi */
630 COSTS_N_INSNS (3), /* fp */
631 COSTS_N_INSNS (3), /* dmul */
632 COSTS_N_INSNS (17), /* sdiv */
633 COSTS_N_INSNS (31), /* ddiv */
634 32, /* cache line size */
640 /* Instruction costs on PPC7450 processors. */
642 struct processor_costs ppc7450_cost
= {
643 COSTS_N_INSNS (4), /* mulsi */
644 COSTS_N_INSNS (3), /* mulsi_const */
645 COSTS_N_INSNS (3), /* mulsi_const9 */
646 COSTS_N_INSNS (4), /* muldi */
647 COSTS_N_INSNS (23), /* divsi */
648 COSTS_N_INSNS (23), /* divdi */
649 COSTS_N_INSNS (5), /* fp */
650 COSTS_N_INSNS (5), /* dmul */
651 COSTS_N_INSNS (21), /* sdiv */
652 COSTS_N_INSNS (35), /* ddiv */
653 32, /* cache line size */
659 /* Instruction costs on PPC8540 processors. */
661 struct processor_costs ppc8540_cost
= {
662 COSTS_N_INSNS (4), /* mulsi */
663 COSTS_N_INSNS (4), /* mulsi_const */
664 COSTS_N_INSNS (4), /* mulsi_const9 */
665 COSTS_N_INSNS (4), /* muldi */
666 COSTS_N_INSNS (19), /* divsi */
667 COSTS_N_INSNS (19), /* divdi */
668 COSTS_N_INSNS (4), /* fp */
669 COSTS_N_INSNS (4), /* dmul */
670 COSTS_N_INSNS (29), /* sdiv */
671 COSTS_N_INSNS (29), /* ddiv */
672 32, /* cache line size */
675 1, /* prefetch streams /*/
678 /* Instruction costs on E300C2 and E300C3 cores. */
680 struct processor_costs ppce300c2c3_cost
= {
681 COSTS_N_INSNS (4), /* mulsi */
682 COSTS_N_INSNS (4), /* mulsi_const */
683 COSTS_N_INSNS (4), /* mulsi_const9 */
684 COSTS_N_INSNS (4), /* muldi */
685 COSTS_N_INSNS (19), /* divsi */
686 COSTS_N_INSNS (19), /* divdi */
687 COSTS_N_INSNS (3), /* fp */
688 COSTS_N_INSNS (4), /* dmul */
689 COSTS_N_INSNS (18), /* sdiv */
690 COSTS_N_INSNS (33), /* ddiv */
694 1, /* prefetch streams /*/
697 /* Instruction costs on PPCE500MC processors. */
699 struct processor_costs ppce500mc_cost
= {
700 COSTS_N_INSNS (4), /* mulsi */
701 COSTS_N_INSNS (4), /* mulsi_const */
702 COSTS_N_INSNS (4), /* mulsi_const9 */
703 COSTS_N_INSNS (4), /* muldi */
704 COSTS_N_INSNS (14), /* divsi */
705 COSTS_N_INSNS (14), /* divdi */
706 COSTS_N_INSNS (8), /* fp */
707 COSTS_N_INSNS (10), /* dmul */
708 COSTS_N_INSNS (36), /* sdiv */
709 COSTS_N_INSNS (66), /* ddiv */
710 64, /* cache line size */
713 1, /* prefetch streams /*/
716 /* Instruction costs on POWER4 and POWER5 processors. */
718 struct processor_costs power4_cost
= {
719 COSTS_N_INSNS (3), /* mulsi */
720 COSTS_N_INSNS (2), /* mulsi_const */
721 COSTS_N_INSNS (2), /* mulsi_const9 */
722 COSTS_N_INSNS (4), /* muldi */
723 COSTS_N_INSNS (18), /* divsi */
724 COSTS_N_INSNS (34), /* divdi */
725 COSTS_N_INSNS (3), /* fp */
726 COSTS_N_INSNS (3), /* dmul */
727 COSTS_N_INSNS (17), /* sdiv */
728 COSTS_N_INSNS (17), /* ddiv */
729 128, /* cache line size */
732 8, /* prefetch streams /*/
735 /* Instruction costs on POWER6 processors. */
737 struct processor_costs power6_cost
= {
738 COSTS_N_INSNS (8), /* mulsi */
739 COSTS_N_INSNS (8), /* mulsi_const */
740 COSTS_N_INSNS (8), /* mulsi_const9 */
741 COSTS_N_INSNS (8), /* muldi */
742 COSTS_N_INSNS (22), /* divsi */
743 COSTS_N_INSNS (28), /* divdi */
744 COSTS_N_INSNS (3), /* fp */
745 COSTS_N_INSNS (3), /* dmul */
746 COSTS_N_INSNS (13), /* sdiv */
747 COSTS_N_INSNS (16), /* ddiv */
748 128, /* cache line size */
751 16, /* prefetch streams */
755 static bool rs6000_function_ok_for_sibcall (tree
, tree
);
756 static const char *rs6000_invalid_within_doloop (const_rtx
);
757 static rtx
rs6000_generate_compare (enum rtx_code
);
758 static void rs6000_emit_stack_tie (void);
759 static void rs6000_frame_related (rtx
, rtx
, HOST_WIDE_INT
, rtx
, rtx
);
760 static bool spe_func_has_64bit_regs_p (void);
761 static void emit_frame_save (rtx
, rtx
, enum machine_mode
, unsigned int,
763 static rtx
gen_frame_mem_offset (enum machine_mode
, rtx
, int);
764 static void rs6000_emit_allocate_stack (HOST_WIDE_INT
, int, int);
765 static unsigned rs6000_hash_constant (rtx
);
766 static unsigned toc_hash_function (const void *);
767 static int toc_hash_eq (const void *, const void *);
768 static int constant_pool_expr_1 (rtx
, int *, int *);
769 static bool constant_pool_expr_p (rtx
);
770 static bool legitimate_small_data_p (enum machine_mode
, rtx
);
771 static bool legitimate_lo_sum_address_p (enum machine_mode
, rtx
, int);
772 static struct machine_function
* rs6000_init_machine_status (void);
773 static bool rs6000_assemble_integer (rtx
, unsigned int, int);
774 static bool no_global_regs_above (int, bool);
775 #ifdef HAVE_GAS_HIDDEN
776 static void rs6000_assemble_visibility (tree
, int);
778 static int rs6000_ra_ever_killed (void);
779 static tree
rs6000_handle_longcall_attribute (tree
*, tree
, tree
, int, bool *);
780 static tree
rs6000_handle_altivec_attribute (tree
*, tree
, tree
, int, bool *);
781 static bool rs6000_ms_bitfield_layout_p (const_tree
);
782 static tree
rs6000_handle_struct_attribute (tree
*, tree
, tree
, int, bool *);
783 static void rs6000_eliminate_indexed_memrefs (rtx operands
[2]);
784 static const char *rs6000_mangle_type (const_tree
);
785 extern const struct attribute_spec rs6000_attribute_table
[];
786 static void rs6000_set_default_type_attributes (tree
);
787 static rtx
rs6000_savres_routine_sym (rs6000_stack_t
*, bool, bool, bool);
788 static void rs6000_emit_stack_reset (rs6000_stack_t
*, rtx
, rtx
, int, bool);
789 static rtx
rs6000_make_savres_rtx (rs6000_stack_t
*, rtx
, int,
790 enum machine_mode
, bool, bool, bool);
791 static bool rs6000_reg_live_or_pic_offset_p (int);
792 static int rs6000_savres_strategy (rs6000_stack_t
*, bool, int, int);
793 static void rs6000_restore_saved_cr (rtx
, int);
794 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT
);
795 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT
);
796 static void rs6000_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
798 static rtx
rs6000_emit_set_long_const (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
799 static bool rs6000_return_in_memory (const_tree
, const_tree
);
800 static void rs6000_file_start (void);
802 static int rs6000_elf_reloc_rw_mask (void);
803 static void rs6000_elf_asm_out_constructor (rtx
, int);
804 static void rs6000_elf_asm_out_destructor (rtx
, int);
805 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED
;
806 static void rs6000_elf_asm_init_sections (void);
807 static section
*rs6000_elf_select_rtx_section (enum machine_mode
, rtx
,
808 unsigned HOST_WIDE_INT
);
809 static void rs6000_elf_encode_section_info (tree
, rtx
, int)
812 static bool rs6000_use_blocks_for_constant_p (enum machine_mode
, const_rtx
);
813 static void rs6000_alloc_sdmode_stack_slot (void);
814 static void rs6000_instantiate_decls (void);
816 static void rs6000_xcoff_asm_output_anchor (rtx
);
817 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
818 static void rs6000_xcoff_asm_init_sections (void);
819 static int rs6000_xcoff_reloc_rw_mask (void);
820 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree
);
821 static section
*rs6000_xcoff_select_section (tree
, int,
822 unsigned HOST_WIDE_INT
);
823 static void rs6000_xcoff_unique_section (tree
, int);
824 static section
*rs6000_xcoff_select_rtx_section
825 (enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
);
826 static const char * rs6000_xcoff_strip_name_encoding (const char *);
827 static unsigned int rs6000_xcoff_section_type_flags (tree
, const char *, int);
828 static void rs6000_xcoff_file_start (void);
829 static void rs6000_xcoff_file_end (void);
831 static int rs6000_variable_issue (FILE *, int, rtx
, int);
832 static bool rs6000_rtx_costs (rtx
, int, int, int *, bool);
833 static int rs6000_adjust_cost (rtx
, rtx
, rtx
, int);
834 static void rs6000_sched_init (FILE *, int, int);
835 static bool is_microcoded_insn (rtx
);
836 static bool is_nonpipeline_insn (rtx
);
837 static bool is_cracked_insn (rtx
);
838 static bool is_branch_slot_insn (rtx
);
839 static bool is_load_insn (rtx
);
840 static rtx
get_store_dest (rtx pat
);
841 static bool is_store_insn (rtx
);
842 static bool set_to_load_agen (rtx
,rtx
);
843 static bool adjacent_mem_locations (rtx
,rtx
);
844 static int rs6000_adjust_priority (rtx
, int);
845 static int rs6000_issue_rate (void);
846 static bool rs6000_is_costly_dependence (dep_t
, int, int);
847 static rtx
get_next_active_insn (rtx
, rtx
);
848 static bool insn_terminates_group_p (rtx
, enum group_termination
);
849 static bool insn_must_be_first_in_group (rtx
);
850 static bool insn_must_be_last_in_group (rtx
);
851 static bool is_costly_group (rtx
*, rtx
);
852 static int force_new_group (int, FILE *, rtx
*, rtx
, bool *, int, int *);
853 static int redefine_groups (FILE *, int, rtx
, rtx
);
854 static int pad_groups (FILE *, int, rtx
, rtx
);
855 static void rs6000_sched_finish (FILE *, int);
856 static int rs6000_sched_reorder (FILE *, int, rtx
*, int *, int);
857 static int rs6000_sched_reorder2 (FILE *, int, rtx
*, int *, int);
858 static int rs6000_use_sched_lookahead (void);
859 static int rs6000_use_sched_lookahead_guard (rtx
);
860 static void * rs6000_alloc_sched_context (void);
861 static void rs6000_init_sched_context (void *, bool);
862 static void rs6000_set_sched_context (void *);
863 static void rs6000_free_sched_context (void *);
864 static tree
rs6000_builtin_reciprocal (unsigned int, bool, bool);
865 static tree
rs6000_builtin_mask_for_load (void);
866 static tree
rs6000_builtin_mul_widen_even (tree
);
867 static tree
rs6000_builtin_mul_widen_odd (tree
);
868 static tree
rs6000_builtin_conversion (enum tree_code
, tree
);
869 static tree
rs6000_builtin_vec_perm (tree
, tree
*);
871 static void def_builtin (int, const char *, tree
, int);
872 static bool rs6000_vector_alignment_reachable (const_tree
, bool);
873 static void rs6000_init_builtins (void);
874 static rtx
rs6000_expand_unop_builtin (enum insn_code
, tree
, rtx
);
875 static rtx
rs6000_expand_binop_builtin (enum insn_code
, tree
, rtx
);
876 static rtx
rs6000_expand_ternop_builtin (enum insn_code
, tree
, rtx
);
877 static rtx
rs6000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
878 static void altivec_init_builtins (void);
879 static void rs6000_common_init_builtins (void);
880 static void rs6000_init_libfuncs (void);
882 static void paired_init_builtins (void);
883 static rtx
paired_expand_builtin (tree
, rtx
, bool *);
884 static rtx
paired_expand_lv_builtin (enum insn_code
, tree
, rtx
);
885 static rtx
paired_expand_stv_builtin (enum insn_code
, tree
);
886 static rtx
paired_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
888 static void enable_mask_for_builtins (struct builtin_description
*, int,
889 enum rs6000_builtins
,
890 enum rs6000_builtins
);
891 static tree
build_opaque_vector_type (tree
, int);
892 static void spe_init_builtins (void);
893 static rtx
spe_expand_builtin (tree
, rtx
, bool *);
894 static rtx
spe_expand_stv_builtin (enum insn_code
, tree
);
895 static rtx
spe_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
896 static rtx
spe_expand_evsel_builtin (enum insn_code
, tree
, rtx
);
897 static int rs6000_emit_int_cmove (rtx
, rtx
, rtx
, rtx
);
898 static rs6000_stack_t
*rs6000_stack_info (void);
899 static void debug_stack_info (rs6000_stack_t
*);
901 static rtx
altivec_expand_builtin (tree
, rtx
, bool *);
902 static rtx
altivec_expand_ld_builtin (tree
, rtx
, bool *);
903 static rtx
altivec_expand_st_builtin (tree
, rtx
, bool *);
904 static rtx
altivec_expand_dst_builtin (tree
, rtx
, bool *);
905 static rtx
altivec_expand_abs_builtin (enum insn_code
, tree
, rtx
);
906 static rtx
altivec_expand_predicate_builtin (enum insn_code
,
907 const char *, tree
, rtx
);
908 static rtx
altivec_expand_stv_builtin (enum insn_code
, tree
);
909 static rtx
altivec_expand_vec_init_builtin (tree
, tree
, rtx
);
910 static rtx
altivec_expand_vec_set_builtin (tree
);
911 static rtx
altivec_expand_vec_ext_builtin (tree
, rtx
);
912 static int get_element_number (tree
, tree
);
913 static bool rs6000_handle_option (size_t, const char *, int);
914 static void rs6000_parse_tls_size_option (void);
915 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
916 static int first_altivec_reg_to_save (void);
917 static unsigned int compute_vrsave_mask (void);
918 static void compute_save_world_info (rs6000_stack_t
*info_ptr
);
919 static void is_altivec_return_reg (rtx
, void *);
920 static rtx
generate_set_vrsave (rtx
, rs6000_stack_t
*, int);
921 int easy_vector_constant (rtx
, enum machine_mode
);
922 static bool rs6000_is_opaque_type (const_tree
);
923 static rtx
rs6000_dwarf_register_span (rtx
);
924 static void rs6000_init_dwarf_reg_sizes_extra (tree
);
925 static rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
926 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
927 static rtx
rs6000_tls_get_addr (void);
928 static rtx
rs6000_got_sym (void);
929 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
930 static const char *rs6000_get_some_local_dynamic_name (void);
931 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
932 static rtx
rs6000_complex_function_value (enum machine_mode
);
933 static rtx
rs6000_spe_function_arg (CUMULATIVE_ARGS
*,
934 enum machine_mode
, tree
);
935 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
937 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
938 tree
, HOST_WIDE_INT
);
939 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
942 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
943 const_tree
, HOST_WIDE_INT
,
945 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, const_tree
, int, bool);
946 static rtx
rs6000_mixed_function_arg (enum machine_mode
, tree
, int);
947 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
948 static void setup_incoming_varargs (CUMULATIVE_ARGS
*,
949 enum machine_mode
, tree
,
951 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
953 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
955 static const char *invalid_arg_for_unprototyped_fn (const_tree
, const_tree
, const_tree
);
957 static void macho_branch_islands (void);
958 static int no_previous_def (tree function_name
);
959 static tree
get_prev_label (tree function_name
);
960 static void rs6000_darwin_file_start (void);
963 static tree
rs6000_build_builtin_va_list (void);
964 static void rs6000_va_start (tree
, rtx
);
965 static tree
rs6000_gimplify_va_arg (tree
, tree
, gimple_seq
*, gimple_seq
*);
966 static bool rs6000_must_pass_in_stack (enum machine_mode
, const_tree
);
967 static bool rs6000_scalar_mode_supported_p (enum machine_mode
);
968 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
969 static int get_vec_cmp_insn (enum rtx_code
, enum machine_mode
,
971 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
973 static int get_vsel_insn (enum machine_mode
);
974 static void rs6000_emit_vector_select (rtx
, rtx
, rtx
, rtx
);
975 static tree
rs6000_stack_protect_fail (void);
977 const int INSN_NOT_AVAILABLE
= -1;
978 static enum machine_mode
rs6000_eh_return_filter_mode (void);
980 /* Hash table stuff for keeping track of TOC entries. */
982 struct toc_hash_struct
GTY(())
984 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
985 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
987 enum machine_mode key_mode
;
991 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
993 /* Default register names. */
994 char rs6000_reg_names
[][8] =
996 "0", "1", "2", "3", "4", "5", "6", "7",
997 "8", "9", "10", "11", "12", "13", "14", "15",
998 "16", "17", "18", "19", "20", "21", "22", "23",
999 "24", "25", "26", "27", "28", "29", "30", "31",
1000 "0", "1", "2", "3", "4", "5", "6", "7",
1001 "8", "9", "10", "11", "12", "13", "14", "15",
1002 "16", "17", "18", "19", "20", "21", "22", "23",
1003 "24", "25", "26", "27", "28", "29", "30", "31",
1004 "mq", "lr", "ctr","ap",
1005 "0", "1", "2", "3", "4", "5", "6", "7",
1007 /* AltiVec registers. */
1008 "0", "1", "2", "3", "4", "5", "6", "7",
1009 "8", "9", "10", "11", "12", "13", "14", "15",
1010 "16", "17", "18", "19", "20", "21", "22", "23",
1011 "24", "25", "26", "27", "28", "29", "30", "31",
1013 /* SPE registers. */
1014 "spe_acc", "spefscr",
1015 /* Soft frame pointer. */
1019 #ifdef TARGET_REGNAMES
1020 static const char alt_reg_names
[][8] =
1022 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1023 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1024 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1025 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1026 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1027 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1028 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1029 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1030 "mq", "lr", "ctr", "ap",
1031 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1033 /* AltiVec registers. */
1034 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1035 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1036 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1037 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1039 /* SPE registers. */
1040 "spe_acc", "spefscr",
1041 /* Soft frame pointer. */
1046 #ifndef MASK_STRICT_ALIGN
1047 #define MASK_STRICT_ALIGN 0
1049 #ifndef TARGET_PROFILE_KERNEL
1050 #define TARGET_PROFILE_KERNEL 0
1053 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1054 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1056 /* Initialize the GCC target structure. */
1057 #undef TARGET_ATTRIBUTE_TABLE
1058 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1059 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1060 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1062 #undef TARGET_ASM_ALIGNED_DI_OP
1063 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1065 /* Default unaligned ops are only provided for ELF. Find the ops needed
1066 for non-ELF systems. */
1067 #ifndef OBJECT_FORMAT_ELF
1069 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1071 #undef TARGET_ASM_UNALIGNED_HI_OP
1072 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1073 #undef TARGET_ASM_UNALIGNED_SI_OP
1074 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1075 #undef TARGET_ASM_UNALIGNED_DI_OP
1076 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1079 #undef TARGET_ASM_UNALIGNED_HI_OP
1080 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1081 #undef TARGET_ASM_UNALIGNED_SI_OP
1082 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1083 #undef TARGET_ASM_UNALIGNED_DI_OP
1084 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1085 #undef TARGET_ASM_ALIGNED_DI_OP
1086 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1090 /* This hook deals with fixups for relocatable code and DI-mode objects
1092 #undef TARGET_ASM_INTEGER
1093 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1095 #ifdef HAVE_GAS_HIDDEN
1096 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1097 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1100 #undef TARGET_HAVE_TLS
1101 #define TARGET_HAVE_TLS HAVE_AS_TLS
1103 #undef TARGET_CANNOT_FORCE_CONST_MEM
1104 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1106 #undef TARGET_ASM_FUNCTION_PROLOGUE
1107 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1108 #undef TARGET_ASM_FUNCTION_EPILOGUE
1109 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1111 #undef TARGET_SCHED_VARIABLE_ISSUE
1112 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1114 #undef TARGET_SCHED_ISSUE_RATE
1115 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1116 #undef TARGET_SCHED_ADJUST_COST
1117 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1118 #undef TARGET_SCHED_ADJUST_PRIORITY
1119 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1120 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1121 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1122 #undef TARGET_SCHED_INIT
1123 #define TARGET_SCHED_INIT rs6000_sched_init
1124 #undef TARGET_SCHED_FINISH
1125 #define TARGET_SCHED_FINISH rs6000_sched_finish
1126 #undef TARGET_SCHED_REORDER
1127 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1128 #undef TARGET_SCHED_REORDER2
1129 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1131 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1132 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1134 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1135 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1137 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1138 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1139 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1140 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1141 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1142 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1143 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1144 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1146 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1147 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1148 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1149 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1150 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1151 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1152 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1153 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1154 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1155 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1157 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1158 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1160 #undef TARGET_INIT_BUILTINS
1161 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1163 #undef TARGET_EXPAND_BUILTIN
1164 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1166 #undef TARGET_MANGLE_TYPE
1167 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1169 #undef TARGET_INIT_LIBFUNCS
1170 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1173 #undef TARGET_BINDS_LOCAL_P
1174 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1177 #undef TARGET_MS_BITFIELD_LAYOUT_P
1178 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1180 #undef TARGET_ASM_OUTPUT_MI_THUNK
1181 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1183 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1184 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1186 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1187 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1189 #undef TARGET_INVALID_WITHIN_DOLOOP
1190 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1192 #undef TARGET_RTX_COSTS
1193 #define TARGET_RTX_COSTS rs6000_rtx_costs
1194 #undef TARGET_ADDRESS_COST
1195 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1197 #undef TARGET_VECTOR_OPAQUE_P
1198 #define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
1200 #undef TARGET_DWARF_REGISTER_SPAN
1201 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1203 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1204 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1206 /* On rs6000, function arguments are promoted, as are function return
1208 #undef TARGET_PROMOTE_FUNCTION_ARGS
1209 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
1210 #undef TARGET_PROMOTE_FUNCTION_RETURN
1211 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
1213 #undef TARGET_RETURN_IN_MEMORY
1214 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1216 #undef TARGET_SETUP_INCOMING_VARARGS
1217 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1219 /* Always strict argument naming on rs6000. */
1220 #undef TARGET_STRICT_ARGUMENT_NAMING
1221 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1222 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1223 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1224 #undef TARGET_SPLIT_COMPLEX_ARG
1225 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1226 #undef TARGET_MUST_PASS_IN_STACK
1227 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1228 #undef TARGET_PASS_BY_REFERENCE
1229 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1230 #undef TARGET_ARG_PARTIAL_BYTES
1231 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1233 #undef TARGET_BUILD_BUILTIN_VA_LIST
1234 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1236 #undef TARGET_EXPAND_BUILTIN_VA_START
1237 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1239 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1240 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1242 #undef TARGET_EH_RETURN_FILTER_MODE
1243 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1245 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1246 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1248 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1249 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1251 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1252 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1254 #undef TARGET_HANDLE_OPTION
1255 #define TARGET_HANDLE_OPTION rs6000_handle_option
1257 #undef TARGET_DEFAULT_TARGET_FLAGS
1258 #define TARGET_DEFAULT_TARGET_FLAGS \
1261 #undef TARGET_STACK_PROTECT_FAIL
1262 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1264 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1265 The PowerPC architecture requires only weak consistency among
1266 processors--that is, memory accesses between processors need not be
1267 sequentially consistent and memory accesses among processors can occur
1268 in any order. The ability to order memory accesses weakly provides
1269 opportunities for more efficient use of the system bus. Unless a
1270 dependency exists, the 604e allows read operations to precede store
1272 #undef TARGET_RELAXED_ORDERING
1273 #define TARGET_RELAXED_ORDERING true
1276 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1277 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1280 /* Use a 32-bit anchor range. This leads to sequences like:
1282 addis tmp,anchor,high
1285 where tmp itself acts as an anchor, and can be shared between
1286 accesses to the same 64k page. */
1287 #undef TARGET_MIN_ANCHOR_OFFSET
1288 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1289 #undef TARGET_MAX_ANCHOR_OFFSET
1290 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1291 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1292 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1294 #undef TARGET_BUILTIN_RECIPROCAL
1295 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1297 #undef TARGET_EXPAND_TO_RTL_HOOK
1298 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1300 #undef TARGET_INSTANTIATE_DECLS
1301 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1303 struct gcc_target targetm
= TARGET_INITIALIZER
;
1306 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1309 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
1311 /* The GPRs can hold any mode, but values bigger than one register
1312 cannot go past R31. */
1313 if (INT_REGNO_P (regno
))
1314 return INT_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1);
1316 /* The float registers can only hold floating modes and DImode.
1317 This excludes the 32-bit decimal float mode for now. */
1318 if (FP_REGNO_P (regno
))
1320 ((SCALAR_FLOAT_MODE_P (mode
)
1321 && (mode
!= TDmode
|| (regno
% 2) == 0)
1322 && FP_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1))
1323 || (GET_MODE_CLASS (mode
) == MODE_INT
1324 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
)
1325 || (PAIRED_SIMD_REGNO_P (regno
) && TARGET_PAIRED_FLOAT
1326 && PAIRED_VECTOR_MODE (mode
)));
1328 /* The CR register can only hold CC modes. */
1329 if (CR_REGNO_P (regno
))
1330 return GET_MODE_CLASS (mode
) == MODE_CC
;
1332 if (XER_REGNO_P (regno
))
1333 return mode
== PSImode
;
1335 /* AltiVec only in AldyVec registers. */
1336 if (ALTIVEC_REGNO_P (regno
))
1337 return ALTIVEC_VECTOR_MODE (mode
);
1339 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1340 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1343 /* We cannot put TImode anywhere except general register and it must be
1344 able to fit within the register set. */
1346 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1349 /* Initialize rs6000_hard_regno_mode_ok_p table. */
1351 rs6000_init_hard_regno_mode_ok (void)
1355 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
1356 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1357 if (rs6000_hard_regno_mode_ok (r
, m
))
1358 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
1362 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
1365 darwin_rs6000_override_options (void)
1367 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
1369 rs6000_altivec_abi
= 1;
1370 TARGET_ALTIVEC_VRSAVE
= 1;
1371 if (DEFAULT_ABI
== ABI_DARWIN
)
1373 if (MACHO_DYNAMIC_NO_PIC_P
)
1376 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
1379 else if (flag_pic
== 1)
1384 if (TARGET_64BIT
&& ! TARGET_POWERPC64
)
1386 target_flags
|= MASK_POWERPC64
;
1387 warning (0, "-m64 requires PowerPC64 architecture, enabling");
1391 rs6000_default_long_calls
= 1;
1392 target_flags
|= MASK_SOFT_FLOAT
;
1395 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
1397 if (!flag_mkernel
&& !flag_apple_kext
1399 && ! (target_flags_explicit
& MASK_ALTIVEC
))
1400 target_flags
|= MASK_ALTIVEC
;
1402 /* Unless the user (not the configurer) has explicitly overridden
1403 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
1404 G4 unless targetting the kernel. */
1407 && strverscmp (darwin_macosx_version_min
, "10.5") >= 0
1408 && ! (target_flags_explicit
& MASK_ALTIVEC
)
1409 && ! rs6000_select
[1].string
)
1411 target_flags
|= MASK_ALTIVEC
;
1416 /* If not otherwise specified by a target, make 'long double' equivalent to
1419 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1420 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1423 /* Override command line options. Mostly we process the processor
1424 type and sometimes adjust other TARGET_ options. */
1427 rs6000_override_options (const char *default_cpu
)
1430 struct rs6000_cpu_select
*ptr
;
1433 /* Simplifications for entries below. */
1436 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
1437 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
1440 /* This table occasionally claims that a processor does not support
1441 a particular feature even though it does, but the feature is slower
1442 than the alternative. Thus, it shouldn't be relied on as a
1443 complete description of the processor's support.
1445 Please keep this list in order, and don't forget to update the
1446 documentation in invoke.texi when adding a new processor or
1450 const char *const name
; /* Canonical processor name. */
1451 const enum processor_type processor
; /* Processor type enum value. */
1452 const int target_enable
; /* Target flags to enable. */
1453 } const processor_target_table
[]
1454 = {{"401", PROCESSOR_PPC403
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1455 {"403", PROCESSOR_PPC403
,
1456 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_STRICT_ALIGN
},
1457 {"405", PROCESSOR_PPC405
,
1458 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1459 {"405fp", PROCESSOR_PPC405
,
1460 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1461 {"440", PROCESSOR_PPC440
,
1462 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1463 {"440fp", PROCESSOR_PPC440
,
1464 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1465 {"464", PROCESSOR_PPC440
,
1466 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1467 {"464fp", PROCESSOR_PPC440
,
1468 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1469 {"505", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
},
1470 {"601", PROCESSOR_PPC601
,
1471 MASK_POWER
| POWERPC_BASE_MASK
| MASK_MULTIPLE
| MASK_STRING
},
1472 {"602", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1473 {"603", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1474 {"603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1475 {"604", PROCESSOR_PPC604
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1476 {"604e", PROCESSOR_PPC604e
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1477 {"620", PROCESSOR_PPC620
,
1478 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1479 {"630", PROCESSOR_PPC630
,
1480 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1481 {"740", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1482 {"7400", PROCESSOR_PPC7400
, POWERPC_7400_MASK
},
1483 {"7450", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1484 {"750", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1485 {"801", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1486 {"821", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1487 {"823", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1488 {"8540", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
},
1489 /* 8548 has a dummy entry for now. */
1490 {"8548", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
},
1491 {"e300c2", PROCESSOR_PPCE300C2
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1492 {"e300c3", PROCESSOR_PPCE300C3
, POWERPC_BASE_MASK
},
1493 {"e500mc", PROCESSOR_PPCE500MC
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1494 {"860", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1495 {"970", PROCESSOR_POWER4
,
1496 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1497 {"cell", PROCESSOR_CELL
,
1498 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1499 {"common", PROCESSOR_COMMON
, MASK_NEW_MNEMONICS
},
1500 {"ec603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1501 {"G3", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1502 {"G4", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1503 {"G5", PROCESSOR_POWER4
,
1504 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1505 {"power", PROCESSOR_POWER
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1506 {"power2", PROCESSOR_POWER
,
1507 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1508 {"power3", PROCESSOR_PPC630
,
1509 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1510 {"power4", PROCESSOR_POWER4
,
1511 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1513 {"power5", PROCESSOR_POWER5
,
1514 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1515 | MASK_MFCRF
| MASK_POPCNTB
},
1516 {"power5+", PROCESSOR_POWER5
,
1517 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1518 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
},
1519 {"power6", PROCESSOR_POWER6
,
1520 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1521 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
},
1522 {"power6x", PROCESSOR_POWER6
,
1523 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_PPC_GFXOPT
1524 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
1526 {"power7", PROCESSOR_POWER5
,
1527 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_PPC_GPOPT
| MASK_MFCRF
1528 | MASK_POPCNTB
| MASK_FPRND
| MASK_CMPB
| MASK_DFP
},
1529 {"powerpc", PROCESSOR_POWERPC
, POWERPC_BASE_MASK
},
1530 {"powerpc64", PROCESSOR_POWERPC64
,
1531 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1532 {"rios", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1533 {"rios1", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1534 {"rios2", PROCESSOR_RIOS2
,
1535 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1536 {"rsc", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1537 {"rsc1", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1538 {"rs64", PROCESSOR_RS64A
,
1539 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
}
1542 const size_t ptt_size
= ARRAY_SIZE (processor_target_table
);
1544 /* Some OSs don't support saving the high part of 64-bit registers on
1545 context switch. Other OSs don't support saving Altivec registers.
1546 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1547 settings; if the user wants either, the user must explicitly specify
1548 them and we won't interfere with the user's specification. */
1551 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
1552 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
| MASK_STRICT_ALIGN
1553 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
1554 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_MULHW
1555 | MASK_DLMZB
| MASK_CMPB
| MASK_MFPGPR
| MASK_DFP
)
1558 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
1559 #ifdef OS_MISSING_POWERPC64
1560 if (OS_MISSING_POWERPC64
)
1561 set_masks
&= ~MASK_POWERPC64
;
1563 #ifdef OS_MISSING_ALTIVEC
1564 if (OS_MISSING_ALTIVEC
)
1565 set_masks
&= ~MASK_ALTIVEC
;
1568 /* Don't override by the processor default if given explicitly. */
1569 set_masks
&= ~target_flags_explicit
;
1571 /* Identify the processor type. */
1572 rs6000_select
[0].string
= default_cpu
;
1573 rs6000_cpu
= TARGET_POWERPC64
? PROCESSOR_DEFAULT64
: PROCESSOR_DEFAULT
;
1575 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
1577 ptr
= &rs6000_select
[i
];
1578 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
1580 for (j
= 0; j
< ptt_size
; j
++)
1581 if (! strcmp (ptr
->string
, processor_target_table
[j
].name
))
1583 if (ptr
->set_tune_p
)
1584 rs6000_cpu
= processor_target_table
[j
].processor
;
1586 if (ptr
->set_arch_p
)
1588 target_flags
&= ~set_masks
;
1589 target_flags
|= (processor_target_table
[j
].target_enable
1596 error ("bad value (%s) for %s switch", ptr
->string
, ptr
->name
);
1600 if ((TARGET_E500
|| rs6000_cpu
== PROCESSOR_PPCE500MC
)
1601 && !rs6000_explicit_options
.isel
)
1604 if (rs6000_cpu
== PROCESSOR_PPCE300C2
|| rs6000_cpu
== PROCESSOR_PPCE300C3
1605 || rs6000_cpu
== PROCESSOR_PPCE500MC
)
1608 error ("AltiVec not supported in this target");
1610 error ("Spe not supported in this target");
1613 /* If we are optimizing big endian systems for space, use the load/store
1614 multiple and string instructions. */
1615 if (BYTES_BIG_ENDIAN
&& optimize_size
)
1616 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
1618 /* Don't allow -mmultiple or -mstring on little endian systems
1619 unless the cpu is a 750, because the hardware doesn't support the
1620 instructions used in little endian mode, and causes an alignment
1621 trap. The 750 does not cause an alignment trap (except when the
1622 target is unaligned). */
1624 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
1626 if (TARGET_MULTIPLE
)
1628 target_flags
&= ~MASK_MULTIPLE
;
1629 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
1630 warning (0, "-mmultiple is not supported on little endian systems");
1635 target_flags
&= ~MASK_STRING
;
1636 if ((target_flags_explicit
& MASK_STRING
) != 0)
1637 warning (0, "-mstring is not supported on little endian systems");
1641 /* Set debug flags */
1642 if (rs6000_debug_name
)
1644 if (! strcmp (rs6000_debug_name
, "all"))
1645 rs6000_debug_stack
= rs6000_debug_arg
= 1;
1646 else if (! strcmp (rs6000_debug_name
, "stack"))
1647 rs6000_debug_stack
= 1;
1648 else if (! strcmp (rs6000_debug_name
, "arg"))
1649 rs6000_debug_arg
= 1;
1651 error ("unknown -mdebug-%s switch", rs6000_debug_name
);
1654 if (rs6000_traceback_name
)
1656 if (! strncmp (rs6000_traceback_name
, "full", 4))
1657 rs6000_traceback
= traceback_full
;
1658 else if (! strncmp (rs6000_traceback_name
, "part", 4))
1659 rs6000_traceback
= traceback_part
;
1660 else if (! strncmp (rs6000_traceback_name
, "no", 2))
1661 rs6000_traceback
= traceback_none
;
1663 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
1664 rs6000_traceback_name
);
1667 if (!rs6000_explicit_options
.long_double
)
1668 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1670 #ifndef POWERPC_LINUX
1671 if (!rs6000_explicit_options
.ieee
)
1672 rs6000_ieeequad
= 1;
1675 /* Enable Altivec ABI for AIX -maltivec. */
1676 if (TARGET_XCOFF
&& TARGET_ALTIVEC
)
1677 rs6000_altivec_abi
= 1;
1679 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
1680 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
1681 be explicitly overridden in either case. */
1684 if (!rs6000_explicit_options
.altivec_abi
1685 && (TARGET_64BIT
|| TARGET_ALTIVEC
))
1686 rs6000_altivec_abi
= 1;
1688 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
1689 if (!rs6000_explicit_options
.vrsave
)
1690 TARGET_ALTIVEC_VRSAVE
= rs6000_altivec_abi
;
1693 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1694 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
1696 rs6000_darwin64_abi
= 1;
1698 darwin_one_byte_bool
= 1;
1700 /* Default to natural alignment, for better performance. */
1701 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
1704 /* Place FP constants in the constant pool instead of TOC
1705 if section anchors enabled. */
1706 if (flag_section_anchors
)
1707 TARGET_NO_FP_IN_TOC
= 1;
1709 /* Handle -mtls-size option. */
1710 rs6000_parse_tls_size_option ();
1712 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1713 SUBTARGET_OVERRIDE_OPTIONS
;
1715 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1716 SUBSUBTARGET_OVERRIDE_OPTIONS
;
1718 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
1719 SUB3TARGET_OVERRIDE_OPTIONS
;
1722 if (TARGET_E500
|| rs6000_cpu
== PROCESSOR_PPCE500MC
)
1724 /* The e500 and e500mc do not have string instructions, and we set
1725 MASK_STRING above when optimizing for size. */
1726 if ((target_flags
& MASK_STRING
) != 0)
1727 target_flags
= target_flags
& ~MASK_STRING
;
1729 else if (rs6000_select
[1].string
!= NULL
)
1731 /* For the powerpc-eabispe configuration, we set all these by
1732 default, so let's unset them if we manually set another
1733 CPU that is not the E500. */
1734 if (!rs6000_explicit_options
.spe_abi
)
1736 if (!rs6000_explicit_options
.spe
)
1738 if (!rs6000_explicit_options
.float_gprs
)
1739 rs6000_float_gprs
= 0;
1740 if (!rs6000_explicit_options
.isel
)
1744 /* Detect invalid option combinations with E500. */
1747 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
1748 && rs6000_cpu
!= PROCESSOR_POWER5
1749 && rs6000_cpu
!= PROCESSOR_POWER6
1750 && rs6000_cpu
!= PROCESSOR_CELL
);
1751 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
1752 || rs6000_cpu
== PROCESSOR_POWER5
);
1753 rs6000_align_branch_targets
= (rs6000_cpu
== PROCESSOR_POWER4
1754 || rs6000_cpu
== PROCESSOR_POWER5
1755 || rs6000_cpu
== PROCESSOR_POWER6
);
1757 rs6000_sched_restricted_insns_priority
1758 = (rs6000_sched_groups
? 1 : 0);
1760 /* Handle -msched-costly-dep option. */
1761 rs6000_sched_costly_dep
1762 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
1764 if (rs6000_sched_costly_dep_str
)
1766 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
1767 rs6000_sched_costly_dep
= no_dep_costly
;
1768 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
1769 rs6000_sched_costly_dep
= all_deps_costly
;
1770 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
1771 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
1772 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
1773 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
1775 rs6000_sched_costly_dep
= 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
= atoi (rs6000_sched_insert_nops_str
);
1794 #ifdef TARGET_REGNAMES
1795 /* If the user desires alternate register names, copy in the
1796 alternate names now. */
1797 if (TARGET_REGNAMES
)
1798 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
1801 /* Set aix_struct_return last, after the ABI is determined.
1802 If -maix-struct-return or -msvr4-struct-return was explicitly
1803 used, don't override with the ABI default. */
1804 if (!rs6000_explicit_options
.aix_struct_ret
)
1805 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
1807 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
1808 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
1811 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
1813 /* We can only guarantee the availability of DI pseudo-ops when
1814 assembling for 64-bit targets. */
1817 targetm
.asm_out
.aligned_op
.di
= NULL
;
1818 targetm
.asm_out
.unaligned_op
.di
= NULL
;
1821 /* Set branch target alignment, if not optimizing for size. */
1824 /* Cell wants to be aligned 8byte for dual issue. */
1825 if (rs6000_cpu
== PROCESSOR_CELL
)
1827 if (align_functions
<= 0)
1828 align_functions
= 8;
1829 if (align_jumps
<= 0)
1831 if (align_loops
<= 0)
1834 if (rs6000_align_branch_targets
)
1836 if (align_functions
<= 0)
1837 align_functions
= 16;
1838 if (align_jumps
<= 0)
1840 if (align_loops
<= 0)
1843 if (align_jumps_max_skip
<= 0)
1844 align_jumps_max_skip
= 15;
1845 if (align_loops_max_skip
<= 0)
1846 align_loops_max_skip
= 15;
1849 /* Arrange to save and restore machine status around nested functions. */
1850 init_machine_status
= rs6000_init_machine_status
;
1852 /* We should always be splitting complex arguments, but we can't break
1853 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1854 if (DEFAULT_ABI
!= ABI_AIX
)
1855 targetm
.calls
.split_complex_arg
= NULL
;
1857 /* Initialize rs6000_cost with the appropriate target costs. */
1859 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
1863 case PROCESSOR_RIOS1
:
1864 rs6000_cost
= &rios1_cost
;
1867 case PROCESSOR_RIOS2
:
1868 rs6000_cost
= &rios2_cost
;
1871 case PROCESSOR_RS64A
:
1872 rs6000_cost
= &rs64a_cost
;
1875 case PROCESSOR_MPCCORE
:
1876 rs6000_cost
= &mpccore_cost
;
1879 case PROCESSOR_PPC403
:
1880 rs6000_cost
= &ppc403_cost
;
1883 case PROCESSOR_PPC405
:
1884 rs6000_cost
= &ppc405_cost
;
1887 case PROCESSOR_PPC440
:
1888 rs6000_cost
= &ppc440_cost
;
1891 case PROCESSOR_PPC601
:
1892 rs6000_cost
= &ppc601_cost
;
1895 case PROCESSOR_PPC603
:
1896 rs6000_cost
= &ppc603_cost
;
1899 case PROCESSOR_PPC604
:
1900 rs6000_cost
= &ppc604_cost
;
1903 case PROCESSOR_PPC604e
:
1904 rs6000_cost
= &ppc604e_cost
;
1907 case PROCESSOR_PPC620
:
1908 rs6000_cost
= &ppc620_cost
;
1911 case PROCESSOR_PPC630
:
1912 rs6000_cost
= &ppc630_cost
;
1915 case PROCESSOR_CELL
:
1916 rs6000_cost
= &ppccell_cost
;
1919 case PROCESSOR_PPC750
:
1920 case PROCESSOR_PPC7400
:
1921 rs6000_cost
= &ppc750_cost
;
1924 case PROCESSOR_PPC7450
:
1925 rs6000_cost
= &ppc7450_cost
;
1928 case PROCESSOR_PPC8540
:
1929 rs6000_cost
= &ppc8540_cost
;
1932 case PROCESSOR_PPCE300C2
:
1933 case PROCESSOR_PPCE300C3
:
1934 rs6000_cost
= &ppce300c2c3_cost
;
1937 case PROCESSOR_PPCE500MC
:
1938 rs6000_cost
= &ppce500mc_cost
;
1941 case PROCESSOR_POWER4
:
1942 case PROCESSOR_POWER5
:
1943 rs6000_cost
= &power4_cost
;
1946 case PROCESSOR_POWER6
:
1947 rs6000_cost
= &power6_cost
;
1954 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES
))
1955 set_param_value ("simultaneous-prefetches",
1956 rs6000_cost
->simultaneous_prefetches
);
1957 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE
))
1958 set_param_value ("l1-cache-size", rs6000_cost
->l1_cache_size
);
1959 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE
))
1960 set_param_value ("l1-cache-line-size", rs6000_cost
->cache_line_size
);
1961 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE
))
1962 set_param_value ("l2-cache-size", rs6000_cost
->l2_cache_size
);
1964 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
1965 can be optimized to ap = __builtin_next_arg (0). */
1966 if (DEFAULT_ABI
!= ABI_V4
)
1967 targetm
.expand_builtin_va_start
= NULL
;
1969 /* Set up single/double float flags.
1970 If TARGET_HARD_FLOAT is set, but neither single or double is set,
1971 then set both flags. */
1972 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
1973 && rs6000_single_float
== 0 && rs6000_double_float
== 0)
1974 rs6000_single_float
= rs6000_double_float
= 1;
1976 /* Reset single and double FP flags if target is E500. */
1979 rs6000_single_float
= rs6000_double_float
= 0;
1980 if (TARGET_E500_SINGLE
)
1981 rs6000_single_float
= 1;
1982 if (TARGET_E500_DOUBLE
)
1983 rs6000_single_float
= rs6000_double_float
= 1;
1986 rs6000_init_hard_regno_mode_ok ();
1989 /* Implement targetm.vectorize.builtin_mask_for_load. */
1991 rs6000_builtin_mask_for_load (void)
1994 return altivec_builtin_mask_for_load
;
1999 /* Implement targetm.vectorize.builtin_conversion.
2000 Returns a decl of a function that implements conversion of an integer vector
2001 into a floating-point vector, or vice-versa. TYPE is the type of the integer
2002 side of the conversion.
2003 Return NULL_TREE if it is not available. */
2005 rs6000_builtin_conversion (enum tree_code code
, tree type
)
2007 if (!TARGET_ALTIVEC
)
2012 case FIX_TRUNC_EXPR
:
2013 switch (TYPE_MODE (type
))
2016 return TYPE_UNSIGNED (type
)
2017 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCTUXS
]
2018 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCTSXS
];
2024 switch (TYPE_MODE (type
))
2027 return TYPE_UNSIGNED (type
)
2028 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCFUX
]
2029 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCFSX
];
2039 /* Implement targetm.vectorize.builtin_mul_widen_even. */
2041 rs6000_builtin_mul_widen_even (tree type
)
2043 if (!TARGET_ALTIVEC
)
2046 switch (TYPE_MODE (type
))
2049 return TYPE_UNSIGNED (type
)
2050 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUH
]
2051 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESH
];
2054 return TYPE_UNSIGNED (type
)
2055 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUB
]
2056 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESB
];
2062 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
2064 rs6000_builtin_mul_widen_odd (tree type
)
2066 if (!TARGET_ALTIVEC
)
2069 switch (TYPE_MODE (type
))
2072 return TYPE_UNSIGNED (type
)
2073 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUH
]
2074 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSH
];
2077 return TYPE_UNSIGNED (type
)
2078 ? rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUB
]
2079 : rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSB
];
2086 /* Return true iff, data reference of TYPE can reach vector alignment (16)
2087 after applying N number of iterations. This routine does not determine
2088 how may iterations are required to reach desired alignment. */
2091 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED
, bool is_packed
)
2098 if (rs6000_alignment_flags
== MASK_ALIGN_NATURAL
)
2101 if (rs6000_alignment_flags
== MASK_ALIGN_POWER
)
2111 /* Assuming that all other types are naturally aligned. CHECKME! */
2116 /* Implement targetm.vectorize.builtin_vec_perm. */
2118 rs6000_builtin_vec_perm (tree type
, tree
*mask_element_type
)
2122 *mask_element_type
= unsigned_char_type_node
;
2124 switch (TYPE_MODE (type
))
2127 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_16QI
];
2131 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_8HI
];
2135 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SI
];
2139 d
= rs6000_builtin_decls
[ALTIVEC_BUILTIN_VPERM_4SF
];
2150 /* Handle generic options of the form -mfoo=yes/no.
2151 NAME is the option name.
2152 VALUE is the option value.
2153 FLAG is the pointer to the flag where to store a 1 or 0, depending on
2154 whether the option value is 'yes' or 'no' respectively. */
2156 rs6000_parse_yes_no_option (const char *name
, const char *value
, int *flag
)
2160 else if (!strcmp (value
, "yes"))
2162 else if (!strcmp (value
, "no"))
2165 error ("unknown -m%s= option specified: '%s'", name
, value
);
2168 /* Validate and record the size specified with the -mtls-size option. */
2171 rs6000_parse_tls_size_option (void)
2173 if (rs6000_tls_size_string
== 0)
2175 else if (strcmp (rs6000_tls_size_string
, "16") == 0)
2176 rs6000_tls_size
= 16;
2177 else if (strcmp (rs6000_tls_size_string
, "32") == 0)
2178 rs6000_tls_size
= 32;
2179 else if (strcmp (rs6000_tls_size_string
, "64") == 0)
2180 rs6000_tls_size
= 64;
2182 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string
);
2186 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
2188 if (DEFAULT_ABI
== ABI_DARWIN
)
2189 /* The Darwin libraries never set errno, so we might as well
2190 avoid calling them when that's the only reason we would. */
2191 flag_errno_math
= 0;
2193 /* Double growth factor to counter reduced min jump length. */
2194 set_param_value ("max-grow-copy-bb-insns", 16);
2196 /* Enable section anchors by default.
2197 Skip section anchors for Objective C and Objective C++
2198 until front-ends fixed. */
2199 if (!TARGET_MACHO
&& lang_hooks
.name
[4] != 'O')
2200 flag_section_anchors
= 2;
2203 /* Implement TARGET_HANDLE_OPTION. */
2206 rs6000_handle_option (size_t code
, const char *arg
, int value
)
2211 target_flags
&= ~(MASK_POWER
| MASK_POWER2
2212 | MASK_MULTIPLE
| MASK_STRING
);
2213 target_flags_explicit
|= (MASK_POWER
| MASK_POWER2
2214 | MASK_MULTIPLE
| MASK_STRING
);
2216 case OPT_mno_powerpc
:
2217 target_flags
&= ~(MASK_POWERPC
| MASK_PPC_GPOPT
2218 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
2219 target_flags_explicit
|= (MASK_POWERPC
| MASK_PPC_GPOPT
2220 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
2223 target_flags
&= ~MASK_MINIMAL_TOC
;
2224 TARGET_NO_FP_IN_TOC
= 0;
2225 TARGET_NO_SUM_IN_TOC
= 0;
2226 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2227 #ifdef TARGET_USES_SYSV4_OPT
2228 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
2229 just the same as -mminimal-toc. */
2230 target_flags
|= MASK_MINIMAL_TOC
;
2231 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2235 #ifdef TARGET_USES_SYSV4_OPT
2237 /* Make -mtoc behave like -mminimal-toc. */
2238 target_flags
|= MASK_MINIMAL_TOC
;
2239 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2243 #ifdef TARGET_USES_AIX64_OPT
2248 target_flags
|= MASK_POWERPC64
| MASK_POWERPC
;
2249 target_flags
|= ~target_flags_explicit
& MASK_PPC_GFXOPT
;
2250 target_flags_explicit
|= MASK_POWERPC64
| MASK_POWERPC
;
2253 #ifdef TARGET_USES_AIX64_OPT
2258 target_flags
&= ~MASK_POWERPC64
;
2259 target_flags_explicit
|= MASK_POWERPC64
;
2262 case OPT_minsert_sched_nops_
:
2263 rs6000_sched_insert_nops_str
= arg
;
2266 case OPT_mminimal_toc
:
2269 TARGET_NO_FP_IN_TOC
= 0;
2270 TARGET_NO_SUM_IN_TOC
= 0;
2277 target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
2278 target_flags_explicit
|= (MASK_MULTIPLE
| MASK_STRING
);
2285 target_flags
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
2286 target_flags_explicit
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
2290 case OPT_mpowerpc_gpopt
:
2291 case OPT_mpowerpc_gfxopt
:
2294 target_flags
|= MASK_POWERPC
;
2295 target_flags_explicit
|= MASK_POWERPC
;
2299 case OPT_maix_struct_return
:
2300 case OPT_msvr4_struct_return
:
2301 rs6000_explicit_options
.aix_struct_ret
= true;
2305 rs6000_explicit_options
.vrsave
= true;
2306 rs6000_parse_yes_no_option ("vrsave", arg
, &(TARGET_ALTIVEC_VRSAVE
));
2310 rs6000_explicit_options
.isel
= true;
2311 rs6000_isel
= value
;
2315 rs6000_explicit_options
.isel
= true;
2316 rs6000_parse_yes_no_option ("isel", arg
, &(rs6000_isel
));
2320 rs6000_explicit_options
.spe
= true;
2325 rs6000_explicit_options
.spe
= true;
2326 rs6000_parse_yes_no_option ("spe", arg
, &(rs6000_spe
));
2330 rs6000_debug_name
= arg
;
2333 #ifdef TARGET_USES_SYSV4_OPT
2335 rs6000_abi_name
= arg
;
2339 rs6000_sdata_name
= arg
;
2342 case OPT_mtls_size_
:
2343 rs6000_tls_size_string
= arg
;
2346 case OPT_mrelocatable
:
2349 target_flags
|= MASK_MINIMAL_TOC
;
2350 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2351 TARGET_NO_FP_IN_TOC
= 1;
2355 case OPT_mrelocatable_lib
:
2358 target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
2359 target_flags_explicit
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
2360 TARGET_NO_FP_IN_TOC
= 1;
2364 target_flags
&= ~MASK_RELOCATABLE
;
2365 target_flags_explicit
|= MASK_RELOCATABLE
;
2371 if (!strcmp (arg
, "altivec"))
2373 rs6000_explicit_options
.altivec_abi
= true;
2374 rs6000_altivec_abi
= 1;
2376 /* Enabling the AltiVec ABI turns off the SPE ABI. */
2379 else if (! strcmp (arg
, "no-altivec"))
2381 rs6000_explicit_options
.altivec_abi
= true;
2382 rs6000_altivec_abi
= 0;
2384 else if (! strcmp (arg
, "spe"))
2386 rs6000_explicit_options
.spe_abi
= true;
2388 rs6000_altivec_abi
= 0;
2389 if (!TARGET_SPE_ABI
)
2390 error ("not configured for ABI: '%s'", arg
);
2392 else if (! strcmp (arg
, "no-spe"))
2394 rs6000_explicit_options
.spe_abi
= true;
2398 /* These are here for testing during development only, do not
2399 document in the manual please. */
2400 else if (! strcmp (arg
, "d64"))
2402 rs6000_darwin64_abi
= 1;
2403 warning (0, "Using darwin64 ABI");
2405 else if (! strcmp (arg
, "d32"))
2407 rs6000_darwin64_abi
= 0;
2408 warning (0, "Using old darwin ABI");
2411 else if (! strcmp (arg
, "ibmlongdouble"))
2413 rs6000_explicit_options
.ieee
= true;
2414 rs6000_ieeequad
= 0;
2415 warning (0, "Using IBM extended precision long double");
2417 else if (! strcmp (arg
, "ieeelongdouble"))
2419 rs6000_explicit_options
.ieee
= true;
2420 rs6000_ieeequad
= 1;
2421 warning (0, "Using IEEE extended precision long double");
2426 error ("unknown ABI specified: '%s'", arg
);
2432 rs6000_select
[1].string
= arg
;
2436 rs6000_select
[2].string
= arg
;
2439 case OPT_mtraceback_
:
2440 rs6000_traceback_name
= arg
;
2443 case OPT_mfloat_gprs_
:
2444 rs6000_explicit_options
.float_gprs
= true;
2445 if (! strcmp (arg
, "yes") || ! strcmp (arg
, "single"))
2446 rs6000_float_gprs
= 1;
2447 else if (! strcmp (arg
, "double"))
2448 rs6000_float_gprs
= 2;
2449 else if (! strcmp (arg
, "no"))
2450 rs6000_float_gprs
= 0;
2453 error ("invalid option for -mfloat-gprs: '%s'", arg
);
2458 case OPT_mlong_double_
:
2459 rs6000_explicit_options
.long_double
= true;
2460 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2461 if (value
!= 64 && value
!= 128)
2463 error ("Unknown switch -mlong-double-%s", arg
);
2464 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2468 rs6000_long_double_type_size
= value
;
2471 case OPT_msched_costly_dep_
:
2472 rs6000_sched_costly_dep_str
= arg
;
2476 rs6000_explicit_options
.alignment
= true;
2477 if (! strcmp (arg
, "power"))
2479 /* On 64-bit Darwin, power alignment is ABI-incompatible with
2480 some C library functions, so warn about it. The flag may be
2481 useful for performance studies from time to time though, so
2482 don't disable it entirely. */
2483 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
2484 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2485 " it is incompatible with the installed C and C++ libraries");
2486 rs6000_alignment_flags
= MASK_ALIGN_POWER
;
2488 else if (! strcmp (arg
, "natural"))
2489 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
2492 error ("unknown -malign-XXXXX option specified: '%s'", arg
);
2497 case OPT_msingle_float
:
2498 if (!TARGET_SINGLE_FPU
)
2499 warning (0, "-msingle-float option equivalent to -mhard-float");
2500 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
2501 rs6000_double_float
= 0;
2502 target_flags
&= ~MASK_SOFT_FLOAT
;
2503 target_flags_explicit
|= MASK_SOFT_FLOAT
;
2506 case OPT_mdouble_float
:
2507 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
2508 rs6000_single_float
= 1;
2509 target_flags
&= ~MASK_SOFT_FLOAT
;
2510 target_flags_explicit
|= MASK_SOFT_FLOAT
;
2513 case OPT_msimple_fpu
:
2514 if (!TARGET_SINGLE_FPU
)
2515 warning (0, "-msimple-fpu option ignored");
2518 case OPT_mhard_float
:
2519 /* -mhard_float implies -msingle-float and -mdouble-float. */
2520 rs6000_single_float
= rs6000_double_float
= 1;
2523 case OPT_msoft_float
:
2524 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
2525 rs6000_single_float
= rs6000_double_float
= 0;
2531 /* Do anything needed at the start of the asm file. */
2534 rs6000_file_start (void)
2538 const char *start
= buffer
;
2539 struct rs6000_cpu_select
*ptr
;
2540 const char *default_cpu
= TARGET_CPU_DEFAULT
;
2541 FILE *file
= asm_out_file
;
2543 default_file_start ();
2545 #ifdef TARGET_BI_ARCH
2546 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
2550 if (flag_verbose_asm
)
2552 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
2553 rs6000_select
[0].string
= default_cpu
;
2555 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
2557 ptr
= &rs6000_select
[i
];
2558 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
2560 fprintf (file
, "%s %s%s", start
, ptr
->name
, ptr
->string
);
2565 if (PPC405_ERRATUM77
)
2567 fprintf (file
, "%s PPC405CR_ERRATUM77", start
);
2571 #ifdef USING_ELFOS_H
2572 switch (rs6000_sdata
)
2574 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
2575 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
2576 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
2577 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
2580 if (rs6000_sdata
&& g_switch_value
)
2582 fprintf (file
, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED
, start
,
2592 #ifdef HAVE_AS_GNU_ATTRIBUTE
2593 if (TARGET_32BIT
&& DEFAULT_ABI
== ABI_V4
)
2595 fprintf (file
, "\t.gnu_attribute 4, %d\n",
2596 ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
) ? 1
2597 : (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_SINGLE_FLOAT
) ? 3
2599 fprintf (file
, "\t.gnu_attribute 8, %d\n",
2600 (TARGET_ALTIVEC_ABI
? 2
2601 : TARGET_SPE_ABI
? 3
2606 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
2608 switch_to_section (toc_section
);
2609 switch_to_section (text_section
);
2614 /* Return nonzero if this function is known to have a null epilogue. */
2617 direct_return (void)
2619 if (reload_completed
)
2621 rs6000_stack_t
*info
= rs6000_stack_info ();
2623 if (info
->first_gp_reg_save
== 32
2624 && info
->first_fp_reg_save
== 64
2625 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
2626 && ! info
->lr_save_p
2627 && ! info
->cr_save_p
2628 && info
->vrsave_mask
== 0
2636 /* Return the number of instructions it takes to form a constant in an
2637 integer register. */
2640 num_insns_constant_wide (HOST_WIDE_INT value
)
2642 /* signed constant loadable with {cal|addi} */
2643 if ((unsigned HOST_WIDE_INT
) (value
+ 0x8000) < 0x10000)
2646 /* constant loadable with {cau|addis} */
2647 else if ((value
& 0xffff) == 0
2648 && (value
>> 31 == -1 || value
>> 31 == 0))
2651 #if HOST_BITS_PER_WIDE_INT == 64
2652 else if (TARGET_POWERPC64
)
2654 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
2655 HOST_WIDE_INT high
= value
>> 31;
2657 if (high
== 0 || high
== -1)
2663 return num_insns_constant_wide (high
) + 1;
2665 return (num_insns_constant_wide (high
)
2666 + num_insns_constant_wide (low
) + 1);
2675 num_insns_constant (rtx op
, enum machine_mode mode
)
2677 HOST_WIDE_INT low
, high
;
2679 switch (GET_CODE (op
))
2682 #if HOST_BITS_PER_WIDE_INT == 64
2683 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
2684 && mask64_operand (op
, mode
))
2688 return num_insns_constant_wide (INTVAL (op
));
2691 if (mode
== SFmode
|| mode
== SDmode
)
2696 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2697 if (DECIMAL_FLOAT_MODE_P (mode
))
2698 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
2700 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
2701 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
2704 if (mode
== VOIDmode
|| mode
== DImode
)
2706 high
= CONST_DOUBLE_HIGH (op
);
2707 low
= CONST_DOUBLE_LOW (op
);
2714 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2715 if (DECIMAL_FLOAT_MODE_P (mode
))
2716 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, l
);
2718 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
2719 high
= l
[WORDS_BIG_ENDIAN
== 0];
2720 low
= l
[WORDS_BIG_ENDIAN
!= 0];
2724 return (num_insns_constant_wide (low
)
2725 + num_insns_constant_wide (high
));
2728 if ((high
== 0 && low
>= 0)
2729 || (high
== -1 && low
< 0))
2730 return num_insns_constant_wide (low
);
2732 else if (mask64_operand (op
, mode
))
2736 return num_insns_constant_wide (high
) + 1;
2739 return (num_insns_constant_wide (high
)
2740 + num_insns_constant_wide (low
) + 1);
2748 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
2749 If the mode of OP is MODE_VECTOR_INT, this simply returns the
2750 corresponding element of the vector, but for V4SFmode and V2SFmode,
2751 the corresponding "float" is interpreted as an SImode integer. */
2754 const_vector_elt_as_int (rtx op
, unsigned int elt
)
2756 rtx tmp
= CONST_VECTOR_ELT (op
, elt
);
2757 if (GET_MODE (op
) == V4SFmode
2758 || GET_MODE (op
) == V2SFmode
)
2759 tmp
= gen_lowpart (SImode
, tmp
);
2760 return INTVAL (tmp
);
2763 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
2764 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2765 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2766 all items are set to the same value and contain COPIES replicas of the
2767 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2768 operand and the others are set to the value of the operand's msb. */
2771 vspltis_constant (rtx op
, unsigned step
, unsigned copies
)
2773 enum machine_mode mode
= GET_MODE (op
);
2774 enum machine_mode inner
= GET_MODE_INNER (mode
);
2777 unsigned nunits
= GET_MODE_NUNITS (mode
);
2778 unsigned bitsize
= GET_MODE_BITSIZE (inner
);
2779 unsigned mask
= GET_MODE_MASK (inner
);
2781 HOST_WIDE_INT val
= const_vector_elt_as_int (op
, nunits
- 1);
2782 HOST_WIDE_INT splat_val
= val
;
2783 HOST_WIDE_INT msb_val
= val
> 0 ? 0 : -1;
2785 /* Construct the value to be splatted, if possible. If not, return 0. */
2786 for (i
= 2; i
<= copies
; i
*= 2)
2788 HOST_WIDE_INT small_val
;
2790 small_val
= splat_val
>> bitsize
;
2792 if (splat_val
!= ((small_val
<< bitsize
) | (small_val
& mask
)))
2794 splat_val
= small_val
;
2797 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2798 if (EASY_VECTOR_15 (splat_val
))
2801 /* Also check if we can splat, and then add the result to itself. Do so if
2802 the value is positive, of if the splat instruction is using OP's mode;
2803 for splat_val < 0, the splat and the add should use the same mode. */
2804 else if (EASY_VECTOR_15_ADD_SELF (splat_val
)
2805 && (splat_val
>= 0 || (step
== 1 && copies
== 1)))
2811 /* Check if VAL is present in every STEP-th element, and the
2812 other elements are filled with its most significant bit. */
2813 for (i
= 0; i
< nunits
- 1; ++i
)
2815 HOST_WIDE_INT desired_val
;
2816 if (((i
+ 1) & (step
- 1)) == 0)
2819 desired_val
= msb_val
;
2821 if (desired_val
!= const_vector_elt_as_int (op
, i
))
2829 /* Return true if OP is of the given MODE and can be synthesized
2830 with a vspltisb, vspltish or vspltisw. */
2833 easy_altivec_constant (rtx op
, enum machine_mode mode
)
2835 unsigned step
, copies
;
2837 if (mode
== VOIDmode
)
2838 mode
= GET_MODE (op
);
2839 else if (mode
!= GET_MODE (op
))
2842 /* Start with a vspltisw. */
2843 step
= GET_MODE_NUNITS (mode
) / 4;
2846 if (vspltis_constant (op
, step
, copies
))
2849 /* Then try with a vspltish. */
2855 if (vspltis_constant (op
, step
, copies
))
2858 /* And finally a vspltisb. */
2864 if (vspltis_constant (op
, step
, copies
))
2870 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2871 result is OP. Abort if it is not possible. */
2874 gen_easy_altivec_constant (rtx op
)
2876 enum machine_mode mode
= GET_MODE (op
);
2877 int nunits
= GET_MODE_NUNITS (mode
);
2878 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
2879 unsigned step
= nunits
/ 4;
2880 unsigned copies
= 1;
2882 /* Start with a vspltisw. */
2883 if (vspltis_constant (op
, step
, copies
))
2884 return gen_rtx_VEC_DUPLICATE (V4SImode
, gen_lowpart (SImode
, last
));
2886 /* Then try with a vspltish. */
2892 if (vspltis_constant (op
, step
, copies
))
2893 return gen_rtx_VEC_DUPLICATE (V8HImode
, gen_lowpart (HImode
, last
));
2895 /* And finally a vspltisb. */
2901 if (vspltis_constant (op
, step
, copies
))
2902 return gen_rtx_VEC_DUPLICATE (V16QImode
, gen_lowpart (QImode
, last
));
2908 output_vec_const_move (rtx
*operands
)
2911 enum machine_mode mode
;
2916 mode
= GET_MODE (dest
);
2921 if (zero_constant (vec
, mode
))
2922 return "vxor %0,%0,%0";
2924 splat_vec
= gen_easy_altivec_constant (vec
);
2925 gcc_assert (GET_CODE (splat_vec
) == VEC_DUPLICATE
);
2926 operands
[1] = XEXP (splat_vec
, 0);
2927 if (!EASY_VECTOR_15 (INTVAL (operands
[1])))
2930 switch (GET_MODE (splat_vec
))
2933 return "vspltisw %0,%1";
2936 return "vspltish %0,%1";
2939 return "vspltisb %0,%1";
2946 gcc_assert (TARGET_SPE
);
2948 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2949 pattern of V1DI, V4HI, and V2SF.
2951 FIXME: We should probably return # and add post reload
2952 splitters for these, but this way is so easy ;-). */
2953 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
2954 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
2955 operands
[1] = CONST_VECTOR_ELT (vec
, 0);
2956 operands
[2] = CONST_VECTOR_ELT (vec
, 1);
2958 return "li %0,%1\n\tevmergelo %0,%0,%0";
2960 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
2963 /* Initialize TARGET of vector PAIRED to VALS. */
2966 paired_expand_vector_init (rtx target
, rtx vals
)
2968 enum machine_mode mode
= GET_MODE (target
);
2969 int n_elts
= GET_MODE_NUNITS (mode
);
2971 rtx x
, new_rtx
, tmp
, constant_op
, op1
, op2
;
2974 for (i
= 0; i
< n_elts
; ++i
)
2976 x
= XVECEXP (vals
, 0, i
);
2977 if (!CONSTANT_P (x
))
2982 /* Load from constant pool. */
2983 emit_move_insn (target
, gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0)));
2989 /* The vector is initialized only with non-constants. */
2990 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, XVECEXP (vals
, 0, 0),
2991 XVECEXP (vals
, 0, 1));
2993 emit_move_insn (target
, new_rtx
);
2997 /* One field is non-constant and the other one is a constant. Load the
2998 constant from the constant pool and use ps_merge instruction to
2999 construct the whole vector. */
3000 op1
= XVECEXP (vals
, 0, 0);
3001 op2
= XVECEXP (vals
, 0, 1);
3003 constant_op
= (CONSTANT_P (op1
)) ? op1
: op2
;
3005 tmp
= gen_reg_rtx (GET_MODE (constant_op
));
3006 emit_move_insn (tmp
, constant_op
);
3008 if (CONSTANT_P (op1
))
3009 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, tmp
, op2
);
3011 new_rtx
= gen_rtx_VEC_CONCAT (V2SFmode
, op1
, tmp
);
3013 emit_move_insn (target
, new_rtx
);
3017 paired_expand_vector_move (rtx operands
[])
3019 rtx op0
= operands
[0], op1
= operands
[1];
3021 emit_move_insn (op0
, op1
);
3024 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
3025 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
3026 operands for the relation operation COND. This is a recursive
3030 paired_emit_vector_compare (enum rtx_code rcode
,
3031 rtx dest
, rtx op0
, rtx op1
,
3032 rtx cc_op0
, rtx cc_op1
)
3034 rtx tmp
= gen_reg_rtx (V2SFmode
);
3035 rtx tmp1
, max
, min
, equal_zero
;
3037 gcc_assert (TARGET_PAIRED_FLOAT
);
3038 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
3044 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3048 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
3049 emit_insn (gen_selv2sf4 (dest
, tmp
, op0
, op1
, CONST0_RTX (SFmode
)));
3053 paired_emit_vector_compare (GE
, dest
, op0
, op1
, cc_op1
, cc_op0
);
3056 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3059 tmp1
= gen_reg_rtx (V2SFmode
);
3060 max
= gen_reg_rtx (V2SFmode
);
3061 min
= gen_reg_rtx (V2SFmode
);
3062 equal_zero
= gen_reg_rtx (V2SFmode
);
3064 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
3065 emit_insn (gen_selv2sf4
3066 (max
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
3067 emit_insn (gen_subv2sf3 (tmp
, cc_op1
, cc_op0
));
3068 emit_insn (gen_selv2sf4
3069 (min
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
3070 emit_insn (gen_subv2sf3 (tmp1
, min
, max
));
3071 emit_insn (gen_selv2sf4 (dest
, tmp1
, op0
, op1
, CONST0_RTX (SFmode
)));
3074 paired_emit_vector_compare (EQ
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3077 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3080 paired_emit_vector_compare (LT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3083 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3086 paired_emit_vector_compare (GT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
3095 /* Emit vector conditional expression.
3096 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
3097 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
3100 paired_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
3101 rtx cond
, rtx cc_op0
, rtx cc_op1
)
3103 enum rtx_code rcode
= GET_CODE (cond
);
3105 if (!TARGET_PAIRED_FLOAT
)
3108 paired_emit_vector_compare (rcode
, dest
, op1
, op2
, cc_op0
, cc_op1
);
3113 /* Initialize vector TARGET to VALS. */
3116 rs6000_expand_vector_init (rtx target
, rtx vals
)
3118 enum machine_mode mode
= GET_MODE (target
);
3119 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
3120 int n_elts
= GET_MODE_NUNITS (mode
);
3121 int n_var
= 0, one_var
= -1;
3122 bool all_same
= true, all_const_zero
= true;
3126 for (i
= 0; i
< n_elts
; ++i
)
3128 x
= XVECEXP (vals
, 0, i
);
3129 if (!CONSTANT_P (x
))
3130 ++n_var
, one_var
= i
;
3131 else if (x
!= CONST0_RTX (inner_mode
))
3132 all_const_zero
= false;
3134 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
3140 rtx const_vec
= gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0));
3141 if (mode
!= V4SFmode
&& all_const_zero
)
3143 /* Zero register. */
3144 emit_insn (gen_rtx_SET (VOIDmode
, target
,
3145 gen_rtx_XOR (mode
, target
, target
)));
3148 else if (mode
!= V4SFmode
&& easy_vector_constant (const_vec
, mode
))
3150 /* Splat immediate. */
3151 emit_insn (gen_rtx_SET (VOIDmode
, target
, const_vec
));
3155 ; /* Splat vector element. */
3158 /* Load from constant pool. */
3159 emit_move_insn (target
, const_vec
);
3164 /* Store value to stack temp. Load vector element. Splat. */
3167 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
3168 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0),
3169 XVECEXP (vals
, 0, 0));
3170 x
= gen_rtx_UNSPEC (VOIDmode
,
3171 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
3172 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3174 gen_rtx_SET (VOIDmode
,
3177 x
= gen_rtx_VEC_SELECT (inner_mode
, target
,
3178 gen_rtx_PARALLEL (VOIDmode
,
3179 gen_rtvec (1, const0_rtx
)));
3180 emit_insn (gen_rtx_SET (VOIDmode
, target
,
3181 gen_rtx_VEC_DUPLICATE (mode
, x
)));
3185 /* One field is non-constant. Load constant then overwrite
3189 rtx copy
= copy_rtx (vals
);
3191 /* Load constant part of vector, substitute neighboring value for
3193 XVECEXP (copy
, 0, one_var
) = XVECEXP (vals
, 0, (one_var
+ 1) % n_elts
);
3194 rs6000_expand_vector_init (target
, copy
);
3196 /* Insert variable. */
3197 rs6000_expand_vector_set (target
, XVECEXP (vals
, 0, one_var
), one_var
);
3201 /* Construct the vector in memory one field at a time
3202 and load the whole vector. */
3203 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
3204 for (i
= 0; i
< n_elts
; i
++)
3205 emit_move_insn (adjust_address_nv (mem
, inner_mode
,
3206 i
* GET_MODE_SIZE (inner_mode
)),
3207 XVECEXP (vals
, 0, i
));
3208 emit_move_insn (target
, mem
);
3211 /* Set field ELT of TARGET to VAL. */
3214 rs6000_expand_vector_set (rtx target
, rtx val
, int elt
)
3216 enum machine_mode mode
= GET_MODE (target
);
3217 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
3218 rtx reg
= gen_reg_rtx (mode
);
3220 int width
= GET_MODE_SIZE (inner_mode
);
3223 /* Load single variable value. */
3224 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
3225 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0), val
);
3226 x
= gen_rtx_UNSPEC (VOIDmode
,
3227 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
3228 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3230 gen_rtx_SET (VOIDmode
,
3234 /* Linear sequence. */
3235 mask
= gen_rtx_PARALLEL (V16QImode
, rtvec_alloc (16));
3236 for (i
= 0; i
< 16; ++i
)
3237 XVECEXP (mask
, 0, i
) = GEN_INT (i
);
3239 /* Set permute mask to insert element into target. */
3240 for (i
= 0; i
< width
; ++i
)
3241 XVECEXP (mask
, 0, elt
*width
+ i
)
3242 = GEN_INT (i
+ 0x10);
3243 x
= gen_rtx_CONST_VECTOR (V16QImode
, XVEC (mask
, 0));
3244 x
= gen_rtx_UNSPEC (mode
,
3245 gen_rtvec (3, target
, reg
,
3246 force_reg (V16QImode
, x
)),
3248 emit_insn (gen_rtx_SET (VOIDmode
, target
, x
));
3251 /* Extract field ELT from VEC into TARGET. */
3254 rs6000_expand_vector_extract (rtx target
, rtx vec
, int elt
)
3256 enum machine_mode mode
= GET_MODE (vec
);
3257 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
3260 /* Allocate mode-sized buffer. */
3261 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
3263 /* Add offset to field within buffer matching vector element. */
3264 mem
= adjust_address_nv (mem
, mode
, elt
* GET_MODE_SIZE (inner_mode
));
3266 /* Store single field into mode-sized buffer. */
3267 x
= gen_rtx_UNSPEC (VOIDmode
,
3268 gen_rtvec (1, const0_rtx
), UNSPEC_STVE
);
3269 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3271 gen_rtx_SET (VOIDmode
,
3274 emit_move_insn (target
, adjust_address_nv (mem
, inner_mode
, 0));
3277 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
3278 implement ANDing by the mask IN. */
3280 build_mask64_2_operands (rtx in
, rtx
*out
)
3282 #if HOST_BITS_PER_WIDE_INT >= 64
3283 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
3286 gcc_assert (GET_CODE (in
) == CONST_INT
);
3291 /* Assume c initially something like 0x00fff000000fffff. The idea
3292 is to rotate the word so that the middle ^^^^^^ group of zeros
3293 is at the MS end and can be cleared with an rldicl mask. We then
3294 rotate back and clear off the MS ^^ group of zeros with a
3296 c
= ~c
; /* c == 0xff000ffffff00000 */
3297 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
3298 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
3299 c
= ~c
; /* c == 0x00fff000000fffff */
3300 c
&= -lsb
; /* c == 0x00fff00000000000 */
3301 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
3302 c
= ~c
; /* c == 0xff000fffffffffff */
3303 c
&= -lsb
; /* c == 0xff00000000000000 */
3305 while ((lsb
>>= 1) != 0)
3306 shift
++; /* shift == 44 on exit from loop */
3307 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
3308 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
3309 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
3313 /* Assume c initially something like 0xff000f0000000000. The idea
3314 is to rotate the word so that the ^^^ middle group of zeros
3315 is at the LS end and can be cleared with an rldicr mask. We then
3316 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
3318 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
3319 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
3320 c
= ~c
; /* c == 0x00fff0ffffffffff */
3321 c
&= -lsb
; /* c == 0x00fff00000000000 */
3322 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
3323 c
= ~c
; /* c == 0xff000fffffffffff */
3324 c
&= -lsb
; /* c == 0xff00000000000000 */
3326 while ((lsb
>>= 1) != 0)
3327 shift
++; /* shift == 44 on exit from loop */
3328 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
3329 m1
>>= shift
; /* m1 == 0x0000000000000fff */
3330 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
3333 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
3334 masks will be all 1's. We are guaranteed more than one transition. */
3335 out
[0] = GEN_INT (64 - shift
);
3336 out
[1] = GEN_INT (m1
);
3337 out
[2] = GEN_INT (shift
);
3338 out
[3] = GEN_INT (m2
);
3346 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
3349 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
3351 if (TARGET_E500_DOUBLE
)
3353 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
3354 subreg:TI and reg:TF. Decimal float modes are like integer
3355 modes (only low part of each register used) for this
3357 if (GET_CODE (op
) == SUBREG
3358 && (mode
== SImode
|| mode
== DImode
|| mode
== TImode
3359 || mode
== DDmode
|| mode
== TDmode
)
3360 && REG_P (SUBREG_REG (op
))
3361 && (GET_MODE (SUBREG_REG (op
)) == DFmode
3362 || GET_MODE (SUBREG_REG (op
)) == TFmode
))
3365 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
3367 if (GET_CODE (op
) == SUBREG
3368 && (mode
== DFmode
|| mode
== TFmode
)
3369 && REG_P (SUBREG_REG (op
))
3370 && (GET_MODE (SUBREG_REG (op
)) == DImode
3371 || GET_MODE (SUBREG_REG (op
)) == TImode
3372 || GET_MODE (SUBREG_REG (op
)) == DDmode
3373 || GET_MODE (SUBREG_REG (op
)) == TDmode
))
3378 && GET_CODE (op
) == SUBREG
3380 && REG_P (SUBREG_REG (op
))
3381 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op
))))
3387 /* AIX increases natural record alignment to doubleword if the first
3388 field is an FP double while the FP fields remain word aligned. */
3391 rs6000_special_round_type_align (tree type
, unsigned int computed
,
3392 unsigned int specified
)
3394 unsigned int align
= MAX (computed
, specified
);
3395 tree field
= TYPE_FIELDS (type
);
3397 /* Skip all non field decls */
3398 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
3399 field
= TREE_CHAIN (field
);
3401 if (field
!= NULL
&& field
!= type
)
3403 type
= TREE_TYPE (field
);
3404 while (TREE_CODE (type
) == ARRAY_TYPE
)
3405 type
= TREE_TYPE (type
);
3407 if (type
!= error_mark_node
&& TYPE_MODE (type
) == DFmode
)
3408 align
= MAX (align
, 64);
3414 /* Darwin increases record alignment to the natural alignment of
3418 darwin_rs6000_special_round_type_align (tree type
, unsigned int computed
,
3419 unsigned int specified
)
3421 unsigned int align
= MAX (computed
, specified
);
3423 if (TYPE_PACKED (type
))
3426 /* Find the first field, looking down into aggregates. */
3428 tree field
= TYPE_FIELDS (type
);
3429 /* Skip all non field decls */
3430 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
3431 field
= TREE_CHAIN (field
);
3434 type
= TREE_TYPE (field
);
3435 while (TREE_CODE (type
) == ARRAY_TYPE
)
3436 type
= TREE_TYPE (type
);
3437 } while (AGGREGATE_TYPE_P (type
));
3439 if (! AGGREGATE_TYPE_P (type
) && type
!= error_mark_node
)
3440 align
= MAX (align
, TYPE_ALIGN (type
));
3445 /* Return 1 for an operand in small memory on V.4/eabi. */
3448 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
3449 enum machine_mode mode ATTRIBUTE_UNUSED
)
3454 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
3457 if (DEFAULT_ABI
!= ABI_V4
)
3460 /* Vector and float memory instructions have a limited offset on the
3461 SPE, so using a vector or float variable directly as an operand is
3464 && (SPE_VECTOR_MODE (mode
) || FLOAT_MODE_P (mode
)))
3467 if (GET_CODE (op
) == SYMBOL_REF
)
3470 else if (GET_CODE (op
) != CONST
3471 || GET_CODE (XEXP (op
, 0)) != PLUS
3472 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
3473 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
3478 rtx sum
= XEXP (op
, 0);
3479 HOST_WIDE_INT summand
;
3481 /* We have to be careful here, because it is the referenced address
3482 that must be 32k from _SDA_BASE_, not just the symbol. */
3483 summand
= INTVAL (XEXP (sum
, 1));
3484 if (summand
< 0 || (unsigned HOST_WIDE_INT
) summand
> g_switch_value
)
3487 sym_ref
= XEXP (sum
, 0);
3490 return SYMBOL_REF_SMALL_P (sym_ref
);
3496 /* Return true if either operand is a general purpose register. */
3499 gpr_or_gpr_p (rtx op0
, rtx op1
)
3501 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
3502 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
3506 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
3509 constant_pool_expr_1 (rtx op
, int *have_sym
, int *have_toc
)
3511 switch (GET_CODE (op
))
3514 if (RS6000_SYMBOL_REF_TLS_P (op
))
3516 else if (CONSTANT_POOL_ADDRESS_P (op
))
3518 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op
), Pmode
))
3526 else if (! strcmp (XSTR (op
, 0), toc_label_name
))
3535 return (constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
)
3536 && constant_pool_expr_1 (XEXP (op
, 1), have_sym
, have_toc
));
3538 return constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
);
3547 constant_pool_expr_p (rtx op
)
3551 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_sym
;
3555 toc_relative_expr_p (rtx op
)
3559 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_toc
;
3563 legitimate_constant_pool_address_p (rtx x
)
3566 && GET_CODE (x
) == PLUS
3567 && GET_CODE (XEXP (x
, 0)) == REG
3568 && (TARGET_MINIMAL_TOC
|| REGNO (XEXP (x
, 0)) == TOC_REGISTER
)
3569 && constant_pool_expr_p (XEXP (x
, 1)));
3573 legitimate_small_data_p (enum machine_mode mode
, rtx x
)
3575 return (DEFAULT_ABI
== ABI_V4
3576 && !flag_pic
&& !TARGET_TOC
3577 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
3578 && small_data_operand (x
, mode
));
3581 /* SPE offset addressing is limited to 5-bits worth of double words. */
3582 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
3585 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
3587 unsigned HOST_WIDE_INT offset
, extra
;
3589 if (GET_CODE (x
) != PLUS
)
3591 if (GET_CODE (XEXP (x
, 0)) != REG
)
3593 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
3595 if (legitimate_constant_pool_address_p (x
))
3597 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
3600 offset
= INTVAL (XEXP (x
, 1));
3608 /* AltiVec vector modes. Only reg+reg addressing is valid and
3609 constant offset zero should not occur due to canonicalization. */
3616 /* Paired vector modes. Only reg+reg addressing is valid and
3617 constant offset zero should not occur due to canonicalization. */
3618 if (TARGET_PAIRED_FLOAT
)
3620 /* SPE vector modes. */
3621 return SPE_CONST_OFFSET_OK (offset
);
3624 if (TARGET_E500_DOUBLE
)
3625 return SPE_CONST_OFFSET_OK (offset
);
3629 /* On e500v2, we may have:
3631 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
3633 Which gets addressed with evldd instructions. */
3634 if (TARGET_E500_DOUBLE
)
3635 return SPE_CONST_OFFSET_OK (offset
);
3637 if (mode
== DFmode
|| mode
== DDmode
|| !TARGET_POWERPC64
)
3639 else if (offset
& 3)
3644 if (TARGET_E500_DOUBLE
)
3645 return (SPE_CONST_OFFSET_OK (offset
)
3646 && SPE_CONST_OFFSET_OK (offset
+ 8));
3650 if (mode
== TFmode
|| mode
== TDmode
|| !TARGET_POWERPC64
)
3652 else if (offset
& 3)
3663 return (offset
< 0x10000) && (offset
+ extra
< 0x10000);
3667 legitimate_indexed_address_p (rtx x
, int strict
)
3671 if (GET_CODE (x
) != PLUS
)
3677 /* Recognize the rtl generated by reload which we know will later be
3678 replaced with proper base and index regs. */
3680 && reload_in_progress
3681 && (REG_P (op0
) || GET_CODE (op0
) == PLUS
)
3685 return (REG_P (op0
) && REG_P (op1
)
3686 && ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
3687 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
3688 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
3689 && INT_REG_OK_FOR_INDEX_P (op0
, strict
))));
3693 legitimate_indirect_address_p (rtx x
, int strict
)
3695 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
3699 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
3701 if (!TARGET_MACHO
|| !flag_pic
3702 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
3706 if (GET_CODE (x
) != LO_SUM
)
3708 if (GET_CODE (XEXP (x
, 0)) != REG
)
3710 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
3714 return CONSTANT_P (x
);
3718 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
3720 if (GET_CODE (x
) != LO_SUM
)
3722 if (GET_CODE (XEXP (x
, 0)) != REG
)
3724 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
3726 /* Restrict addressing for DI because of our SUBREG hackery. */
3727 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3728 || mode
== DDmode
|| mode
== TDmode
3733 if (TARGET_ELF
|| TARGET_MACHO
)
3735 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
3739 if (GET_MODE_NUNITS (mode
) != 1)
3741 if (GET_MODE_BITSIZE (mode
) > 64
3742 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
3743 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
3744 && (mode
== DFmode
|| mode
== DDmode
))))
3747 return CONSTANT_P (x
);
3754 /* Try machine-dependent ways of modifying an illegitimate address
3755 to be legitimate. If we find one, return the new, valid address.
3756 This is used from only one place: `memory_address' in explow.c.
3758 OLDX is the address as it was before break_out_memory_refs was
3759 called. In some cases it is useful to look at this to decide what
3762 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
3764 It is always safe for this function to do nothing. It exists to
3765 recognize opportunities to optimize the output.
3767 On RS/6000, first check for the sum of a register with a constant
3768 integer that is out of range. If so, generate code to add the
3769 constant with the low-order 16 bits masked to the register and force
3770 this result into another register (this can be done with `cau').
3771 Then generate an address of REG+(CONST&0xffff), allowing for the
3772 possibility of bit 16 being a one.
3774 Then check for the sum of a register and something not constant, try to
3775 load the other things into a register and return the sum. */
3778 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3779 enum machine_mode mode
)
3781 if (GET_CODE (x
) == SYMBOL_REF
)
3783 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
3785 return rs6000_legitimize_tls_address (x
, model
);
3788 if (GET_CODE (x
) == PLUS
3789 && GET_CODE (XEXP (x
, 0)) == REG
3790 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3791 && (unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000) >= 0x10000
3792 && !(SPE_VECTOR_MODE (mode
)
3793 || ALTIVEC_VECTOR_MODE (mode
)
3794 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3795 || mode
== DImode
|| mode
== DDmode
3796 || mode
== TDmode
))))
3798 HOST_WIDE_INT high_int
, low_int
;
3800 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
3801 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
3802 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
3803 GEN_INT (high_int
)), 0);
3804 return gen_rtx_PLUS (Pmode
, sum
, GEN_INT (low_int
));
3806 else if (GET_CODE (x
) == PLUS
3807 && GET_CODE (XEXP (x
, 0)) == REG
3808 && GET_CODE (XEXP (x
, 1)) != CONST_INT
3809 && GET_MODE_NUNITS (mode
) == 1
3810 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
3812 || ((mode
!= DImode
&& mode
!= DFmode
&& mode
!= DDmode
)
3813 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
)))
3814 && (TARGET_POWERPC64
|| mode
!= DImode
)
3819 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
3820 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
3822 else if (ALTIVEC_VECTOR_MODE (mode
))
3826 /* Make sure both operands are registers. */
3827 if (GET_CODE (x
) == PLUS
)
3828 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, XEXP (x
, 0)),
3829 force_reg (Pmode
, XEXP (x
, 1)));
3831 reg
= force_reg (Pmode
, x
);
3834 else if (SPE_VECTOR_MODE (mode
)
3835 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3836 || mode
== DDmode
|| mode
== TDmode
3837 || mode
== DImode
)))
3841 /* We accept [reg + reg] and [reg + OFFSET]. */
3843 if (GET_CODE (x
) == PLUS
)
3845 rtx op1
= XEXP (x
, 0);
3846 rtx op2
= XEXP (x
, 1);
3849 op1
= force_reg (Pmode
, op1
);
3851 if (GET_CODE (op2
) != REG
3852 && (GET_CODE (op2
) != CONST_INT
3853 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))
3854 || (GET_MODE_SIZE (mode
) > 8
3855 && !SPE_CONST_OFFSET_OK (INTVAL (op2
) + 8))))
3856 op2
= force_reg (Pmode
, op2
);
3858 /* We can't always do [reg + reg] for these, because [reg +
3859 reg + offset] is not a legitimate addressing mode. */
3860 y
= gen_rtx_PLUS (Pmode
, op1
, op2
);
3862 if ((GET_MODE_SIZE (mode
) > 8 || mode
== DDmode
) && REG_P (op2
))
3863 return force_reg (Pmode
, y
);
3868 return force_reg (Pmode
, x
);
3874 && GET_CODE (x
) != CONST_INT
3875 && GET_CODE (x
) != CONST_DOUBLE
3877 && GET_MODE_NUNITS (mode
) == 1
3878 && (GET_MODE_BITSIZE (mode
) <= 32
3879 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
3880 && (mode
== DFmode
|| mode
== DDmode
))))
3882 rtx reg
= gen_reg_rtx (Pmode
);
3883 emit_insn (gen_elf_high (reg
, x
));
3884 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
3886 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
3889 && ! MACHO_DYNAMIC_NO_PIC_P
3891 && GET_CODE (x
) != CONST_INT
3892 && GET_CODE (x
) != CONST_DOUBLE
3894 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
3895 || (mode
!= DFmode
&& mode
!= DDmode
))
3899 rtx reg
= gen_reg_rtx (Pmode
);
3900 emit_insn (gen_macho_high (reg
, x
));
3901 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
3904 && GET_CODE (x
) == SYMBOL_REF
3905 && constant_pool_expr_p (x
)
3906 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
3908 return create_TOC_reference (x
);
3914 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
3915 We need to emit DTP-relative relocations. */
3918 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
3923 fputs ("\t.long\t", file
);
3926 fputs (DOUBLE_INT_ASM_OP
, file
);
3931 output_addr_const (file
, x
);
3932 fputs ("@dtprel+0x8000", file
);
3935 /* Construct the SYMBOL_REF for the tls_get_addr function. */
3937 static GTY(()) rtx rs6000_tls_symbol
;
3939 rs6000_tls_get_addr (void)
3941 if (!rs6000_tls_symbol
)
3942 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
3944 return rs6000_tls_symbol
;
3947 /* Construct the SYMBOL_REF for TLS GOT references. */
3949 static GTY(()) rtx rs6000_got_symbol
;
3951 rs6000_got_sym (void)
3953 if (!rs6000_got_symbol
)
3955 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
3956 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
3957 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
3960 return rs6000_got_symbol
;
3963 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3964 this (thread-local) address. */
3967 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
3971 dest
= gen_reg_rtx (Pmode
);
3972 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
3978 tlsreg
= gen_rtx_REG (Pmode
, 13);
3979 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
3983 tlsreg
= gen_rtx_REG (Pmode
, 2);
3984 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
3988 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
3992 tmp
= gen_reg_rtx (Pmode
);
3995 tlsreg
= gen_rtx_REG (Pmode
, 13);
3996 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
4000 tlsreg
= gen_rtx_REG (Pmode
, 2);
4001 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
4005 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
4007 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
4012 rtx r3
, got
, tga
, tmp1
, tmp2
, eqv
;
4014 /* We currently use relocations like @got@tlsgd for tls, which
4015 means the linker will handle allocation of tls entries, placing
4016 them in the .got section. So use a pointer to the .got section,
4017 not one to secondary TOC sections used by 64-bit -mminimal-toc,
4018 or to secondary GOT sections used by 32-bit -fPIC. */
4020 got
= gen_rtx_REG (Pmode
, 2);
4024 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
4027 rtx gsym
= rs6000_got_sym ();
4028 got
= gen_reg_rtx (Pmode
);
4030 rs6000_emit_move (got
, gsym
, Pmode
);
4036 tmp1
= gen_reg_rtx (Pmode
);
4037 tmp2
= gen_reg_rtx (Pmode
);
4038 tmp3
= gen_reg_rtx (Pmode
);
4039 mem
= gen_const_mem (Pmode
, tmp1
);
4041 first
= emit_insn (gen_load_toc_v4_PIC_1b (gsym
));
4042 emit_move_insn (tmp1
,
4043 gen_rtx_REG (Pmode
, LR_REGNO
));
4044 emit_move_insn (tmp2
, mem
);
4045 emit_insn (gen_addsi3 (tmp3
, tmp1
, tmp2
));
4046 last
= emit_move_insn (got
, tmp3
);
4047 set_unique_reg_note (last
, REG_EQUAL
, gsym
);
4052 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
4054 r3
= gen_rtx_REG (Pmode
, 3);
4055 tga
= rs6000_tls_get_addr ();
4057 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
4058 insn
= gen_tls_gd_aix64 (r3
, got
, addr
, tga
, const0_rtx
);
4059 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
4060 insn
= gen_tls_gd_aix32 (r3
, got
, addr
, tga
, const0_rtx
);
4061 else if (DEFAULT_ABI
== ABI_V4
)
4062 insn
= gen_tls_gd_sysvsi (r3
, got
, addr
, tga
, const0_rtx
);
4067 insn
= emit_call_insn (insn
);
4068 RTL_CONST_CALL_P (insn
) = 1;
4069 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
4070 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
4071 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
4072 insn
= get_insns ();
4074 emit_libcall_block (insn
, dest
, r3
, addr
);
4076 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
4078 r3
= gen_rtx_REG (Pmode
, 3);
4079 tga
= rs6000_tls_get_addr ();
4081 if (DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
4082 insn
= gen_tls_ld_aix64 (r3
, got
, tga
, const0_rtx
);
4083 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_64BIT
)
4084 insn
= gen_tls_ld_aix32 (r3
, got
, tga
, const0_rtx
);
4085 else if (DEFAULT_ABI
== ABI_V4
)
4086 insn
= gen_tls_ld_sysvsi (r3
, got
, tga
, const0_rtx
);
4091 insn
= emit_call_insn (insn
);
4092 RTL_CONST_CALL_P (insn
) = 1;
4093 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
4094 if (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
4095 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
4096 insn
= get_insns ();
4098 tmp1
= gen_reg_rtx (Pmode
);
4099 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
),
4101 emit_libcall_block (insn
, tmp1
, r3
, eqv
);
4102 if (rs6000_tls_size
== 16)
4105 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
4107 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
4109 else if (rs6000_tls_size
== 32)
4111 tmp2
= gen_reg_rtx (Pmode
);
4113 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
4115 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
4118 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
4120 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
4124 tmp2
= gen_reg_rtx (Pmode
);
4126 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
4128 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
4130 insn
= gen_rtx_SET (Pmode
, dest
,
4131 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
4137 /* IE, or 64-bit offset LE. */
4138 tmp2
= gen_reg_rtx (Pmode
);
4140 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
4142 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
4145 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
4147 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
4155 /* Return 1 if X contains a thread-local symbol. */
4158 rs6000_tls_referenced_p (rtx x
)
4160 if (! TARGET_HAVE_TLS
)
4163 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
4166 /* Return 1 if *X is a thread-local symbol. This is the same as
4167 rs6000_tls_symbol_ref except for the type of the unused argument. */
4170 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
4172 return RS6000_SYMBOL_REF_TLS_P (*x
);
4175 /* The convention appears to be to define this wherever it is used.
4176 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
4177 is now used here. */
4178 #ifndef REG_MODE_OK_FOR_BASE_P
4179 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
4182 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
4183 replace the input X, or the original X if no replacement is called for.
4184 The output parameter *WIN is 1 if the calling macro should goto WIN,
4187 For RS/6000, we wish to handle large displacements off a base
4188 register by splitting the addend across an addiu/addis and the mem insn.
4189 This cuts number of extra insns needed from 3 to 1.
4191 On Darwin, we use this to generate code for floating point constants.
4192 A movsf_low is generated so we wind up with 2 instructions rather than 3.
4193 The Darwin code is inside #if TARGET_MACHO because only then is
4194 machopic_function_base_name() defined. */
4196 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
4197 int opnum
, int type
,
4198 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
4200 /* We must recognize output that we have already generated ourselves. */
4201 if (GET_CODE (x
) == PLUS
4202 && GET_CODE (XEXP (x
, 0)) == PLUS
4203 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
4204 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
4205 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
4207 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4208 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
4209 opnum
, (enum reload_type
)type
);
4215 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
4216 && GET_CODE (x
) == LO_SUM
4217 && GET_CODE (XEXP (x
, 0)) == PLUS
4218 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
4219 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
4220 && GET_CODE (XEXP (XEXP (XEXP (x
, 0), 1), 0)) == CONST
4221 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
4222 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == MINUS
4223 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 0)) == SYMBOL_REF
4224 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 1)) == SYMBOL_REF
)
4226 /* Result of previous invocation of this function on Darwin
4227 floating point constant. */
4228 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4229 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
4230 opnum
, (enum reload_type
)type
);
4236 /* Force ld/std non-word aligned offset into base register by wrapping
4238 if (GET_CODE (x
) == PLUS
4239 && GET_CODE (XEXP (x
, 0)) == REG
4240 && REGNO (XEXP (x
, 0)) < 32
4241 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
4242 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4243 && (INTVAL (XEXP (x
, 1)) & 3) != 0
4244 && !ALTIVEC_VECTOR_MODE (mode
)
4245 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
4246 && TARGET_POWERPC64
)
4248 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
4249 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4250 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
4251 opnum
, (enum reload_type
) type
);
4256 if (GET_CODE (x
) == PLUS
4257 && GET_CODE (XEXP (x
, 0)) == REG
4258 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
4259 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
4260 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4261 && !SPE_VECTOR_MODE (mode
)
4262 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
4263 || mode
== DDmode
|| mode
== TDmode
4265 && !ALTIVEC_VECTOR_MODE (mode
))
4267 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
4268 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
4270 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
4272 /* Check for 32-bit overflow. */
4273 if (high
+ low
!= val
)
4279 /* Reload the high part into a base reg; leave the low part
4280 in the mem directly. */
4282 x
= gen_rtx_PLUS (GET_MODE (x
),
4283 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
4287 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4288 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
4289 opnum
, (enum reload_type
)type
);
4294 if (GET_CODE (x
) == SYMBOL_REF
4295 && !ALTIVEC_VECTOR_MODE (mode
)
4296 && !SPE_VECTOR_MODE (mode
)
4298 && DEFAULT_ABI
== ABI_DARWIN
4299 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
4301 && DEFAULT_ABI
== ABI_V4
4304 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
4305 The same goes for DImode without 64-bit gprs and DFmode and DDmode
4309 && (mode
!= DImode
|| TARGET_POWERPC64
)
4310 && ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_POWERPC64
4311 || (TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)))
4316 rtx offset
= gen_rtx_CONST (Pmode
,
4317 gen_rtx_MINUS (Pmode
, x
,
4318 machopic_function_base_sym ()));
4319 x
= gen_rtx_LO_SUM (GET_MODE (x
),
4320 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
4321 gen_rtx_HIGH (Pmode
, offset
)), offset
);
4325 x
= gen_rtx_LO_SUM (GET_MODE (x
),
4326 gen_rtx_HIGH (Pmode
, x
), x
);
4328 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4329 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
4330 opnum
, (enum reload_type
)type
);
4335 /* Reload an offset address wrapped by an AND that represents the
4336 masking of the lower bits. Strip the outer AND and let reload
4337 convert the offset address into an indirect address. */
4339 && ALTIVEC_VECTOR_MODE (mode
)
4340 && GET_CODE (x
) == AND
4341 && GET_CODE (XEXP (x
, 0)) == PLUS
4342 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
4343 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
4344 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4345 && INTVAL (XEXP (x
, 1)) == -16)
4353 && GET_CODE (x
) == SYMBOL_REF
4354 && constant_pool_expr_p (x
)
4355 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
4357 x
= create_TOC_reference (x
);
4365 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
4366 that is a valid memory address for an instruction.
4367 The MODE argument is the machine mode for the MEM expression
4368 that wants to use this address.
4370 On the RS/6000, there are four valid address: a SYMBOL_REF that
4371 refers to a constant pool entry of an address (or the sum of it
4372 plus a constant), a short (16-bit signed) constant plus a register,
4373 the sum of two registers, or a register indirect, possibly with an
4374 auto-increment. For DFmode, DDmode and DImode with a constant plus
4375 register, we must ensure that both words are addressable or PowerPC64
4376 with offset word aligned.
4378 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
4379 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
4380 because adjacent memory cells are accessed by adding word-sized offsets
4381 during assembly output. */
4383 rs6000_legitimate_address (enum machine_mode mode
, rtx x
, int reg_ok_strict
)
4385 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
4387 && ALTIVEC_VECTOR_MODE (mode
)
4388 && GET_CODE (x
) == AND
4389 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4390 && INTVAL (XEXP (x
, 1)) == -16)
4393 if (RS6000_SYMBOL_REF_TLS_P (x
))
4395 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
4397 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
4398 && !ALTIVEC_VECTOR_MODE (mode
)
4399 && !SPE_VECTOR_MODE (mode
)
4402 /* Restrict addressing for DI because of our SUBREG hackery. */
4403 && !(TARGET_E500_DOUBLE
4404 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
4406 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
4408 if (legitimate_small_data_p (mode
, x
))
4410 if (legitimate_constant_pool_address_p (x
))
4412 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
4414 && GET_CODE (x
) == PLUS
4415 && GET_CODE (XEXP (x
, 0)) == REG
4416 && (XEXP (x
, 0) == virtual_stack_vars_rtx
4417 || XEXP (x
, 0) == arg_pointer_rtx
)
4418 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
4420 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
4425 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
4427 || (mode
!= DFmode
&& mode
!= DDmode
)
4428 || (TARGET_E500_DOUBLE
&& mode
!= DDmode
))
4429 && (TARGET_POWERPC64
|| mode
!= DImode
)
4430 && legitimate_indexed_address_p (x
, reg_ok_strict
))
4432 if (GET_CODE (x
) == PRE_MODIFY
4436 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
)
4438 || ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_E500_DOUBLE
))
4439 && (TARGET_POWERPC64
|| mode
!= DImode
)
4440 && !ALTIVEC_VECTOR_MODE (mode
)
4441 && !SPE_VECTOR_MODE (mode
)
4442 /* Restrict addressing for DI because of our SUBREG hackery. */
4443 && !(TARGET_E500_DOUBLE
4444 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
4446 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
)
4447 && (rs6000_legitimate_offset_address_p (mode
, XEXP (x
, 1), reg_ok_strict
)
4448 || legitimate_indexed_address_p (XEXP (x
, 1), reg_ok_strict
))
4449 && rtx_equal_p (XEXP (XEXP (x
, 1), 0), XEXP (x
, 0)))
4451 if (legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
4456 /* Go to LABEL if ADDR (a legitimate address expression)
4457 has an effect that depends on the machine mode it is used for.
4459 On the RS/6000 this is true of all integral offsets (since AltiVec
4460 modes don't allow them) or is a pre-increment or decrement.
4462 ??? Except that due to conceptual problems in offsettable_address_p
4463 we can't really report the problems of integral offsets. So leave
4464 this assuming that the adjustable offset must be valid for the
4465 sub-words of a TFmode operand, which is what we had before. */
4468 rs6000_mode_dependent_address (rtx addr
)
4470 switch (GET_CODE (addr
))
4473 if (GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
4475 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
4476 return val
+ 12 + 0x8000 >= 0x10000;
4483 /* Auto-increment cases are now treated generically in recog.c. */
4485 return TARGET_UPDATE
;
4494 /* More elaborate version of recog's offsettable_memref_p predicate
4495 that works around the ??? note of rs6000_mode_dependent_address.
4496 In particular it accepts
4498 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
4500 in 32-bit mode, that the recog predicate rejects. */
4503 rs6000_offsettable_memref_p (rtx op
)
4508 /* First mimic offsettable_memref_p. */
4509 if (offsettable_address_p (1, GET_MODE (op
), XEXP (op
, 0)))
4512 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
4513 the latter predicate knows nothing about the mode of the memory
4514 reference and, therefore, assumes that it is the largest supported
4515 mode (TFmode). As a consequence, legitimate offsettable memory
4516 references are rejected. rs6000_legitimate_offset_address_p contains
4517 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
4518 return rs6000_legitimate_offset_address_p (GET_MODE (op
), XEXP (op
, 0), 1);
4521 /* Return number of consecutive hard regs needed starting at reg REGNO
4522 to hold something of mode MODE.
4523 This is ordinarily the length in words of a value of mode MODE
4524 but can be less for certain modes in special long registers.
4526 For the SPE, GPRs are 64 bits but only 32 bits are visible in
4527 scalar instructions. The upper 32 bits are only available to the
4530 POWER and PowerPC GPRs hold 32 bits worth;
4531 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
4534 rs6000_hard_regno_nregs (int regno
, enum machine_mode mode
)
4536 if (FP_REGNO_P (regno
))
4537 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
4539 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
4540 return (GET_MODE_SIZE (mode
) + UNITS_PER_SPE_WORD
- 1) / UNITS_PER_SPE_WORD
;
4542 if (ALTIVEC_REGNO_P (regno
))
4544 (GET_MODE_SIZE (mode
) + UNITS_PER_ALTIVEC_WORD
- 1) / UNITS_PER_ALTIVEC_WORD
;
4546 /* The value returned for SCmode in the E500 double case is 2 for
4547 ABI compatibility; storing an SCmode value in a single register
4548 would require function_arg and rs6000_spe_function_arg to handle
4549 SCmode so as to pass the value correctly in a pair of
4551 if (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
) && mode
!= SCmode
4552 && !DECIMAL_FLOAT_MODE_P (mode
))
4553 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
4555 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
4558 /* Change register usage conditional on target flags. */
4560 rs6000_conditional_register_usage (void)
4564 /* Set MQ register fixed (already call_used) if not POWER
4565 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
4570 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
4572 fixed_regs
[13] = call_used_regs
[13]
4573 = call_really_used_regs
[13] = 1;
4575 /* Conditionally disable FPRs. */
4576 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
4577 for (i
= 32; i
< 64; i
++)
4578 fixed_regs
[i
] = call_used_regs
[i
]
4579 = call_really_used_regs
[i
] = 1;
4581 /* The TOC register is not killed across calls in a way that is
4582 visible to the compiler. */
4583 if (DEFAULT_ABI
== ABI_AIX
)
4584 call_really_used_regs
[2] = 0;
4586 if (DEFAULT_ABI
== ABI_V4
4587 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
4589 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4591 if (DEFAULT_ABI
== ABI_V4
4592 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
4594 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4595 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4596 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4598 if (DEFAULT_ABI
== ABI_DARWIN
4599 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
4600 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4601 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4602 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4604 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
4605 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4606 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4610 global_regs
[SPEFSCR_REGNO
] = 1;
4611 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
4612 registers in prologues and epilogues. We no longer use r14
4613 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
4614 pool for link-compatibility with older versions of GCC. Once
4615 "old" code has died out, we can return r14 to the allocation
4618 = call_used_regs
[14]
4619 = call_really_used_regs
[14] = 1;
4622 if (!TARGET_ALTIVEC
)
4624 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
4625 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4626 call_really_used_regs
[VRSAVE_REGNO
] = 1;
4630 global_regs
[VSCR_REGNO
] = 1;
4632 if (TARGET_ALTIVEC_ABI
)
4634 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
4635 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4637 /* AIX reserves VR20:31 in non-extended ABI mode. */
4639 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
< FIRST_ALTIVEC_REGNO
+ 32; ++i
)
4640 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4644 /* Try to output insns to set TARGET equal to the constant C if it can
4645 be done in less than N insns. Do all computations in MODE.
4646 Returns the place where the output has been placed if it can be
4647 done and the insns have been emitted. If it would take more than N
4648 insns, zero is returned and no insns and emitted. */
4651 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
4652 rtx source
, int n ATTRIBUTE_UNUSED
)
4654 rtx result
, insn
, set
;
4655 HOST_WIDE_INT c0
, c1
;
4662 dest
= gen_reg_rtx (mode
);
4663 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
4667 result
= !can_create_pseudo_p () ? dest
: gen_reg_rtx (SImode
);
4669 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (result
),
4670 GEN_INT (INTVAL (source
)
4671 & (~ (HOST_WIDE_INT
) 0xffff))));
4672 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
4673 gen_rtx_IOR (SImode
, copy_rtx (result
),
4674 GEN_INT (INTVAL (source
) & 0xffff))));
4679 switch (GET_CODE (source
))
4682 c0
= INTVAL (source
);
4687 #if HOST_BITS_PER_WIDE_INT >= 64
4688 c0
= CONST_DOUBLE_LOW (source
);
4691 c0
= CONST_DOUBLE_LOW (source
);
4692 c1
= CONST_DOUBLE_HIGH (source
);
4700 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
4707 insn
= get_last_insn ();
4708 set
= single_set (insn
);
4709 if (! CONSTANT_P (SET_SRC (set
)))
4710 set_unique_reg_note (insn
, REG_EQUAL
, source
);
4715 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
4716 fall back to a straight forward decomposition. We do this to avoid
4717 exponential run times encountered when looking for longer sequences
4718 with rs6000_emit_set_const. */
4720 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
4722 if (!TARGET_POWERPC64
)
4724 rtx operand1
, operand2
;
4726 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
4728 operand2
= operand_subword_force (copy_rtx (dest
), WORDS_BIG_ENDIAN
!= 0,
4730 emit_move_insn (operand1
, GEN_INT (c1
));
4731 emit_move_insn (operand2
, GEN_INT (c2
));
4735 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
4738 ud2
= (c1
& 0xffff0000) >> 16;
4739 #if HOST_BITS_PER_WIDE_INT >= 64
4743 ud4
= (c2
& 0xffff0000) >> 16;
4745 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
4746 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
4749 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
4751 emit_move_insn (dest
, GEN_INT (ud1
));
4754 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
4755 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
4758 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
4761 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
4763 emit_move_insn (copy_rtx (dest
),
4764 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4767 else if ((ud4
== 0xffff && (ud3
& 0x8000))
4768 || (ud4
== 0 && ! (ud3
& 0x8000)))
4771 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
4774 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
4777 emit_move_insn (copy_rtx (dest
),
4778 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4780 emit_move_insn (copy_rtx (dest
),
4781 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
4784 emit_move_insn (copy_rtx (dest
),
4785 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4791 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
4794 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
4797 emit_move_insn (copy_rtx (dest
),
4798 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4801 emit_move_insn (copy_rtx (dest
),
4802 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
4805 emit_move_insn (copy_rtx (dest
),
4806 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4807 GEN_INT (ud2
<< 16)));
4809 emit_move_insn (copy_rtx (dest
),
4810 gen_rtx_IOR (DImode
, copy_rtx (dest
), GEN_INT (ud1
)));
4816 /* Helper for the following. Get rid of [r+r] memory refs
4817 in cases where it won't work (TImode, TFmode, TDmode). */
4820 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
4822 if (GET_CODE (operands
[0]) == MEM
4823 && GET_CODE (XEXP (operands
[0], 0)) != REG
4824 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0))
4825 && ! reload_in_progress
)
4827 = replace_equiv_address (operands
[0],
4828 copy_addr_to_reg (XEXP (operands
[0], 0)));
4830 if (GET_CODE (operands
[1]) == MEM
4831 && GET_CODE (XEXP (operands
[1], 0)) != REG
4832 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0))
4833 && ! reload_in_progress
)
4835 = replace_equiv_address (operands
[1],
4836 copy_addr_to_reg (XEXP (operands
[1], 0)));
4839 /* Emit a move from SOURCE to DEST in mode MODE. */
4841 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
4845 operands
[1] = source
;
4847 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
4848 if (GET_CODE (operands
[1]) == CONST_DOUBLE
4849 && ! FLOAT_MODE_P (mode
)
4850 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
4852 /* FIXME. This should never happen. */
4853 /* Since it seems that it does, do the safe thing and convert
4855 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
4857 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
4858 || FLOAT_MODE_P (mode
)
4859 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
4860 || CONST_DOUBLE_LOW (operands
[1]) < 0)
4861 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
4862 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
4864 /* Check if GCC is setting up a block move that will end up using FP
4865 registers as temporaries. We must make sure this is acceptable. */
4866 if (GET_CODE (operands
[0]) == MEM
4867 && GET_CODE (operands
[1]) == MEM
4869 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
4870 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
4871 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
4872 ? 32 : MEM_ALIGN (operands
[0])))
4873 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
4875 : MEM_ALIGN (operands
[1]))))
4876 && ! MEM_VOLATILE_P (operands
[0])
4877 && ! MEM_VOLATILE_P (operands
[1]))
4879 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
4880 adjust_address (operands
[1], SImode
, 0));
4881 emit_move_insn (adjust_address (copy_rtx (operands
[0]), SImode
, 4),
4882 adjust_address (copy_rtx (operands
[1]), SImode
, 4));
4886 if (can_create_pseudo_p () && GET_CODE (operands
[0]) == MEM
4887 && !gpc_reg_operand (operands
[1], mode
))
4888 operands
[1] = force_reg (mode
, operands
[1]);
4890 if (mode
== SFmode
&& ! TARGET_POWERPC
4891 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
4892 && GET_CODE (operands
[0]) == MEM
)
4896 if (reload_in_progress
|| reload_completed
)
4897 regnum
= true_regnum (operands
[1]);
4898 else if (GET_CODE (operands
[1]) == REG
)
4899 regnum
= REGNO (operands
[1]);
4903 /* If operands[1] is a register, on POWER it may have
4904 double-precision data in it, so truncate it to single
4906 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
4909 newreg
= (!can_create_pseudo_p () ? copy_rtx (operands
[1])
4910 : gen_reg_rtx (mode
));
4911 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
4912 operands
[1] = newreg
;
4916 /* Recognize the case where operand[1] is a reference to thread-local
4917 data and load its address to a register. */
4918 if (rs6000_tls_referenced_p (operands
[1]))
4920 enum tls_model model
;
4921 rtx tmp
= operands
[1];
4924 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
4926 addend
= XEXP (XEXP (tmp
, 0), 1);
4927 tmp
= XEXP (XEXP (tmp
, 0), 0);
4930 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
4931 model
= SYMBOL_REF_TLS_MODEL (tmp
);
4932 gcc_assert (model
!= 0);
4934 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
4937 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
4938 tmp
= force_operand (tmp
, operands
[0]);
4943 /* Handle the case where reload calls us with an invalid address. */
4944 if (reload_in_progress
&& mode
== Pmode
4945 && (! general_operand (operands
[1], mode
)
4946 || ! nonimmediate_operand (operands
[0], mode
)))
4949 /* 128-bit constant floating-point values on Darwin should really be
4950 loaded as two parts. */
4951 if (!TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
4952 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
4954 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
4955 know how to get a DFmode SUBREG of a TFmode. */
4956 enum machine_mode imode
= (TARGET_E500_DOUBLE
? DFmode
: DImode
);
4957 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
, 0),
4958 simplify_gen_subreg (imode
, operands
[1], mode
, 0),
4960 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
,
4961 GET_MODE_SIZE (imode
)),
4962 simplify_gen_subreg (imode
, operands
[1], mode
,
4963 GET_MODE_SIZE (imode
)),
4968 if (reload_in_progress
&& cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
4969 cfun
->machine
->sdmode_stack_slot
=
4970 eliminate_regs (cfun
->machine
->sdmode_stack_slot
, VOIDmode
, NULL_RTX
);
4972 if (reload_in_progress
4974 && MEM_P (operands
[0])
4975 && rtx_equal_p (operands
[0], cfun
->machine
->sdmode_stack_slot
)
4976 && REG_P (operands
[1]))
4978 if (FP_REGNO_P (REGNO (operands
[1])))
4980 rtx mem
= adjust_address_nv (operands
[0], DDmode
, 0);
4981 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
4982 emit_insn (gen_movsd_store (mem
, operands
[1]));
4984 else if (INT_REGNO_P (REGNO (operands
[1])))
4986 rtx mem
= adjust_address_nv (operands
[0], mode
, 4);
4987 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
4988 emit_insn (gen_movsd_hardfloat (mem
, operands
[1]));
4994 if (reload_in_progress
4996 && REG_P (operands
[0])
4997 && MEM_P (operands
[1])
4998 && rtx_equal_p (operands
[1], cfun
->machine
->sdmode_stack_slot
))
5000 if (FP_REGNO_P (REGNO (operands
[0])))
5002 rtx mem
= adjust_address_nv (operands
[1], DDmode
, 0);
5003 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
5004 emit_insn (gen_movsd_load (operands
[0], mem
));
5006 else if (INT_REGNO_P (REGNO (operands
[0])))
5008 rtx mem
= adjust_address_nv (operands
[1], mode
, 4);
5009 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
5010 emit_insn (gen_movsd_hardfloat (operands
[0], mem
));
5017 /* FIXME: In the long term, this switch statement should go away
5018 and be replaced by a sequence of tests based on things like
5024 if (CONSTANT_P (operands
[1])
5025 && GET_CODE (operands
[1]) != CONST_INT
)
5026 operands
[1] = force_const_mem (mode
, operands
[1]);
5031 rs6000_eliminate_indexed_memrefs (operands
);
5038 if (CONSTANT_P (operands
[1])
5039 && ! easy_fp_constant (operands
[1], mode
))
5040 operands
[1] = force_const_mem (mode
, operands
[1]);
5051 if (CONSTANT_P (operands
[1])
5052 && !easy_vector_constant (operands
[1], mode
))
5053 operands
[1] = force_const_mem (mode
, operands
[1]);
5058 /* Use default pattern for address of ELF small data */
5061 && DEFAULT_ABI
== ABI_V4
5062 && (GET_CODE (operands
[1]) == SYMBOL_REF
5063 || GET_CODE (operands
[1]) == CONST
)
5064 && small_data_operand (operands
[1], mode
))
5066 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
5070 if (DEFAULT_ABI
== ABI_V4
5071 && mode
== Pmode
&& mode
== SImode
5072 && flag_pic
== 1 && got_operand (operands
[1], mode
))
5074 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
5078 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
5082 && CONSTANT_P (operands
[1])
5083 && GET_CODE (operands
[1]) != HIGH
5084 && GET_CODE (operands
[1]) != CONST_INT
)
5086 rtx target
= (!can_create_pseudo_p ()
5088 : gen_reg_rtx (mode
));
5090 /* If this is a function address on -mcall-aixdesc,
5091 convert it to the address of the descriptor. */
5092 if (DEFAULT_ABI
== ABI_AIX
5093 && GET_CODE (operands
[1]) == SYMBOL_REF
5094 && XSTR (operands
[1], 0)[0] == '.')
5096 const char *name
= XSTR (operands
[1], 0);
5098 while (*name
== '.')
5100 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
5101 CONSTANT_POOL_ADDRESS_P (new_ref
)
5102 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
5103 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
5104 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
5105 SYMBOL_REF_DATA (new_ref
) = SYMBOL_REF_DATA (operands
[1]);
5106 operands
[1] = new_ref
;
5109 if (DEFAULT_ABI
== ABI_DARWIN
)
5112 if (MACHO_DYNAMIC_NO_PIC_P
)
5114 /* Take care of any required data indirection. */
5115 operands
[1] = rs6000_machopic_legitimize_pic_address (
5116 operands
[1], mode
, operands
[0]);
5117 if (operands
[0] != operands
[1])
5118 emit_insn (gen_rtx_SET (VOIDmode
,
5119 operands
[0], operands
[1]));
5123 emit_insn (gen_macho_high (target
, operands
[1]));
5124 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
5128 emit_insn (gen_elf_high (target
, operands
[1]));
5129 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
5133 /* If this is a SYMBOL_REF that refers to a constant pool entry,
5134 and we have put it in the TOC, we just need to make a TOC-relative
5137 && GET_CODE (operands
[1]) == SYMBOL_REF
5138 && constant_pool_expr_p (operands
[1])
5139 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
5140 get_pool_mode (operands
[1])))
5142 operands
[1] = create_TOC_reference (operands
[1]);
5144 else if (mode
== Pmode
5145 && CONSTANT_P (operands
[1])
5146 && ((GET_CODE (operands
[1]) != CONST_INT
5147 && ! easy_fp_constant (operands
[1], mode
))
5148 || (GET_CODE (operands
[1]) == CONST_INT
5149 && num_insns_constant (operands
[1], mode
) > 2)
5150 || (GET_CODE (operands
[0]) == REG
5151 && FP_REGNO_P (REGNO (operands
[0]))))
5152 && GET_CODE (operands
[1]) != HIGH
5153 && ! legitimate_constant_pool_address_p (operands
[1])
5154 && ! toc_relative_expr_p (operands
[1]))
5156 /* Emit a USE operation so that the constant isn't deleted if
5157 expensive optimizations are turned on because nobody
5158 references it. This should only be done for operands that
5159 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
5160 This should not be done for operands that contain LABEL_REFs.
5161 For now, we just handle the obvious case. */
5162 if (GET_CODE (operands
[1]) != LABEL_REF
)
5163 emit_use (operands
[1]);
5166 /* Darwin uses a special PIC legitimizer. */
5167 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
5170 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
5172 if (operands
[0] != operands
[1])
5173 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
5178 /* If we are to limit the number of things we put in the TOC and
5179 this is a symbol plus a constant we can add in one insn,
5180 just put the symbol in the TOC and add the constant. Don't do
5181 this if reload is in progress. */
5182 if (GET_CODE (operands
[1]) == CONST
5183 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
5184 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
5185 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
5186 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
5187 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
5188 && ! side_effects_p (operands
[0]))
5191 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
5192 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
5194 sym
= force_reg (mode
, sym
);
5196 emit_insn (gen_addsi3 (operands
[0], sym
, other
));
5198 emit_insn (gen_adddi3 (operands
[0], sym
, other
));
5202 operands
[1] = force_const_mem (mode
, operands
[1]);
5205 && GET_CODE (XEXP (operands
[1], 0)) == SYMBOL_REF
5206 && constant_pool_expr_p (XEXP (operands
[1], 0))
5207 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
5208 get_pool_constant (XEXP (operands
[1], 0)),
5209 get_pool_mode (XEXP (operands
[1], 0))))
5212 = gen_const_mem (mode
,
5213 create_TOC_reference (XEXP (operands
[1], 0)));
5214 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
5220 rs6000_eliminate_indexed_memrefs (operands
);
5224 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
5226 gen_rtx_SET (VOIDmode
,
5227 operands
[0], operands
[1]),
5228 gen_rtx_CLOBBER (VOIDmode
,
5229 gen_rtx_SCRATCH (SImode
)))));
5238 /* Above, we may have called force_const_mem which may have returned
5239 an invalid address. If we can, fix this up; otherwise, reload will
5240 have to deal with it. */
5241 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
5242 operands
[1] = validize_mem (operands
[1]);
5245 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
5248 /* Nonzero if we can use a floating-point register to pass this arg. */
5249 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
5250 (SCALAR_FLOAT_MODE_P (MODE) \
5251 && (CUM)->fregno <= FP_ARG_MAX_REG \
5252 && TARGET_HARD_FLOAT && TARGET_FPRS \
5253 && ((TARGET_DOUBLE_FLOAT && (MODE) == DFmode)\
5254 || (TARGET_SINGLE_FLOAT && (MODE) == SFmode)))
5256 /* Nonzero if we can use an AltiVec register to pass this arg. */
5257 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
5258 (ALTIVEC_VECTOR_MODE (MODE) \
5259 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
5260 && TARGET_ALTIVEC_ABI \
5263 /* Return a nonzero value to say to return the function value in
5264 memory, just as large structures are always returned. TYPE will be
5265 the data type of the value, and FNTYPE will be the type of the
5266 function doing the returning, or @code{NULL} for libcalls.
5268 The AIX ABI for the RS/6000 specifies that all structures are
5269 returned in memory. The Darwin ABI does the same. The SVR4 ABI
5270 specifies that structures <= 8 bytes are returned in r3/r4, but a
5271 draft put them in memory, and GCC used to implement the draft
5272 instead of the final standard. Therefore, aix_struct_return
5273 controls this instead of DEFAULT_ABI; V.4 targets needing backward
5274 compatibility can change DRAFT_V4_STRUCT_RET to override the
5275 default, and -m switches get the final word. See
5276 rs6000_override_options for more details.
5278 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
5279 long double support is enabled. These values are returned in memory.
5281 int_size_in_bytes returns -1 for variable size objects, which go in
5282 memory always. The cast to unsigned makes -1 > 8. */
5285 rs6000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
5287 /* In the darwin64 abi, try to use registers for larger structs
5289 if (rs6000_darwin64_abi
5290 && TREE_CODE (type
) == RECORD_TYPE
5291 && int_size_in_bytes (type
) > 0)
5293 CUMULATIVE_ARGS valcum
;
5297 valcum
.fregno
= FP_ARG_MIN_REG
;
5298 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
5299 /* Do a trial code generation as if this were going to be passed
5300 as an argument; if any part goes in memory, we return NULL. */
5301 valret
= rs6000_darwin64_record_arg (&valcum
, type
, 1, true);
5304 /* Otherwise fall through to more conventional ABI rules. */
5307 if (AGGREGATE_TYPE_P (type
)
5308 && (aix_struct_return
5309 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
5312 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5313 modes only exist for GCC vector types if -maltivec. */
5314 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
5315 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
5318 /* Return synthetic vectors in memory. */
5319 if (TREE_CODE (type
) == VECTOR_TYPE
5320 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
5322 static bool warned_for_return_big_vectors
= false;
5323 if (!warned_for_return_big_vectors
)
5325 warning (0, "GCC vector returned by reference: "
5326 "non-standard ABI extension with no compatibility guarantee");
5327 warned_for_return_big_vectors
= true;
5332 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& TYPE_MODE (type
) == TFmode
)
5338 /* Initialize a variable CUM of type CUMULATIVE_ARGS
5339 for a call to a function whose data type is FNTYPE.
5340 For a library call, FNTYPE is 0.
5342 For incoming args we set the number of arguments in the prototype large
5343 so we never return a PARALLEL. */
5346 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
5347 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
5348 int libcall
, int n_named_args
)
5350 static CUMULATIVE_ARGS zero_cumulative
;
5352 *cum
= zero_cumulative
;
5354 cum
->fregno
= FP_ARG_MIN_REG
;
5355 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
5356 cum
->prototype
= (fntype
&& TYPE_ARG_TYPES (fntype
));
5357 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
5358 ? CALL_LIBCALL
: CALL_NORMAL
);
5359 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
5360 cum
->stdarg
= fntype
5361 && (TYPE_ARG_TYPES (fntype
) != 0
5362 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
5363 != void_type_node
));
5365 cum
->nargs_prototype
= 0;
5366 if (incoming
|| cum
->prototype
)
5367 cum
->nargs_prototype
= n_named_args
;
5369 /* Check for a longcall attribute. */
5370 if ((!fntype
&& rs6000_default_long_calls
)
5372 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
5373 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
5374 cum
->call_cookie
|= CALL_LONG
;
5376 if (TARGET_DEBUG_ARG
)
5378 fprintf (stderr
, "\ninit_cumulative_args:");
5381 tree ret_type
= TREE_TYPE (fntype
);
5382 fprintf (stderr
, " ret code = %s,",
5383 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
5386 if (cum
->call_cookie
& CALL_LONG
)
5387 fprintf (stderr
, " longcall,");
5389 fprintf (stderr
, " proto = %d, nargs = %d\n",
5390 cum
->prototype
, cum
->nargs_prototype
);
5395 && TARGET_ALTIVEC_ABI
5396 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
5398 error ("cannot return value in vector register because"
5399 " altivec instructions are disabled, use -maltivec"
5404 /* Return true if TYPE must be passed on the stack and not in registers. */
5407 rs6000_must_pass_in_stack (enum machine_mode mode
, const_tree type
)
5409 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
5410 return must_pass_in_stack_var_size (mode
, type
);
5412 return must_pass_in_stack_var_size_or_pad (mode
, type
);
5415 /* If defined, a C expression which determines whether, and in which
5416 direction, to pad out an argument with extra space. The value
5417 should be of type `enum direction': either `upward' to pad above
5418 the argument, `downward' to pad below, or `none' to inhibit
5421 For the AIX ABI structs are always stored left shifted in their
5425 function_arg_padding (enum machine_mode mode
, const_tree type
)
5427 #ifndef AGGREGATE_PADDING_FIXED
5428 #define AGGREGATE_PADDING_FIXED 0
5430 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
5431 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
5434 if (!AGGREGATE_PADDING_FIXED
)
5436 /* GCC used to pass structures of the same size as integer types as
5437 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
5438 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
5439 passed padded downward, except that -mstrict-align further
5440 muddied the water in that multi-component structures of 2 and 4
5441 bytes in size were passed padded upward.
5443 The following arranges for best compatibility with previous
5444 versions of gcc, but removes the -mstrict-align dependency. */
5445 if (BYTES_BIG_ENDIAN
)
5447 HOST_WIDE_INT size
= 0;
5449 if (mode
== BLKmode
)
5451 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
5452 size
= int_size_in_bytes (type
);
5455 size
= GET_MODE_SIZE (mode
);
5457 if (size
== 1 || size
== 2 || size
== 4)
5463 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
5465 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
5469 /* Fall back to the default. */
5470 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
5473 /* If defined, a C expression that gives the alignment boundary, in bits,
5474 of an argument with the specified mode and type. If it is not defined,
5475 PARM_BOUNDARY is used for all arguments.
5477 V.4 wants long longs and doubles to be double word aligned. Just
5478 testing the mode size is a boneheaded way to do this as it means
5479 that other types such as complex int are also double word aligned.
5480 However, we're stuck with this because changing the ABI might break
5481 existing library interfaces.
5483 Doubleword align SPE vectors.
5484 Quadword align Altivec vectors.
5485 Quadword align large synthetic vector types. */
5488 function_arg_boundary (enum machine_mode mode
, tree type
)
5490 if (DEFAULT_ABI
== ABI_V4
5491 && (GET_MODE_SIZE (mode
) == 8
5492 || (TARGET_HARD_FLOAT
5494 && (mode
== TFmode
|| mode
== TDmode
))))
5496 else if (SPE_VECTOR_MODE (mode
)
5497 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5498 && int_size_in_bytes (type
) >= 8
5499 && int_size_in_bytes (type
) < 16))
5501 else if (ALTIVEC_VECTOR_MODE (mode
)
5502 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5503 && int_size_in_bytes (type
) >= 16))
5505 else if (rs6000_darwin64_abi
&& mode
== BLKmode
5506 && type
&& TYPE_ALIGN (type
) > 64)
5509 return PARM_BOUNDARY
;
5512 /* For a function parm of MODE and TYPE, return the starting word in
5513 the parameter area. NWORDS of the parameter area are already used. */
5516 rs6000_parm_start (enum machine_mode mode
, tree type
, unsigned int nwords
)
5519 unsigned int parm_offset
;
5521 align
= function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
5522 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
5523 return nwords
+ (-(parm_offset
+ nwords
) & align
);
5526 /* Compute the size (in words) of a function argument. */
5528 static unsigned long
5529 rs6000_arg_size (enum machine_mode mode
, tree type
)
5533 if (mode
!= BLKmode
)
5534 size
= GET_MODE_SIZE (mode
);
5536 size
= int_size_in_bytes (type
);
5539 return (size
+ 3) >> 2;
5541 return (size
+ 7) >> 3;
5544 /* Use this to flush pending int fields. */
5547 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
5548 HOST_WIDE_INT bitpos
)
5550 unsigned int startbit
, endbit
;
5551 int intregs
, intoffset
;
5552 enum machine_mode mode
;
5554 if (cum
->intoffset
== -1)
5557 intoffset
= cum
->intoffset
;
5558 cum
->intoffset
= -1;
5560 if (intoffset
% BITS_PER_WORD
!= 0)
5562 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
5564 if (mode
== BLKmode
)
5566 /* We couldn't find an appropriate mode, which happens,
5567 e.g., in packed structs when there are 3 bytes to load.
5568 Back intoffset back to the beginning of the word in this
5570 intoffset
= intoffset
& -BITS_PER_WORD
;
5574 startbit
= intoffset
& -BITS_PER_WORD
;
5575 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
5576 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
5577 cum
->words
+= intregs
;
5580 /* The darwin64 ABI calls for us to recurse down through structs,
5581 looking for elements passed in registers. Unfortunately, we have
5582 to track int register count here also because of misalignments
5583 in powerpc alignment mode. */
5586 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
5588 HOST_WIDE_INT startbitpos
)
5592 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
5593 if (TREE_CODE (f
) == FIELD_DECL
)
5595 HOST_WIDE_INT bitpos
= startbitpos
;
5596 tree ftype
= TREE_TYPE (f
);
5597 enum machine_mode mode
;
5598 if (ftype
== error_mark_node
)
5600 mode
= TYPE_MODE (ftype
);
5602 if (DECL_SIZE (f
) != 0
5603 && host_integerp (bit_position (f
), 1))
5604 bitpos
+= int_bit_position (f
);
5606 /* ??? FIXME: else assume zero offset. */
5608 if (TREE_CODE (ftype
) == RECORD_TYPE
)
5609 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
5610 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
5612 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
5613 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5614 cum
->words
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5616 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
5618 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
5622 else if (cum
->intoffset
== -1)
5623 cum
->intoffset
= bitpos
;
5627 /* Update the data in CUM to advance over an argument
5628 of mode MODE and data type TYPE.
5629 (TYPE is null for libcalls where that information may not be available.)
5631 Note that for args passed by reference, function_arg will be called
5632 with MODE and TYPE set to that of the pointer to the arg, not the arg
5636 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5637 tree type
, int named
, int depth
)
5641 /* Only tick off an argument if we're not recursing. */
5643 cum
->nargs_prototype
--;
5645 if (TARGET_ALTIVEC_ABI
5646 && (ALTIVEC_VECTOR_MODE (mode
)
5647 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5648 && int_size_in_bytes (type
) == 16)))
5652 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
5655 if (!TARGET_ALTIVEC
)
5656 error ("cannot pass argument in vector register because"
5657 " altivec instructions are disabled, use -maltivec"
5660 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
5661 even if it is going to be passed in a vector register.
5662 Darwin does the same for variable-argument functions. */
5663 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
5664 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
5674 /* Vector parameters must be 16-byte aligned. This places
5675 them at 2 mod 4 in terms of words in 32-bit mode, since
5676 the parameter save area starts at offset 24 from the
5677 stack. In 64-bit mode, they just have to start on an
5678 even word, since the parameter save area is 16-byte
5679 aligned. Space for GPRs is reserved even if the argument
5680 will be passed in memory. */
5682 align
= (2 - cum
->words
) & 3;
5684 align
= cum
->words
& 1;
5685 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
5687 if (TARGET_DEBUG_ARG
)
5689 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
5691 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
5692 cum
->nargs_prototype
, cum
->prototype
,
5693 GET_MODE_NAME (mode
));
5697 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
5699 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
5702 else if (rs6000_darwin64_abi
5704 && TREE_CODE (type
) == RECORD_TYPE
5705 && (size
= int_size_in_bytes (type
)) > 0)
5707 /* Variable sized types have size == -1 and are
5708 treated as if consisting entirely of ints.
5709 Pad to 16 byte boundary if needed. */
5710 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
5711 && (cum
->words
% 2) != 0)
5713 /* For varargs, we can just go up by the size of the struct. */
5715 cum
->words
+= (size
+ 7) / 8;
5718 /* It is tempting to say int register count just goes up by
5719 sizeof(type)/8, but this is wrong in a case such as
5720 { int; double; int; } [powerpc alignment]. We have to
5721 grovel through the fields for these too. */
5723 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
5724 rs6000_darwin64_record_arg_advance_flush (cum
,
5725 size
* BITS_PER_UNIT
);
5728 else if (DEFAULT_ABI
== ABI_V4
)
5730 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5731 && (mode
== SFmode
|| mode
== DFmode
5732 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
5733 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)))
5735 /* _Decimal128 must use an even/odd register pair. This assumes
5736 that the register number is odd when fregno is odd. */
5737 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
5740 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
5741 <= FP_ARG_V4_MAX_REG
)
5742 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5745 cum
->fregno
= FP_ARG_V4_MAX_REG
+ 1;
5746 if (mode
== DFmode
|| mode
== TFmode
5747 || mode
== DDmode
|| mode
== TDmode
)
5748 cum
->words
+= cum
->words
& 1;
5749 cum
->words
+= rs6000_arg_size (mode
, type
);
5754 int n_words
= rs6000_arg_size (mode
, type
);
5755 int gregno
= cum
->sysv_gregno
;
5757 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5758 (r7,r8) or (r9,r10). As does any other 2 word item such
5759 as complex int due to a historical mistake. */
5761 gregno
+= (1 - gregno
) & 1;
5763 /* Multi-reg args are not split between registers and stack. */
5764 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5766 /* Long long and SPE vectors are aligned on the stack.
5767 So are other 2 word items such as complex int due to
5768 a historical mistake. */
5770 cum
->words
+= cum
->words
& 1;
5771 cum
->words
+= n_words
;
5774 /* Note: continuing to accumulate gregno past when we've started
5775 spilling to the stack indicates the fact that we've started
5776 spilling to the stack to expand_builtin_saveregs. */
5777 cum
->sysv_gregno
= gregno
+ n_words
;
5780 if (TARGET_DEBUG_ARG
)
5782 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
5783 cum
->words
, cum
->fregno
);
5784 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
5785 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
5786 fprintf (stderr
, "mode = %4s, named = %d\n",
5787 GET_MODE_NAME (mode
), named
);
5792 int n_words
= rs6000_arg_size (mode
, type
);
5793 int start_words
= cum
->words
;
5794 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
5796 cum
->words
= align_words
+ n_words
;
5798 if (SCALAR_FLOAT_MODE_P (mode
)
5799 && TARGET_HARD_FLOAT
&& TARGET_FPRS
5800 && ((TARGET_DOUBLE_FLOAT
&& mode
== DFmode
)
5801 || (TARGET_SINGLE_FLOAT
&& mode
== SFmode
)))
5803 /* _Decimal128 must be passed in an even/odd float register pair.
5804 This assumes that the register number is odd when fregno is
5806 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
5808 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5811 if (TARGET_DEBUG_ARG
)
5813 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
5814 cum
->words
, cum
->fregno
);
5815 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
5816 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
5817 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
5818 named
, align_words
- start_words
, depth
);
5824 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
5831 r1
= gen_rtx_REG (DImode
, gregno
);
5832 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5833 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
5837 r1
= gen_rtx_REG (DImode
, gregno
);
5838 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5839 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
5840 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
5841 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
5844 r1
= gen_rtx_REG (DImode
, gregno
);
5845 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5846 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
5847 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
5848 r5
= gen_rtx_REG (DImode
, gregno
+ 4);
5849 r5
= gen_rtx_EXPR_LIST (VOIDmode
, r5
, GEN_INT (16));
5850 r7
= gen_rtx_REG (DImode
, gregno
+ 6);
5851 r7
= gen_rtx_EXPR_LIST (VOIDmode
, r7
, GEN_INT (24));
5852 return gen_rtx_PARALLEL (mode
, gen_rtvec (4, r1
, r3
, r5
, r7
));
5859 /* Determine where to put a SIMD argument on the SPE. */
5861 rs6000_spe_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5864 int gregno
= cum
->sysv_gregno
;
5866 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
5867 are passed and returned in a pair of GPRs for ABI compatibility. */
5868 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5869 || mode
== DCmode
|| mode
== TCmode
))
5871 int n_words
= rs6000_arg_size (mode
, type
);
5873 /* Doubles go in an odd/even register pair (r5/r6, etc). */
5875 gregno
+= (1 - gregno
) & 1;
5877 /* Multi-reg args are not split between registers and stack. */
5878 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5881 return spe_build_register_parallel (mode
, gregno
);
5885 int n_words
= rs6000_arg_size (mode
, type
);
5887 /* SPE vectors are put in odd registers. */
5888 if (n_words
== 2 && (gregno
& 1) == 0)
5891 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
5894 enum machine_mode m
= SImode
;
5896 r1
= gen_rtx_REG (m
, gregno
);
5897 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
5898 r2
= gen_rtx_REG (m
, gregno
+ 1);
5899 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
5900 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
5907 if (gregno
<= GP_ARG_MAX_REG
)
5908 return gen_rtx_REG (mode
, gregno
);
5914 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
5915 structure between cum->intoffset and bitpos to integer registers. */
5918 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
5919 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
5921 enum machine_mode mode
;
5923 unsigned int startbit
, endbit
;
5924 int this_regno
, intregs
, intoffset
;
5927 if (cum
->intoffset
== -1)
5930 intoffset
= cum
->intoffset
;
5931 cum
->intoffset
= -1;
5933 /* If this is the trailing part of a word, try to only load that
5934 much into the register. Otherwise load the whole register. Note
5935 that in the latter case we may pick up unwanted bits. It's not a
5936 problem at the moment but may wish to revisit. */
5938 if (intoffset
% BITS_PER_WORD
!= 0)
5940 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
5942 if (mode
== BLKmode
)
5944 /* We couldn't find an appropriate mode, which happens,
5945 e.g., in packed structs when there are 3 bytes to load.
5946 Back intoffset back to the beginning of the word in this
5948 intoffset
= intoffset
& -BITS_PER_WORD
;
5955 startbit
= intoffset
& -BITS_PER_WORD
;
5956 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
5957 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
5958 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
5960 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
5963 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
5967 intoffset
/= BITS_PER_UNIT
;
5970 regno
= GP_ARG_MIN_REG
+ this_regno
;
5971 reg
= gen_rtx_REG (mode
, regno
);
5973 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
5976 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
5980 while (intregs
> 0);
5983 /* Recursive workhorse for the following. */
5986 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, const_tree type
,
5987 HOST_WIDE_INT startbitpos
, rtx rvec
[],
5992 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
5993 if (TREE_CODE (f
) == FIELD_DECL
)
5995 HOST_WIDE_INT bitpos
= startbitpos
;
5996 tree ftype
= TREE_TYPE (f
);
5997 enum machine_mode mode
;
5998 if (ftype
== error_mark_node
)
6000 mode
= TYPE_MODE (ftype
);
6002 if (DECL_SIZE (f
) != 0
6003 && host_integerp (bit_position (f
), 1))
6004 bitpos
+= int_bit_position (f
);
6006 /* ??? FIXME: else assume zero offset. */
6008 if (TREE_CODE (ftype
) == RECORD_TYPE
)
6009 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
6010 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
6015 case SCmode
: mode
= SFmode
; break;
6016 case DCmode
: mode
= DFmode
; break;
6017 case TCmode
: mode
= TFmode
; break;
6021 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
6023 = gen_rtx_EXPR_LIST (VOIDmode
,
6024 gen_rtx_REG (mode
, cum
->fregno
++),
6025 GEN_INT (bitpos
/ BITS_PER_UNIT
));
6026 if (mode
== TFmode
|| mode
== TDmode
)
6029 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
6031 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
6033 = gen_rtx_EXPR_LIST (VOIDmode
,
6034 gen_rtx_REG (mode
, cum
->vregno
++),
6035 GEN_INT (bitpos
/ BITS_PER_UNIT
));
6037 else if (cum
->intoffset
== -1)
6038 cum
->intoffset
= bitpos
;
6042 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
6043 the register(s) to be used for each field and subfield of a struct
6044 being passed by value, along with the offset of where the
6045 register's value may be found in the block. FP fields go in FP
6046 register, vector fields go in vector registers, and everything
6047 else goes in int registers, packed as in memory.
6049 This code is also used for function return values. RETVAL indicates
6050 whether this is the case.
6052 Much of this is taken from the SPARC V9 port, which has a similar
6053 calling convention. */
6056 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, const_tree type
,
6057 int named
, bool retval
)
6059 rtx rvec
[FIRST_PSEUDO_REGISTER
];
6060 int k
= 1, kbase
= 1;
6061 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
6062 /* This is a copy; modifications are not visible to our caller. */
6063 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
6064 CUMULATIVE_ARGS
*cum
= ©_cum
;
6066 /* Pad to 16 byte boundary if needed. */
6067 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
6068 && (cum
->words
% 2) != 0)
6075 /* Put entries into rvec[] for individual FP and vector fields, and
6076 for the chunks of memory that go in int regs. Note we start at
6077 element 1; 0 is reserved for an indication of using memory, and
6078 may or may not be filled in below. */
6079 rs6000_darwin64_record_arg_recurse (cum
, type
, 0, rvec
, &k
);
6080 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
6082 /* If any part of the struct went on the stack put all of it there.
6083 This hack is because the generic code for
6084 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
6085 parts of the struct are not at the beginning. */
6089 return NULL_RTX
; /* doesn't go in registers at all */
6091 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
6093 if (k
> 1 || cum
->use_stack
)
6094 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
6099 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
6102 rs6000_mixed_function_arg (enum machine_mode mode
, tree type
, int align_words
)
6106 rtx rvec
[GP_ARG_NUM_REG
+ 1];
6108 if (align_words
>= GP_ARG_NUM_REG
)
6111 n_units
= rs6000_arg_size (mode
, type
);
6113 /* Optimize the simple case where the arg fits in one gpr, except in
6114 the case of BLKmode due to assign_parms assuming that registers are
6115 BITS_PER_WORD wide. */
6117 || (n_units
== 1 && mode
!= BLKmode
))
6118 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6121 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
6122 /* Not all of the arg fits in gprs. Say that it goes in memory too,
6123 using a magic NULL_RTX component.
6124 This is not strictly correct. Only some of the arg belongs in
6125 memory, not all of it. However, the normal scheme using
6126 function_arg_partial_nregs can result in unusual subregs, eg.
6127 (subreg:SI (reg:DF) 4), which are not handled well. The code to
6128 store the whole arg to memory is often more efficient than code
6129 to store pieces, and we know that space is available in the right
6130 place for the whole arg. */
6131 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
6136 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
6137 rtx off
= GEN_INT (i
++ * 4);
6138 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
6140 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
6142 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
6145 /* Determine where to put an argument to a function.
6146 Value is zero to push the argument on the stack,
6147 or a hard register in which to store the argument.
6149 MODE is the argument's machine mode.
6150 TYPE is the data type of the argument (as a tree).
6151 This is null for libcalls where that information may
6153 CUM is a variable of type CUMULATIVE_ARGS which gives info about
6154 the preceding args and about the function being called. It is
6155 not modified in this routine.
6156 NAMED is nonzero if this argument is a named parameter
6157 (otherwise it is an extra parameter matching an ellipsis).
6159 On RS/6000 the first eight words of non-FP are normally in registers
6160 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
6161 Under V.4, the first 8 FP args are in registers.
6163 If this is floating-point and no prototype is specified, we use
6164 both an FP and integer register (or possibly FP reg and stack). Library
6165 functions (when CALL_LIBCALL is set) always have the proper types for args,
6166 so we can pass the FP value just in one register. emit_library_function
6167 doesn't support PARALLEL anyway.
6169 Note that for args passed by reference, function_arg will be called
6170 with MODE and TYPE set to that of the pointer to the arg, not the arg
6174 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6175 tree type
, int named
)
6177 enum rs6000_abi abi
= DEFAULT_ABI
;
6179 /* Return a marker to indicate whether CR1 needs to set or clear the
6180 bit that V.4 uses to say fp args were passed in registers.
6181 Assume that we don't need the marker for software floating point,
6182 or compiler generated library calls. */
6183 if (mode
== VOIDmode
)
6186 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
6188 || (cum
->nargs_prototype
< 0
6189 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))))
6191 /* For the SPE, we need to crxor CR6 always. */
6193 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
6194 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
6195 return GEN_INT (cum
->call_cookie
6196 | ((cum
->fregno
== FP_ARG_MIN_REG
)
6197 ? CALL_V4_SET_FP_ARGS
6198 : CALL_V4_CLEAR_FP_ARGS
));
6201 return GEN_INT (cum
->call_cookie
);
6204 if (rs6000_darwin64_abi
&& mode
== BLKmode
6205 && TREE_CODE (type
) == RECORD_TYPE
)
6207 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, false);
6208 if (rslt
!= NULL_RTX
)
6210 /* Else fall through to usual handling. */
6213 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
6214 if (TARGET_64BIT
&& ! cum
->prototype
)
6216 /* Vector parameters get passed in vector register
6217 and also in GPRs or memory, in absence of prototype. */
6220 align_words
= (cum
->words
+ 1) & ~1;
6222 if (align_words
>= GP_ARG_NUM_REG
)
6228 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6230 return gen_rtx_PARALLEL (mode
,
6232 gen_rtx_EXPR_LIST (VOIDmode
,
6234 gen_rtx_EXPR_LIST (VOIDmode
,
6235 gen_rtx_REG (mode
, cum
->vregno
),
6239 return gen_rtx_REG (mode
, cum
->vregno
);
6240 else if (TARGET_ALTIVEC_ABI
6241 && (ALTIVEC_VECTOR_MODE (mode
)
6242 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
6243 && int_size_in_bytes (type
) == 16)))
6245 if (named
|| abi
== ABI_V4
)
6249 /* Vector parameters to varargs functions under AIX or Darwin
6250 get passed in memory and possibly also in GPRs. */
6251 int align
, align_words
, n_words
;
6252 enum machine_mode part_mode
;
6254 /* Vector parameters must be 16-byte aligned. This places them at
6255 2 mod 4 in terms of words in 32-bit mode, since the parameter
6256 save area starts at offset 24 from the stack. In 64-bit mode,
6257 they just have to start on an even word, since the parameter
6258 save area is 16-byte aligned. */
6260 align
= (2 - cum
->words
) & 3;
6262 align
= cum
->words
& 1;
6263 align_words
= cum
->words
+ align
;
6265 /* Out of registers? Memory, then. */
6266 if (align_words
>= GP_ARG_NUM_REG
)
6269 if (TARGET_32BIT
&& TARGET_POWERPC64
)
6270 return rs6000_mixed_function_arg (mode
, type
, align_words
);
6272 /* The vector value goes in GPRs. Only the part of the
6273 value in GPRs is reported here. */
6275 n_words
= rs6000_arg_size (mode
, type
);
6276 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
6277 /* Fortunately, there are only two possibilities, the value
6278 is either wholly in GPRs or half in GPRs and half not. */
6281 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
6284 else if (TARGET_SPE_ABI
&& TARGET_SPE
6285 && (SPE_VECTOR_MODE (mode
)
6286 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
6289 || mode
== TCmode
))))
6290 return rs6000_spe_function_arg (cum
, mode
, type
);
6292 else if (abi
== ABI_V4
)
6294 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
6295 && (mode
== SFmode
|| mode
== DFmode
6296 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
6297 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
6299 /* _Decimal128 must use an even/odd register pair. This assumes
6300 that the register number is odd when fregno is odd. */
6301 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
6304 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
6305 <= FP_ARG_V4_MAX_REG
)
6306 return gen_rtx_REG (mode
, cum
->fregno
);
6312 int n_words
= rs6000_arg_size (mode
, type
);
6313 int gregno
= cum
->sysv_gregno
;
6315 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
6316 (r7,r8) or (r9,r10). As does any other 2 word item such
6317 as complex int due to a historical mistake. */
6319 gregno
+= (1 - gregno
) & 1;
6321 /* Multi-reg args are not split between registers and stack. */
6322 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
6325 if (TARGET_32BIT
&& TARGET_POWERPC64
)
6326 return rs6000_mixed_function_arg (mode
, type
,
6327 gregno
- GP_ARG_MIN_REG
);
6328 return gen_rtx_REG (mode
, gregno
);
6333 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
6335 /* _Decimal128 must be passed in an even/odd float register pair.
6336 This assumes that the register number is odd when fregno is odd. */
6337 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
6340 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
6342 rtx rvec
[GP_ARG_NUM_REG
+ 1];
6346 enum machine_mode fmode
= mode
;
6347 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
6349 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
6351 /* Currently, we only ever need one reg here because complex
6352 doubles are split. */
6353 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
6354 && (fmode
== TFmode
|| fmode
== TDmode
));
6356 /* Long double or _Decimal128 split over regs and memory. */
6357 fmode
= DECIMAL_FLOAT_MODE_P (fmode
) ? DDmode
: DFmode
;
6360 /* Do we also need to pass this arg in the parameter save
6363 && (cum
->nargs_prototype
<= 0
6364 || (DEFAULT_ABI
== ABI_AIX
6366 && align_words
>= GP_ARG_NUM_REG
)));
6368 if (!needs_psave
&& mode
== fmode
)
6369 return gen_rtx_REG (fmode
, cum
->fregno
);
6374 /* Describe the part that goes in gprs or the stack.
6375 This piece must come first, before the fprs. */
6376 if (align_words
< GP_ARG_NUM_REG
)
6378 unsigned long n_words
= rs6000_arg_size (mode
, type
);
6380 if (align_words
+ n_words
> GP_ARG_NUM_REG
6381 || (TARGET_32BIT
&& TARGET_POWERPC64
))
6383 /* If this is partially on the stack, then we only
6384 include the portion actually in registers here. */
6385 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
6388 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
6389 /* Not all of the arg fits in gprs. Say that it
6390 goes in memory too, using a magic NULL_RTX
6391 component. Also see comment in
6392 rs6000_mixed_function_arg for why the normal
6393 function_arg_partial_nregs scheme doesn't work
6395 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
6399 r
= gen_rtx_REG (rmode
,
6400 GP_ARG_MIN_REG
+ align_words
);
6401 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
6402 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
6404 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
6408 /* The whole arg fits in gprs. */
6409 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6410 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
6414 /* It's entirely in memory. */
6415 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
6418 /* Describe where this piece goes in the fprs. */
6419 r
= gen_rtx_REG (fmode
, cum
->fregno
);
6420 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
6422 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
6424 else if (align_words
< GP_ARG_NUM_REG
)
6426 if (TARGET_32BIT
&& TARGET_POWERPC64
)
6427 return rs6000_mixed_function_arg (mode
, type
, align_words
);
6429 if (mode
== BLKmode
)
6432 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6439 /* For an arg passed partly in registers and partly in memory, this is
6440 the number of bytes passed in registers. For args passed entirely in
6441 registers or entirely in memory, zero. When an arg is described by a
6442 PARALLEL, perhaps using more than one register type, this function
6443 returns the number of bytes used by the first element of the PARALLEL. */
6446 rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6447 tree type
, bool named
)
6452 if (DEFAULT_ABI
== ABI_V4
)
6455 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
6456 && cum
->nargs_prototype
>= 0)
6459 /* In this complicated case we just disable the partial_nregs code. */
6460 if (rs6000_darwin64_abi
&& mode
== BLKmode
6461 && TREE_CODE (type
) == RECORD_TYPE
6462 && int_size_in_bytes (type
) > 0)
6465 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
6467 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
6469 /* If we are passing this arg in the fixed parameter save area
6470 (gprs or memory) as well as fprs, then this function should
6471 return the number of partial bytes passed in the parameter
6472 save area rather than partial bytes passed in fprs. */
6474 && (cum
->nargs_prototype
<= 0
6475 || (DEFAULT_ABI
== ABI_AIX
6477 && align_words
>= GP_ARG_NUM_REG
)))
6479 else if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3)
6480 > FP_ARG_MAX_REG
+ 1)
6481 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
6482 else if (cum
->nargs_prototype
>= 0)
6486 if (align_words
< GP_ARG_NUM_REG
6487 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
6488 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
6490 if (ret
!= 0 && TARGET_DEBUG_ARG
)
6491 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
6496 /* A C expression that indicates when an argument must be passed by
6497 reference. If nonzero for an argument, a copy of that argument is
6498 made in memory and a pointer to the argument is passed instead of
6499 the argument itself. The pointer is passed in whatever way is
6500 appropriate for passing a pointer to that type.
6502 Under V.4, aggregates and long double are passed by reference.
6504 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
6505 reference unless the AltiVec vector extension ABI is in force.
6507 As an extension to all ABIs, variable sized types are passed by
6511 rs6000_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
6512 enum machine_mode mode
, const_tree type
,
6513 bool named ATTRIBUTE_UNUSED
)
6515 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& mode
== TFmode
)
6517 if (TARGET_DEBUG_ARG
)
6518 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
6525 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
6527 if (TARGET_DEBUG_ARG
)
6528 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
6532 if (int_size_in_bytes (type
) < 0)
6534 if (TARGET_DEBUG_ARG
)
6535 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
6539 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6540 modes only exist for GCC vector types if -maltivec. */
6541 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
6543 if (TARGET_DEBUG_ARG
)
6544 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
6548 /* Pass synthetic vectors in memory. */
6549 if (TREE_CODE (type
) == VECTOR_TYPE
6550 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
6552 static bool warned_for_pass_big_vectors
= false;
6553 if (TARGET_DEBUG_ARG
)
6554 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
6555 if (!warned_for_pass_big_vectors
)
6557 warning (0, "GCC vector passed by reference: "
6558 "non-standard ABI extension with no compatibility guarantee");
6559 warned_for_pass_big_vectors
= true;
6568 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
6571 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
6576 for (i
= 0; i
< nregs
; i
++)
6578 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
6579 if (reload_completed
)
6581 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
6584 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
6585 i
* GET_MODE_SIZE (reg_mode
));
6588 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
6592 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
6596 /* Perform any needed actions needed for a function that is receiving a
6597 variable number of arguments.
6601 MODE and TYPE are the mode and type of the current parameter.
6603 PRETEND_SIZE is a variable that should be set to the amount of stack
6604 that must be pushed by the prolog to pretend that our caller pushed
6607 Normally, this macro will push all remaining incoming registers on the
6608 stack and set PRETEND_SIZE to the length of the registers pushed. */
6611 setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6612 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
6615 CUMULATIVE_ARGS next_cum
;
6616 int reg_size
= TARGET_32BIT
? 4 : 8;
6617 rtx save_area
= NULL_RTX
, mem
;
6618 int first_reg_offset
;
6621 /* Skip the last named argument. */
6623 function_arg_advance (&next_cum
, mode
, type
, 1, 0);
6625 if (DEFAULT_ABI
== ABI_V4
)
6627 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
6631 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
6632 HOST_WIDE_INT offset
= 0;
6634 /* Try to optimize the size of the varargs save area.
6635 The ABI requires that ap.reg_save_area is doubleword
6636 aligned, but we don't need to allocate space for all
6637 the bytes, only those to which we actually will save
6639 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
6640 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
6641 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
6642 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
6643 && cfun
->va_list_fpr_size
)
6646 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
6647 * UNITS_PER_FP_WORD
;
6648 if (cfun
->va_list_fpr_size
6649 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
6650 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
6652 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
6653 * UNITS_PER_FP_WORD
;
6657 offset
= -((first_reg_offset
* reg_size
) & ~7);
6658 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
6660 gpr_reg_num
= cfun
->va_list_gpr_size
;
6661 if (reg_size
== 4 && (first_reg_offset
& 1))
6664 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
6667 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
6669 - (int) (GP_ARG_NUM_REG
* reg_size
);
6671 if (gpr_size
+ fpr_size
)
6674 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
6675 gcc_assert (GET_CODE (reg_save_area
) == MEM
);
6676 reg_save_area
= XEXP (reg_save_area
, 0);
6677 if (GET_CODE (reg_save_area
) == PLUS
)
6679 gcc_assert (XEXP (reg_save_area
, 0)
6680 == virtual_stack_vars_rtx
);
6681 gcc_assert (GET_CODE (XEXP (reg_save_area
, 1)) == CONST_INT
);
6682 offset
+= INTVAL (XEXP (reg_save_area
, 1));
6685 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
6688 cfun
->machine
->varargs_save_offset
= offset
;
6689 save_area
= plus_constant (virtual_stack_vars_rtx
, offset
);
6694 first_reg_offset
= next_cum
.words
;
6695 save_area
= virtual_incoming_args_rtx
;
6697 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
6698 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
6701 set
= get_varargs_alias_set ();
6702 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
6703 && cfun
->va_list_gpr_size
)
6705 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
6707 if (va_list_gpr_counter_field
)
6709 /* V4 va_list_gpr_size counts number of registers needed. */
6710 if (nregs
> cfun
->va_list_gpr_size
)
6711 nregs
= cfun
->va_list_gpr_size
;
6715 /* char * va_list instead counts number of bytes needed. */
6716 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
6717 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
6720 mem
= gen_rtx_MEM (BLKmode
,
6721 plus_constant (save_area
,
6722 first_reg_offset
* reg_size
));
6723 MEM_NOTRAP_P (mem
) = 1;
6724 set_mem_alias_set (mem
, set
);
6725 set_mem_align (mem
, BITS_PER_WORD
);
6727 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
6731 /* Save FP registers if needed. */
6732 if (DEFAULT_ABI
== ABI_V4
6733 && TARGET_HARD_FLOAT
&& TARGET_FPRS
6735 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
6736 && cfun
->va_list_fpr_size
)
6738 int fregno
= next_cum
.fregno
, nregs
;
6739 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
6740 rtx lab
= gen_label_rtx ();
6741 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
6742 * UNITS_PER_FP_WORD
);
6745 (gen_rtx_SET (VOIDmode
,
6747 gen_rtx_IF_THEN_ELSE (VOIDmode
,
6748 gen_rtx_NE (VOIDmode
, cr1
,
6750 gen_rtx_LABEL_REF (VOIDmode
, lab
),
6754 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
6755 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
6757 mem
= gen_rtx_MEM ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
6759 plus_constant (save_area
, off
));
6760 MEM_NOTRAP_P (mem
) = 1;
6761 set_mem_alias_set (mem
, set
);
6762 set_mem_align (mem
, GET_MODE_ALIGNMENT (
6763 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
6764 ? DFmode
: SFmode
));
6765 emit_move_insn (mem
, gen_rtx_REG (
6766 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
6767 ? DFmode
: SFmode
, fregno
));
6774 /* Create the va_list data type. */
6777 rs6000_build_builtin_va_list (void)
6779 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
6781 /* For AIX, prefer 'char *' because that's what the system
6782 header files like. */
6783 if (DEFAULT_ABI
!= ABI_V4
)
6784 return build_pointer_type (char_type_node
);
6786 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
6787 type_decl
= build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
6789 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("gpr"),
6790 unsigned_char_type_node
);
6791 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("fpr"),
6792 unsigned_char_type_node
);
6793 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
6795 f_res
= build_decl (FIELD_DECL
, get_identifier ("reserved"),
6796 short_unsigned_type_node
);
6797 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("overflow_arg_area"),
6799 f_sav
= build_decl (FIELD_DECL
, get_identifier ("reg_save_area"),
6802 va_list_gpr_counter_field
= f_gpr
;
6803 va_list_fpr_counter_field
= f_fpr
;
6805 DECL_FIELD_CONTEXT (f_gpr
) = record
;
6806 DECL_FIELD_CONTEXT (f_fpr
) = record
;
6807 DECL_FIELD_CONTEXT (f_res
) = record
;
6808 DECL_FIELD_CONTEXT (f_ovf
) = record
;
6809 DECL_FIELD_CONTEXT (f_sav
) = record
;
6811 TREE_CHAIN (record
) = type_decl
;
6812 TYPE_NAME (record
) = type_decl
;
6813 TYPE_FIELDS (record
) = f_gpr
;
6814 TREE_CHAIN (f_gpr
) = f_fpr
;
6815 TREE_CHAIN (f_fpr
) = f_res
;
6816 TREE_CHAIN (f_res
) = f_ovf
;
6817 TREE_CHAIN (f_ovf
) = f_sav
;
6819 layout_type (record
);
6821 /* The correct type is an array type of one element. */
6822 return build_array_type (record
, build_index_type (size_zero_node
));
6825 /* Implement va_start. */
6828 rs6000_va_start (tree valist
, rtx nextarg
)
6830 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
6831 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
6832 tree gpr
, fpr
, ovf
, sav
, t
;
6834 /* Only SVR4 needs something special. */
6835 if (DEFAULT_ABI
!= ABI_V4
)
6837 std_expand_builtin_va_start (valist
, nextarg
);
6841 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6842 f_fpr
= TREE_CHAIN (f_gpr
);
6843 f_res
= TREE_CHAIN (f_fpr
);
6844 f_ovf
= TREE_CHAIN (f_res
);
6845 f_sav
= TREE_CHAIN (f_ovf
);
6847 valist
= build_va_arg_indirect_ref (valist
);
6848 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6849 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
6851 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
6853 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
6856 /* Count number of gp and fp argument registers used. */
6857 words
= crtl
->args
.info
.words
;
6858 n_gpr
= MIN (crtl
->args
.info
.sysv_gregno
- GP_ARG_MIN_REG
,
6860 n_fpr
= MIN (crtl
->args
.info
.fregno
- FP_ARG_MIN_REG
,
6863 if (TARGET_DEBUG_ARG
)
6864 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
6865 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
6866 words
, n_gpr
, n_fpr
);
6868 if (cfun
->va_list_gpr_size
)
6870 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
6871 build_int_cst (NULL_TREE
, n_gpr
));
6872 TREE_SIDE_EFFECTS (t
) = 1;
6873 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6876 if (cfun
->va_list_fpr_size
)
6878 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
6879 build_int_cst (NULL_TREE
, n_fpr
));
6880 TREE_SIDE_EFFECTS (t
) = 1;
6881 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6884 /* Find the overflow area. */
6885 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
6887 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ovf
), t
,
6888 size_int (words
* UNITS_PER_WORD
));
6889 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
6890 TREE_SIDE_EFFECTS (t
) = 1;
6891 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6893 /* If there were no va_arg invocations, don't set up the register
6895 if (!cfun
->va_list_gpr_size
6896 && !cfun
->va_list_fpr_size
6897 && n_gpr
< GP_ARG_NUM_REG
6898 && n_fpr
< FP_ARG_V4_MAX_REG
)
6901 /* Find the register save area. */
6902 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
6903 if (cfun
->machine
->varargs_save_offset
)
6904 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (sav
), t
,
6905 size_int (cfun
->machine
->varargs_save_offset
));
6906 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
6907 TREE_SIDE_EFFECTS (t
) = 1;
6908 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6911 /* Implement va_arg. */
6914 rs6000_gimplify_va_arg (tree valist
, tree type
, gimple_seq
*pre_p
,
6917 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
6918 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
6919 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
6920 tree lab_false
, lab_over
, addr
;
6922 tree ptrtype
= build_pointer_type (type
);
6926 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
6928 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
6929 return build_va_arg_indirect_ref (t
);
6932 if (DEFAULT_ABI
!= ABI_V4
)
6934 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
6936 tree elem_type
= TREE_TYPE (type
);
6937 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
6938 int elem_size
= GET_MODE_SIZE (elem_mode
);
6940 if (elem_size
< UNITS_PER_WORD
)
6942 tree real_part
, imag_part
;
6943 gimple_seq post
= NULL
;
6945 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
6947 /* Copy the value into a temporary, lest the formal temporary
6948 be reused out from under us. */
6949 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
6950 gimple_seq_add_seq (pre_p
, post
);
6952 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
6955 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
6959 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
6962 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6963 f_fpr
= TREE_CHAIN (f_gpr
);
6964 f_res
= TREE_CHAIN (f_fpr
);
6965 f_ovf
= TREE_CHAIN (f_res
);
6966 f_sav
= TREE_CHAIN (f_ovf
);
6968 valist
= build_va_arg_indirect_ref (valist
);
6969 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6970 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
6972 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
6974 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
6977 size
= int_size_in_bytes (type
);
6978 rsize
= (size
+ 3) / 4;
6981 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
6982 && ((TARGET_SINGLE_FLOAT
&& TYPE_MODE (type
) == SFmode
)
6983 || (TARGET_DOUBLE_FLOAT
6984 && (TYPE_MODE (type
) == DFmode
6985 || TYPE_MODE (type
) == TFmode
6986 || TYPE_MODE (type
) == SDmode
6987 || TYPE_MODE (type
) == DDmode
6988 || TYPE_MODE (type
) == TDmode
))))
6990 /* FP args go in FP registers, if present. */
6992 n_reg
= (size
+ 7) / 8;
6993 sav_ofs
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4) * 4;
6994 sav_scale
= ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? 8 : 4);
6995 if (TYPE_MODE (type
) != SFmode
&& TYPE_MODE (type
) != SDmode
)
7000 /* Otherwise into GP registers. */
7009 /* Pull the value out of the saved registers.... */
7012 addr
= create_tmp_var (ptr_type_node
, "addr");
7013 DECL_POINTER_ALIAS_SET (addr
) = get_varargs_alias_set ();
7015 /* AltiVec vectors never go in registers when -mabi=altivec. */
7016 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
7020 lab_false
= create_artificial_label ();
7021 lab_over
= create_artificial_label ();
7023 /* Long long and SPE vectors are aligned in the registers.
7024 As are any other 2 gpr item such as complex int due to a
7025 historical mistake. */
7027 if (n_reg
== 2 && reg
== gpr
)
7030 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
7031 build_int_cst (TREE_TYPE (reg
), n_reg
- 1));
7032 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
),
7033 unshare_expr (reg
), u
);
7035 /* _Decimal128 is passed in even/odd fpr pairs; the stored
7036 reg number is 0 for f1, so we want to make it odd. */
7037 else if (reg
== fpr
&& TYPE_MODE (type
) == TDmode
)
7040 t
= build2 (BIT_IOR_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
7041 build_int_cst (TREE_TYPE (reg
), 1));
7042 u
= build2 (MODIFY_EXPR
, void_type_node
, unshare_expr (reg
), t
);
7045 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
7046 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
7047 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
7048 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
7049 gimplify_and_add (t
, pre_p
);
7053 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, sav
, size_int (sav_ofs
));
7055 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
7056 build_int_cst (TREE_TYPE (reg
), n_reg
));
7057 u
= fold_convert (sizetype
, u
);
7058 u
= build2 (MULT_EXPR
, sizetype
, u
, size_int (sav_scale
));
7059 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
, u
);
7061 /* _Decimal32 varargs are located in the second word of the 64-bit
7062 FP register for 32-bit binaries. */
7063 if (!TARGET_POWERPC64
7064 && TARGET_HARD_FLOAT
&& TARGET_FPRS
7065 && TYPE_MODE (type
) == SDmode
)
7066 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
7068 gimplify_assign (addr
, t
, pre_p
);
7070 gimple_seq_add_stmt (pre_p
, gimple_build_goto (lab_over
));
7072 stmt
= gimple_build_label (lab_false
);
7073 gimple_seq_add_stmt (pre_p
, stmt
);
7075 if ((n_reg
== 2 && !regalign
) || n_reg
> 2)
7077 /* Ensure that we don't find any more args in regs.
7078 Alignment has taken care of for special cases. */
7079 gimplify_assign (reg
, build_int_cst (TREE_TYPE (reg
), 8), pre_p
);
7083 /* ... otherwise out of the overflow area. */
7085 /* Care for on-stack alignment if needed. */
7089 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (align
- 1));
7090 t
= fold_convert (sizetype
, t
);
7091 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
7093 t
= fold_convert (TREE_TYPE (ovf
), t
);
7095 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
7097 gimplify_assign (unshare_expr (addr
), t
, pre_p
);
7099 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
7100 gimplify_assign (unshare_expr (ovf
), t
, pre_p
);
7104 stmt
= gimple_build_label (lab_over
);
7105 gimple_seq_add_stmt (pre_p
, stmt
);
7108 if (STRICT_ALIGNMENT
7109 && (TYPE_ALIGN (type
)
7110 > (unsigned) BITS_PER_UNIT
* (align
< 4 ? 4 : align
)))
7112 /* The value (of type complex double, for example) may not be
7113 aligned in memory in the saved registers, so copy via a
7114 temporary. (This is the same code as used for SPARC.) */
7115 tree tmp
= create_tmp_var (type
, "va_arg_tmp");
7116 tree dest_addr
= build_fold_addr_expr (tmp
);
7118 tree copy
= build_call_expr (implicit_built_in_decls
[BUILT_IN_MEMCPY
],
7119 3, dest_addr
, addr
, size_int (rsize
* 4));
7121 gimplify_and_add (copy
, pre_p
);
7125 addr
= fold_convert (ptrtype
, addr
);
7126 return build_va_arg_indirect_ref (addr
);
7132 def_builtin (int mask
, const char *name
, tree type
, int code
)
7134 if ((mask
& target_flags
) || TARGET_PAIRED_FLOAT
)
7136 if (rs6000_builtin_decls
[code
])
7139 rs6000_builtin_decls
[code
] =
7140 add_builtin_function (name
, type
, code
, BUILT_IN_MD
,
7145 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
7147 static const struct builtin_description bdesc_3arg
[] =
7149 { MASK_ALTIVEC
, CODE_FOR_altivec_vmaddfp
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
7150 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
7151 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
7152 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
7153 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
7154 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
7155 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
7156 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
7157 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
7158 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
7159 { MASK_ALTIVEC
, CODE_FOR_altivec_vnmsubfp
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
7160 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
7161 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
7162 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
7163 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
7164 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
7165 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
7166 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
7167 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
7168 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
7169 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
7170 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
7171 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
7173 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
7174 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
7175 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
7176 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
7177 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
7178 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
7179 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
7180 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
7181 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
7182 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
7183 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
7184 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
7185 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
7186 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
7187 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
7189 { 0, CODE_FOR_paired_msub
, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB
},
7190 { 0, CODE_FOR_paired_madd
, "__builtin_paired_madd", PAIRED_BUILTIN_MADD
},
7191 { 0, CODE_FOR_paired_madds0
, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0
},
7192 { 0, CODE_FOR_paired_madds1
, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1
},
7193 { 0, CODE_FOR_paired_nmsub
, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB
},
7194 { 0, CODE_FOR_paired_nmadd
, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD
},
7195 { 0, CODE_FOR_paired_sum0
, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0
},
7196 { 0, CODE_FOR_paired_sum1
, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1
},
7197 { 0, CODE_FOR_selv2sf4
, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4
},
7200 /* DST operations: void foo (void *, const int, const char). */
7202 static const struct builtin_description bdesc_dst
[] =
7204 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
7205 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
7206 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
7207 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
7209 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
7210 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
7211 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
7212 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
7215 /* Simple binary operations: VECc = foo (VECa, VECb). */
7217 static struct builtin_description bdesc_2arg
[] =
7219 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
7220 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
7221 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
7222 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
7223 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
7224 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
7225 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
7226 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
7227 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
7228 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
7229 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
7230 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
7231 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
7232 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
7233 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
7234 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
7235 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
7236 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
7237 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
7238 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
7239 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
7240 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
7241 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequb
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
7242 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequh
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
7243 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequw
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
7244 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpeqfp
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
7245 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgefp
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
7246 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtub
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
7247 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsb
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
7248 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuh
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
7249 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsh
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
7250 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuw
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
7251 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsw
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
7252 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtfp
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
7253 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
7254 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
7255 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
7256 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
7257 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
7258 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
7259 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
7260 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
7261 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
7262 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
7263 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
7264 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
7265 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
7266 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
7267 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
7268 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
7269 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
7270 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
7271 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
7272 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
7273 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
7274 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
7275 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
7276 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
7277 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
7278 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
7279 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
7280 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
7281 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
7282 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
7283 { MASK_ALTIVEC
, CODE_FOR_altivec_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
7284 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
7285 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
7286 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
7287 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
7288 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
7289 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
7290 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
7291 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
7292 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
7293 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
7294 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlb
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
7295 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlh
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
7296 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlw
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
7297 { MASK_ALTIVEC
, CODE_FOR_vashlv16qi3
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
7298 { MASK_ALTIVEC
, CODE_FOR_vashlv8hi3
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
7299 { MASK_ALTIVEC
, CODE_FOR_vashlv4si3
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
7300 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
7301 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
7302 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
7303 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
7304 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
7305 { MASK_ALTIVEC
, CODE_FOR_vlshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
7306 { MASK_ALTIVEC
, CODE_FOR_vlshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
7307 { MASK_ALTIVEC
, CODE_FOR_vlshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
7308 { MASK_ALTIVEC
, CODE_FOR_vashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
7309 { MASK_ALTIVEC
, CODE_FOR_vashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
7310 { MASK_ALTIVEC
, CODE_FOR_vashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
7311 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
7312 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
7313 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
7314 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
7315 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
7316 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
7317 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
7318 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
7319 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
7320 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
7321 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
7322 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
7323 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
7324 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
7325 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
7326 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
7327 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
7328 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
7329 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
7331 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
7332 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
7333 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
7334 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
7335 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
7336 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
7337 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
7338 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
7339 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
7340 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
7341 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
7342 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
7343 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
7344 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
7345 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
7346 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
7347 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
7348 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
7349 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
7350 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
7351 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
7352 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
7353 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
7354 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
7355 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
7356 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
7357 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
7358 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
7359 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
7360 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
7361 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
7362 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
7363 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
7364 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
7365 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
7366 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
7367 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
7368 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
7369 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
7370 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
7371 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
7372 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
7373 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
7374 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
7375 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
7376 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
7377 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
7378 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
7379 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
7380 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
7381 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
7382 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
7383 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
7384 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
7385 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
7386 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
7387 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
7388 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
7389 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
7390 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
7391 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
7392 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
7393 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
7394 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
7395 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
7396 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
7397 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
7398 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
7399 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
7400 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
7401 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
7402 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
7403 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
7404 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
7405 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
7406 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
7407 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
7408 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
7409 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
7410 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
7411 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
7412 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
7413 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
7414 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
7415 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
7416 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
7417 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
7418 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
7419 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
7420 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
7421 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
7422 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
7423 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
7424 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
7425 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
7426 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
7427 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
7428 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
7429 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
7430 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
7431 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
7432 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
7433 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
7434 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
7435 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
7436 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
7437 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
7438 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
7439 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
7440 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
7441 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
7442 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
7443 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
7444 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
7445 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
7446 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
7447 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
7448 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
7449 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
7450 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
7451 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
7452 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
7453 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
7454 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
7455 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
7456 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
7457 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
7459 { 0, CODE_FOR_divv2sf3
, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3
},
7460 { 0, CODE_FOR_addv2sf3
, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3
},
7461 { 0, CODE_FOR_subv2sf3
, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3
},
7462 { 0, CODE_FOR_mulv2sf3
, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3
},
7463 { 0, CODE_FOR_paired_muls0
, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0
},
7464 { 0, CODE_FOR_paired_muls1
, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1
},
7465 { 0, CODE_FOR_paired_merge00
, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00
},
7466 { 0, CODE_FOR_paired_merge01
, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01
},
7467 { 0, CODE_FOR_paired_merge10
, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10
},
7468 { 0, CODE_FOR_paired_merge11
, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11
},
7470 /* Place holder, leave as first spe builtin. */
7471 { 0, CODE_FOR_spe_evaddw
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
7472 { 0, CODE_FOR_spe_evand
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
7473 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
7474 { 0, CODE_FOR_spe_evdivws
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
7475 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
7476 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
7477 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
7478 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
7479 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
7480 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
7481 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
7482 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
7483 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
7484 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
7485 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
7486 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
7487 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
7488 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
7489 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
7490 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
7491 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
7492 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
7493 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
7494 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
7495 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
7496 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
7497 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
7498 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
7499 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
7500 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
7501 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
7502 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
7503 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
7504 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
7505 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
7506 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
7507 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
7508 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
7509 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
7510 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
7511 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
7512 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
7513 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
7514 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
7515 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
7516 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
7517 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
7518 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
7519 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
7520 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
7521 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
7522 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
7523 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
7524 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
7525 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
7526 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
7527 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
7528 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
7529 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
7530 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
7531 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
7532 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
7533 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
7534 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
7535 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
7536 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
7537 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
7538 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
7539 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
7540 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
7541 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
7542 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
7543 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
7544 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
7545 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
7546 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
7547 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
7548 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
7549 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
7550 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
7551 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
7552 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
7553 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
7554 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
7555 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
7556 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
7557 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
7558 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
7559 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
7560 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
7561 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
7562 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
7563 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
7564 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
7565 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
7566 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
7567 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
7568 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
7569 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
7570 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
7571 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
7572 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
7573 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
7574 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
7575 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
7576 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
7577 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
7578 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
7579 { 0, CODE_FOR_spe_evsubfw
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
7581 /* SPE binary operations expecting a 5-bit unsigned literal. */
7582 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
7584 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
7585 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
7586 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
7587 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
7588 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
7589 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
7590 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
7591 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
7592 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
7593 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
7594 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
7595 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
7596 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
7597 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
7598 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
7599 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
7600 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
7601 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
7602 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
7603 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
7604 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
7605 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
7606 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
7607 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
7608 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
7609 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
7611 /* Place-holder. Leave as last binary SPE builtin. */
7612 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
7615 /* AltiVec predicates. */
7617 struct builtin_description_predicates
7619 const unsigned int mask
;
7620 const enum insn_code icode
;
7622 const char *const name
;
7623 const enum rs6000_builtins code
;
7626 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
7628 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P
},
7629 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
7630 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
7631 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
7632 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P
},
7633 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P
},
7634 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P
},
7635 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P
},
7636 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P
},
7637 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P
},
7638 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P
},
7639 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P
},
7640 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P
},
7642 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P
},
7643 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P
},
7644 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P
}
7647 /* SPE predicates. */
7648 static struct builtin_description bdesc_spe_predicates
[] =
7650 /* Place-holder. Leave as first. */
7651 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
7652 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
7653 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
7654 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
7655 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
7656 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
7657 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
7658 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
7659 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
7660 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
7661 /* Place-holder. Leave as last. */
7662 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
7665 /* SPE evsel predicates. */
7666 static struct builtin_description bdesc_spe_evsel
[] =
7668 /* Place-holder. Leave as first. */
7669 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
7670 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
7671 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
7672 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
7673 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
7674 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
7675 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
7676 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
7677 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
7678 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
7679 /* Place-holder. Leave as last. */
7680 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
7683 /* PAIRED predicates. */
7684 static const struct builtin_description bdesc_paired_preds
[] =
7686 /* Place-holder. Leave as first. */
7687 { 0, CODE_FOR_paired_cmpu0
, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0
},
7688 /* Place-holder. Leave as last. */
7689 { 0, CODE_FOR_paired_cmpu1
, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1
},
7692 /* ABS* operations. */
7694 static const struct builtin_description bdesc_abs
[] =
7696 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
7697 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
7698 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
7699 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
7700 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
7701 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
7702 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
}
7705 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
7708 static struct builtin_description bdesc_1arg
[] =
7710 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
7711 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
7712 { MASK_ALTIVEC
, CODE_FOR_altivec_vrefp
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
7713 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfim
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
7714 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
7715 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfip
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
7716 { MASK_ALTIVEC
, CODE_FOR_ftruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
7717 { MASK_ALTIVEC
, CODE_FOR_altivec_vrsqrtefp
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
7718 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
7719 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
7720 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
7721 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
7722 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
7723 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
7724 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
7725 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
7726 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
7728 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
7729 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
7730 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
7731 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
7732 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
7733 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
7734 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
7735 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
7736 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
7737 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
7738 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
7739 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
7740 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
7741 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
7742 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
7743 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
7744 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
7745 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
7746 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
7748 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
7749 end with SPE_BUILTIN_EVSUBFUSIAAW. */
7750 { 0, CODE_FOR_spe_evabs
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
7751 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
7752 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
7753 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
7754 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
7755 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
7756 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
7757 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
7758 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
7759 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
7760 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
7761 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
7762 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
7763 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
7764 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
7765 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
7766 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
7767 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
7768 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
7769 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
7770 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
7771 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
7772 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
7773 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
7774 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
7775 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
7776 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
7777 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
7779 /* Place-holder. Leave as last unary SPE builtin. */
7780 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
},
7782 { 0, CODE_FOR_absv2sf2
, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2
},
7783 { 0, CODE_FOR_nabsv2sf2
, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2
},
7784 { 0, CODE_FOR_negv2sf2
, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2
},
7785 { 0, CODE_FOR_sqrtv2sf2
, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2
},
7786 { 0, CODE_FOR_resv2sf2
, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2
}
7790 rs6000_expand_unop_builtin (enum insn_code icode
, tree exp
, rtx target
)
7793 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7794 rtx op0
= expand_normal (arg0
);
7795 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7796 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7798 if (icode
== CODE_FOR_nothing
)
7799 /* Builtin not supported on this processor. */
7802 /* If we got invalid arguments bail out before generating bad rtl. */
7803 if (arg0
== error_mark_node
)
7806 if (icode
== CODE_FOR_altivec_vspltisb
7807 || icode
== CODE_FOR_altivec_vspltish
7808 || icode
== CODE_FOR_altivec_vspltisw
7809 || icode
== CODE_FOR_spe_evsplatfi
7810 || icode
== CODE_FOR_spe_evsplati
)
7812 /* Only allow 5-bit *signed* literals. */
7813 if (GET_CODE (op0
) != CONST_INT
7814 || INTVAL (op0
) > 15
7815 || INTVAL (op0
) < -16)
7817 error ("argument 1 must be a 5-bit signed literal");
7823 || GET_MODE (target
) != tmode
7824 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7825 target
= gen_reg_rtx (tmode
);
7827 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7828 op0
= copy_to_mode_reg (mode0
, op0
);
7830 pat
= GEN_FCN (icode
) (target
, op0
);
7839 altivec_expand_abs_builtin (enum insn_code icode
, tree exp
, rtx target
)
7841 rtx pat
, scratch1
, scratch2
;
7842 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7843 rtx op0
= expand_normal (arg0
);
7844 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7845 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7847 /* If we have invalid arguments, bail out before generating bad rtl. */
7848 if (arg0
== error_mark_node
)
7852 || GET_MODE (target
) != tmode
7853 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7854 target
= gen_reg_rtx (tmode
);
7856 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7857 op0
= copy_to_mode_reg (mode0
, op0
);
7859 scratch1
= gen_reg_rtx (mode0
);
7860 scratch2
= gen_reg_rtx (mode0
);
7862 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
7871 rs6000_expand_binop_builtin (enum insn_code icode
, tree exp
, rtx target
)
7874 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7875 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7876 rtx op0
= expand_normal (arg0
);
7877 rtx op1
= expand_normal (arg1
);
7878 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7879 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7880 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7882 if (icode
== CODE_FOR_nothing
)
7883 /* Builtin not supported on this processor. */
7886 /* If we got invalid arguments bail out before generating bad rtl. */
7887 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7890 if (icode
== CODE_FOR_altivec_vcfux
7891 || icode
== CODE_FOR_altivec_vcfsx
7892 || icode
== CODE_FOR_altivec_vctsxs
7893 || icode
== CODE_FOR_altivec_vctuxs
7894 || icode
== CODE_FOR_altivec_vspltb
7895 || icode
== CODE_FOR_altivec_vsplth
7896 || icode
== CODE_FOR_altivec_vspltw
7897 || icode
== CODE_FOR_spe_evaddiw
7898 || icode
== CODE_FOR_spe_evldd
7899 || icode
== CODE_FOR_spe_evldh
7900 || icode
== CODE_FOR_spe_evldw
7901 || icode
== CODE_FOR_spe_evlhhesplat
7902 || icode
== CODE_FOR_spe_evlhhossplat
7903 || icode
== CODE_FOR_spe_evlhhousplat
7904 || icode
== CODE_FOR_spe_evlwhe
7905 || icode
== CODE_FOR_spe_evlwhos
7906 || icode
== CODE_FOR_spe_evlwhou
7907 || icode
== CODE_FOR_spe_evlwhsplat
7908 || icode
== CODE_FOR_spe_evlwwsplat
7909 || icode
== CODE_FOR_spe_evrlwi
7910 || icode
== CODE_FOR_spe_evslwi
7911 || icode
== CODE_FOR_spe_evsrwis
7912 || icode
== CODE_FOR_spe_evsubifw
7913 || icode
== CODE_FOR_spe_evsrwiu
)
7915 /* Only allow 5-bit unsigned literals. */
7917 if (TREE_CODE (arg1
) != INTEGER_CST
7918 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
7920 error ("argument 2 must be a 5-bit unsigned literal");
7926 || GET_MODE (target
) != tmode
7927 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7928 target
= gen_reg_rtx (tmode
);
7930 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7931 op0
= copy_to_mode_reg (mode0
, op0
);
7932 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7933 op1
= copy_to_mode_reg (mode1
, op1
);
7935 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
7944 altivec_expand_predicate_builtin (enum insn_code icode
, const char *opcode
,
7945 tree exp
, rtx target
)
7948 tree cr6_form
= CALL_EXPR_ARG (exp
, 0);
7949 tree arg0
= CALL_EXPR_ARG (exp
, 1);
7950 tree arg1
= CALL_EXPR_ARG (exp
, 2);
7951 rtx op0
= expand_normal (arg0
);
7952 rtx op1
= expand_normal (arg1
);
7953 enum machine_mode tmode
= SImode
;
7954 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7955 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7958 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
7960 error ("argument 1 of __builtin_altivec_predicate must be a constant");
7964 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
7966 gcc_assert (mode0
== mode1
);
7968 /* If we have invalid arguments, bail out before generating bad rtl. */
7969 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7973 || GET_MODE (target
) != tmode
7974 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7975 target
= gen_reg_rtx (tmode
);
7977 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7978 op0
= copy_to_mode_reg (mode0
, op0
);
7979 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7980 op1
= copy_to_mode_reg (mode1
, op1
);
7982 scratch
= gen_reg_rtx (mode0
);
7984 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
,
7985 gen_rtx_SYMBOL_REF (Pmode
, opcode
));
7990 /* The vec_any* and vec_all* predicates use the same opcodes for two
7991 different operations, but the bits in CR6 will be different
7992 depending on what information we want. So we have to play tricks
7993 with CR6 to get the right bits out.
7995 If you think this is disgusting, look at the specs for the
7996 AltiVec predicates. */
7998 switch (cr6_form_int
)
8001 emit_insn (gen_cr6_test_for_zero (target
));
8004 emit_insn (gen_cr6_test_for_zero_reverse (target
));
8007 emit_insn (gen_cr6_test_for_lt (target
));
8010 emit_insn (gen_cr6_test_for_lt_reverse (target
));
8013 error ("argument 1 of __builtin_altivec_predicate is out of range");
8021 paired_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
)
8024 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8025 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8026 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8027 enum machine_mode mode0
= Pmode
;
8028 enum machine_mode mode1
= Pmode
;
8029 rtx op0
= expand_normal (arg0
);
8030 rtx op1
= expand_normal (arg1
);
8032 if (icode
== CODE_FOR_nothing
)
8033 /* Builtin not supported on this processor. */
8036 /* If we got invalid arguments bail out before generating bad rtl. */
8037 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
8041 || GET_MODE (target
) != tmode
8042 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8043 target
= gen_reg_rtx (tmode
);
8045 op1
= copy_to_mode_reg (mode1
, op1
);
8047 if (op0
== const0_rtx
)
8049 addr
= gen_rtx_MEM (tmode
, op1
);
8053 op0
= copy_to_mode_reg (mode0
, op0
);
8054 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
8057 pat
= GEN_FCN (icode
) (target
, addr
);
8067 altivec_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
, bool blk
)
8070 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8071 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8072 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8073 enum machine_mode mode0
= Pmode
;
8074 enum machine_mode mode1
= Pmode
;
8075 rtx op0
= expand_normal (arg0
);
8076 rtx op1
= expand_normal (arg1
);
8078 if (icode
== CODE_FOR_nothing
)
8079 /* Builtin not supported on this processor. */
8082 /* If we got invalid arguments bail out before generating bad rtl. */
8083 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
8087 || GET_MODE (target
) != tmode
8088 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8089 target
= gen_reg_rtx (tmode
);
8091 op1
= copy_to_mode_reg (mode1
, op1
);
8093 if (op0
== const0_rtx
)
8095 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, op1
);
8099 op0
= copy_to_mode_reg (mode0
, op0
);
8100 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
8103 pat
= GEN_FCN (icode
) (target
, addr
);
8113 spe_expand_stv_builtin (enum insn_code icode
, tree exp
)
8115 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8116 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8117 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8118 rtx op0
= expand_normal (arg0
);
8119 rtx op1
= expand_normal (arg1
);
8120 rtx op2
= expand_normal (arg2
);
8122 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
8123 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
8124 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
8126 /* Invalid arguments. Bail before doing anything stoopid! */
8127 if (arg0
== error_mark_node
8128 || arg1
== error_mark_node
8129 || arg2
== error_mark_node
)
8132 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
8133 op0
= copy_to_mode_reg (mode2
, op0
);
8134 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
8135 op1
= copy_to_mode_reg (mode0
, op1
);
8136 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
8137 op2
= copy_to_mode_reg (mode1
, op2
);
8139 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
8146 paired_expand_stv_builtin (enum insn_code icode
, tree exp
)
8148 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8149 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8150 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8151 rtx op0
= expand_normal (arg0
);
8152 rtx op1
= expand_normal (arg1
);
8153 rtx op2
= expand_normal (arg2
);
8155 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8156 enum machine_mode mode1
= Pmode
;
8157 enum machine_mode mode2
= Pmode
;
8159 /* Invalid arguments. Bail before doing anything stoopid! */
8160 if (arg0
== error_mark_node
8161 || arg1
== error_mark_node
8162 || arg2
== error_mark_node
)
8165 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
8166 op0
= copy_to_mode_reg (tmode
, op0
);
8168 op2
= copy_to_mode_reg (mode2
, op2
);
8170 if (op1
== const0_rtx
)
8172 addr
= gen_rtx_MEM (tmode
, op2
);
8176 op1
= copy_to_mode_reg (mode1
, op1
);
8177 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
8180 pat
= GEN_FCN (icode
) (addr
, op0
);
8187 altivec_expand_stv_builtin (enum insn_code icode
, tree exp
)
8189 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8190 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8191 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8192 rtx op0
= expand_normal (arg0
);
8193 rtx op1
= expand_normal (arg1
);
8194 rtx op2
= expand_normal (arg2
);
8196 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8197 enum machine_mode mode1
= Pmode
;
8198 enum machine_mode mode2
= Pmode
;
8200 /* Invalid arguments. Bail before doing anything stoopid! */
8201 if (arg0
== error_mark_node
8202 || arg1
== error_mark_node
8203 || arg2
== error_mark_node
)
8206 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
8207 op0
= copy_to_mode_reg (tmode
, op0
);
8209 op2
= copy_to_mode_reg (mode2
, op2
);
8211 if (op1
== const0_rtx
)
8213 addr
= gen_rtx_MEM (tmode
, op2
);
8217 op1
= copy_to_mode_reg (mode1
, op1
);
8218 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
8221 pat
= GEN_FCN (icode
) (addr
, op0
);
8228 rs6000_expand_ternop_builtin (enum insn_code icode
, tree exp
, rtx target
)
8231 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8232 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8233 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8234 rtx op0
= expand_normal (arg0
);
8235 rtx op1
= expand_normal (arg1
);
8236 rtx op2
= expand_normal (arg2
);
8237 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8238 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8239 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8240 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
8242 if (icode
== CODE_FOR_nothing
)
8243 /* Builtin not supported on this processor. */
8246 /* If we got invalid arguments bail out before generating bad rtl. */
8247 if (arg0
== error_mark_node
8248 || arg1
== error_mark_node
8249 || arg2
== error_mark_node
)
8252 if (icode
== CODE_FOR_altivec_vsldoi_v4sf
8253 || icode
== CODE_FOR_altivec_vsldoi_v4si
8254 || icode
== CODE_FOR_altivec_vsldoi_v8hi
8255 || icode
== CODE_FOR_altivec_vsldoi_v16qi
)
8257 /* Only allow 4-bit unsigned literals. */
8259 if (TREE_CODE (arg2
) != INTEGER_CST
8260 || TREE_INT_CST_LOW (arg2
) & ~0xf)
8262 error ("argument 3 must be a 4-bit unsigned literal");
8268 || GET_MODE (target
) != tmode
8269 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8270 target
= gen_reg_rtx (tmode
);
8272 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8273 op0
= copy_to_mode_reg (mode0
, op0
);
8274 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
8275 op1
= copy_to_mode_reg (mode1
, op1
);
8276 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
8277 op2
= copy_to_mode_reg (mode2
, op2
);
8279 if (TARGET_PAIRED_FLOAT
&& icode
== CODE_FOR_selv2sf4
)
8280 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
, CONST0_RTX (SFmode
));
8282 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
8290 /* Expand the lvx builtins. */
8292 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
8294 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8295 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8297 enum machine_mode tmode
, mode0
;
8299 enum insn_code icode
;
8303 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
8304 icode
= CODE_FOR_altivec_lvx_v16qi
;
8306 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
8307 icode
= CODE_FOR_altivec_lvx_v8hi
;
8309 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
8310 icode
= CODE_FOR_altivec_lvx_v4si
;
8312 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
8313 icode
= CODE_FOR_altivec_lvx_v4sf
;
8322 arg0
= CALL_EXPR_ARG (exp
, 0);
8323 op0
= expand_normal (arg0
);
8324 tmode
= insn_data
[icode
].operand
[0].mode
;
8325 mode0
= insn_data
[icode
].operand
[1].mode
;
8328 || GET_MODE (target
) != tmode
8329 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8330 target
= gen_reg_rtx (tmode
);
8332 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8333 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
8335 pat
= GEN_FCN (icode
) (target
, op0
);
8342 /* Expand the stvx builtins. */
8344 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
8347 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8348 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8350 enum machine_mode mode0
, mode1
;
8352 enum insn_code icode
;
8356 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
8357 icode
= CODE_FOR_altivec_stvx_v16qi
;
8359 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
8360 icode
= CODE_FOR_altivec_stvx_v8hi
;
8362 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
8363 icode
= CODE_FOR_altivec_stvx_v4si
;
8365 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
8366 icode
= CODE_FOR_altivec_stvx_v4sf
;
8373 arg0
= CALL_EXPR_ARG (exp
, 0);
8374 arg1
= CALL_EXPR_ARG (exp
, 1);
8375 op0
= expand_normal (arg0
);
8376 op1
= expand_normal (arg1
);
8377 mode0
= insn_data
[icode
].operand
[0].mode
;
8378 mode1
= insn_data
[icode
].operand
[1].mode
;
8380 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8381 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
8382 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
8383 op1
= copy_to_mode_reg (mode1
, op1
);
8385 pat
= GEN_FCN (icode
) (op0
, op1
);
8393 /* Expand the dst builtins. */
8395 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
8398 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8399 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8400 tree arg0
, arg1
, arg2
;
8401 enum machine_mode mode0
, mode1
, mode2
;
8402 rtx pat
, op0
, op1
, op2
;
8403 const struct builtin_description
*d
;
8408 /* Handle DST variants. */
8410 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
8411 if (d
->code
== fcode
)
8413 arg0
= CALL_EXPR_ARG (exp
, 0);
8414 arg1
= CALL_EXPR_ARG (exp
, 1);
8415 arg2
= CALL_EXPR_ARG (exp
, 2);
8416 op0
= expand_normal (arg0
);
8417 op1
= expand_normal (arg1
);
8418 op2
= expand_normal (arg2
);
8419 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8420 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
8421 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
8423 /* Invalid arguments, bail out before generating bad rtl. */
8424 if (arg0
== error_mark_node
8425 || arg1
== error_mark_node
8426 || arg2
== error_mark_node
)
8431 if (TREE_CODE (arg2
) != INTEGER_CST
8432 || TREE_INT_CST_LOW (arg2
) & ~0x3)
8434 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
8438 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
8439 op0
= copy_to_mode_reg (Pmode
, op0
);
8440 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
8441 op1
= copy_to_mode_reg (mode1
, op1
);
8443 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
8453 /* Expand vec_init builtin. */
8455 altivec_expand_vec_init_builtin (tree type
, tree exp
, rtx target
)
8457 enum machine_mode tmode
= TYPE_MODE (type
);
8458 enum machine_mode inner_mode
= GET_MODE_INNER (tmode
);
8459 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
8460 rtvec v
= rtvec_alloc (n_elt
);
8462 gcc_assert (VECTOR_MODE_P (tmode
));
8463 gcc_assert (n_elt
== call_expr_nargs (exp
));
8465 for (i
= 0; i
< n_elt
; ++i
)
8467 rtx x
= expand_normal (CALL_EXPR_ARG (exp
, i
));
8468 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
8471 if (!target
|| !register_operand (target
, tmode
))
8472 target
= gen_reg_rtx (tmode
);
8474 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
8478 /* Return the integer constant in ARG. Constrain it to be in the range
8479 of the subparts of VEC_TYPE; issue an error if not. */
8482 get_element_number (tree vec_type
, tree arg
)
8484 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
8486 if (!host_integerp (arg
, 1)
8487 || (elt
= tree_low_cst (arg
, 1), elt
> max
))
8489 error ("selector must be an integer constant in the range 0..%wi", max
);
8496 /* Expand vec_set builtin. */
8498 altivec_expand_vec_set_builtin (tree exp
)
8500 enum machine_mode tmode
, mode1
;
8501 tree arg0
, arg1
, arg2
;
8505 arg0
= CALL_EXPR_ARG (exp
, 0);
8506 arg1
= CALL_EXPR_ARG (exp
, 1);
8507 arg2
= CALL_EXPR_ARG (exp
, 2);
8509 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
8510 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
8511 gcc_assert (VECTOR_MODE_P (tmode
));
8513 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, 0);
8514 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, 0);
8515 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
8517 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
8518 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
8520 op0
= force_reg (tmode
, op0
);
8521 op1
= force_reg (mode1
, op1
);
8523 rs6000_expand_vector_set (op0
, op1
, elt
);
8528 /* Expand vec_ext builtin. */
8530 altivec_expand_vec_ext_builtin (tree exp
, rtx target
)
8532 enum machine_mode tmode
, mode0
;
8537 arg0
= CALL_EXPR_ARG (exp
, 0);
8538 arg1
= CALL_EXPR_ARG (exp
, 1);
8540 op0
= expand_normal (arg0
);
8541 elt
= get_element_number (TREE_TYPE (arg0
), arg1
);
8543 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
8544 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
8545 gcc_assert (VECTOR_MODE_P (mode0
));
8547 op0
= force_reg (mode0
, op0
);
8549 if (optimize
|| !target
|| !register_operand (target
, tmode
))
8550 target
= gen_reg_rtx (tmode
);
8552 rs6000_expand_vector_extract (target
, op0
, elt
);
8557 /* Expand the builtin in EXP and store the result in TARGET. Store
8558 true in *EXPANDEDP if we found a builtin to expand. */
8560 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
8562 const struct builtin_description
*d
;
8563 const struct builtin_description_predicates
*dp
;
8565 enum insn_code icode
;
8566 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8569 enum machine_mode tmode
, mode0
;
8570 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8572 if (fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8573 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
8576 error ("unresolved overload for Altivec builtin %qF", fndecl
);
8580 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
8584 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
8588 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
8596 case ALTIVEC_BUILTIN_STVX
:
8597 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx
, exp
);
8598 case ALTIVEC_BUILTIN_STVEBX
:
8599 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, exp
);
8600 case ALTIVEC_BUILTIN_STVEHX
:
8601 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, exp
);
8602 case ALTIVEC_BUILTIN_STVEWX
:
8603 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, exp
);
8604 case ALTIVEC_BUILTIN_STVXL
:
8605 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, exp
);
8607 case ALTIVEC_BUILTIN_STVLX
:
8608 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx
, exp
);
8609 case ALTIVEC_BUILTIN_STVLXL
:
8610 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl
, exp
);
8611 case ALTIVEC_BUILTIN_STVRX
:
8612 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx
, exp
);
8613 case ALTIVEC_BUILTIN_STVRXL
:
8614 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl
, exp
);
8616 case ALTIVEC_BUILTIN_MFVSCR
:
8617 icode
= CODE_FOR_altivec_mfvscr
;
8618 tmode
= insn_data
[icode
].operand
[0].mode
;
8621 || GET_MODE (target
) != tmode
8622 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8623 target
= gen_reg_rtx (tmode
);
8625 pat
= GEN_FCN (icode
) (target
);
8631 case ALTIVEC_BUILTIN_MTVSCR
:
8632 icode
= CODE_FOR_altivec_mtvscr
;
8633 arg0
= CALL_EXPR_ARG (exp
, 0);
8634 op0
= expand_normal (arg0
);
8635 mode0
= insn_data
[icode
].operand
[0].mode
;
8637 /* If we got invalid arguments bail out before generating bad rtl. */
8638 if (arg0
== error_mark_node
)
8641 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8642 op0
= copy_to_mode_reg (mode0
, op0
);
8644 pat
= GEN_FCN (icode
) (op0
);
8649 case ALTIVEC_BUILTIN_DSSALL
:
8650 emit_insn (gen_altivec_dssall ());
8653 case ALTIVEC_BUILTIN_DSS
:
8654 icode
= CODE_FOR_altivec_dss
;
8655 arg0
= CALL_EXPR_ARG (exp
, 0);
8657 op0
= expand_normal (arg0
);
8658 mode0
= insn_data
[icode
].operand
[0].mode
;
8660 /* If we got invalid arguments bail out before generating bad rtl. */
8661 if (arg0
== error_mark_node
)
8664 if (TREE_CODE (arg0
) != INTEGER_CST
8665 || TREE_INT_CST_LOW (arg0
) & ~0x3)
8667 error ("argument to dss must be a 2-bit unsigned literal");
8671 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8672 op0
= copy_to_mode_reg (mode0
, op0
);
8674 emit_insn (gen_altivec_dss (op0
));
8677 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
8678 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
8679 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
8680 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
8681 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), exp
, target
);
8683 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
8684 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
8685 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
8686 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
8687 return altivec_expand_vec_set_builtin (exp
);
8689 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
8690 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
8691 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
8692 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
8693 return altivec_expand_vec_ext_builtin (exp
, target
);
8700 /* Expand abs* operations. */
8702 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
8703 if (d
->code
== fcode
)
8704 return altivec_expand_abs_builtin (d
->icode
, exp
, target
);
8706 /* Expand the AltiVec predicates. */
8707 dp
= bdesc_altivec_preds
;
8708 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
8709 if (dp
->code
== fcode
)
8710 return altivec_expand_predicate_builtin (dp
->icode
, dp
->opcode
,
8713 /* LV* are funky. We initialized them differently. */
8716 case ALTIVEC_BUILTIN_LVSL
:
8717 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
8718 exp
, target
, false);
8719 case ALTIVEC_BUILTIN_LVSR
:
8720 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
8721 exp
, target
, false);
8722 case ALTIVEC_BUILTIN_LVEBX
:
8723 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
8724 exp
, target
, false);
8725 case ALTIVEC_BUILTIN_LVEHX
:
8726 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
8727 exp
, target
, false);
8728 case ALTIVEC_BUILTIN_LVEWX
:
8729 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
8730 exp
, target
, false);
8731 case ALTIVEC_BUILTIN_LVXL
:
8732 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
8733 exp
, target
, false);
8734 case ALTIVEC_BUILTIN_LVX
:
8735 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx
,
8736 exp
, target
, false);
8737 case ALTIVEC_BUILTIN_LVLX
:
8738 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx
,
8740 case ALTIVEC_BUILTIN_LVLXL
:
8741 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl
,
8743 case ALTIVEC_BUILTIN_LVRX
:
8744 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx
,
8746 case ALTIVEC_BUILTIN_LVRXL
:
8747 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl
,
8758 /* Expand the builtin in EXP and store the result in TARGET. Store
8759 true in *EXPANDEDP if we found a builtin to expand. */
8761 paired_expand_builtin (tree exp
, rtx target
, bool * expandedp
)
8763 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8764 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8765 const struct builtin_description
*d
;
8772 case PAIRED_BUILTIN_STX
:
8773 return paired_expand_stv_builtin (CODE_FOR_paired_stx
, exp
);
8774 case PAIRED_BUILTIN_LX
:
8775 return paired_expand_lv_builtin (CODE_FOR_paired_lx
, exp
, target
);
8781 /* Expand the paired predicates. */
8782 d
= bdesc_paired_preds
;
8783 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); i
++, d
++)
8784 if (d
->code
== fcode
)
8785 return paired_expand_predicate_builtin (d
->icode
, exp
, target
);
8791 /* Binops that need to be initialized manually, but can be expanded
8792 automagically by rs6000_expand_binop_builtin. */
8793 static struct builtin_description bdesc_2arg_spe
[] =
8795 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
8796 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
8797 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
8798 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
8799 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
8800 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
8801 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
8802 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
8803 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
8804 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
8805 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
8806 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
8807 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
8808 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
8809 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
8810 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
8811 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
8812 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
8813 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
8814 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
8815 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
8816 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
8819 /* Expand the builtin in EXP and store the result in TARGET. Store
8820 true in *EXPANDEDP if we found a builtin to expand.
8822 This expands the SPE builtins that are not simple unary and binary
8825 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
8827 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8829 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8830 enum insn_code icode
;
8831 enum machine_mode tmode
, mode0
;
8833 struct builtin_description
*d
;
8838 /* Syntax check for a 5-bit unsigned immediate. */
8841 case SPE_BUILTIN_EVSTDD
:
8842 case SPE_BUILTIN_EVSTDH
:
8843 case SPE_BUILTIN_EVSTDW
:
8844 case SPE_BUILTIN_EVSTWHE
:
8845 case SPE_BUILTIN_EVSTWHO
:
8846 case SPE_BUILTIN_EVSTWWE
:
8847 case SPE_BUILTIN_EVSTWWO
:
8848 arg1
= CALL_EXPR_ARG (exp
, 2);
8849 if (TREE_CODE (arg1
) != INTEGER_CST
8850 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
8852 error ("argument 2 must be a 5-bit unsigned literal");
8860 /* The evsplat*i instructions are not quite generic. */
8863 case SPE_BUILTIN_EVSPLATFI
:
8864 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
8866 case SPE_BUILTIN_EVSPLATI
:
8867 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
8873 d
= (struct builtin_description
*) bdesc_2arg_spe
;
8874 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
8875 if (d
->code
== fcode
)
8876 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
8878 d
= (struct builtin_description
*) bdesc_spe_predicates
;
8879 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
8880 if (d
->code
== fcode
)
8881 return spe_expand_predicate_builtin (d
->icode
, exp
, target
);
8883 d
= (struct builtin_description
*) bdesc_spe_evsel
;
8884 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
8885 if (d
->code
== fcode
)
8886 return spe_expand_evsel_builtin (d
->icode
, exp
, target
);
8890 case SPE_BUILTIN_EVSTDDX
:
8891 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, exp
);
8892 case SPE_BUILTIN_EVSTDHX
:
8893 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, exp
);
8894 case SPE_BUILTIN_EVSTDWX
:
8895 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, exp
);
8896 case SPE_BUILTIN_EVSTWHEX
:
8897 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, exp
);
8898 case SPE_BUILTIN_EVSTWHOX
:
8899 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, exp
);
8900 case SPE_BUILTIN_EVSTWWEX
:
8901 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, exp
);
8902 case SPE_BUILTIN_EVSTWWOX
:
8903 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, exp
);
8904 case SPE_BUILTIN_EVSTDD
:
8905 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, exp
);
8906 case SPE_BUILTIN_EVSTDH
:
8907 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, exp
);
8908 case SPE_BUILTIN_EVSTDW
:
8909 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, exp
);
8910 case SPE_BUILTIN_EVSTWHE
:
8911 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, exp
);
8912 case SPE_BUILTIN_EVSTWHO
:
8913 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, exp
);
8914 case SPE_BUILTIN_EVSTWWE
:
8915 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, exp
);
8916 case SPE_BUILTIN_EVSTWWO
:
8917 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, exp
);
8918 case SPE_BUILTIN_MFSPEFSCR
:
8919 icode
= CODE_FOR_spe_mfspefscr
;
8920 tmode
= insn_data
[icode
].operand
[0].mode
;
8923 || GET_MODE (target
) != tmode
8924 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8925 target
= gen_reg_rtx (tmode
);
8927 pat
= GEN_FCN (icode
) (target
);
8932 case SPE_BUILTIN_MTSPEFSCR
:
8933 icode
= CODE_FOR_spe_mtspefscr
;
8934 arg0
= CALL_EXPR_ARG (exp
, 0);
8935 op0
= expand_normal (arg0
);
8936 mode0
= insn_data
[icode
].operand
[0].mode
;
8938 if (arg0
== error_mark_node
)
8941 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8942 op0
= copy_to_mode_reg (mode0
, op0
);
8944 pat
= GEN_FCN (icode
) (op0
);
8957 paired_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
8959 rtx pat
, scratch
, tmp
;
8960 tree form
= CALL_EXPR_ARG (exp
, 0);
8961 tree arg0
= CALL_EXPR_ARG (exp
, 1);
8962 tree arg1
= CALL_EXPR_ARG (exp
, 2);
8963 rtx op0
= expand_normal (arg0
);
8964 rtx op1
= expand_normal (arg1
);
8965 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8966 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8970 if (TREE_CODE (form
) != INTEGER_CST
)
8972 error ("argument 1 of __builtin_paired_predicate must be a constant");
8976 form_int
= TREE_INT_CST_LOW (form
);
8978 gcc_assert (mode0
== mode1
);
8980 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
8984 || GET_MODE (target
) != SImode
8985 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
8986 target
= gen_reg_rtx (SImode
);
8987 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8988 op0
= copy_to_mode_reg (mode0
, op0
);
8989 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
8990 op1
= copy_to_mode_reg (mode1
, op1
);
8992 scratch
= gen_reg_rtx (CCFPmode
);
8994 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
9016 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
9019 error ("argument 1 of __builtin_paired_predicate is out of range");
9023 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
9024 emit_move_insn (target
, tmp
);
9029 spe_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
9031 rtx pat
, scratch
, tmp
;
9032 tree form
= CALL_EXPR_ARG (exp
, 0);
9033 tree arg0
= CALL_EXPR_ARG (exp
, 1);
9034 tree arg1
= CALL_EXPR_ARG (exp
, 2);
9035 rtx op0
= expand_normal (arg0
);
9036 rtx op1
= expand_normal (arg1
);
9037 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
9038 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
9042 if (TREE_CODE (form
) != INTEGER_CST
)
9044 error ("argument 1 of __builtin_spe_predicate must be a constant");
9048 form_int
= TREE_INT_CST_LOW (form
);
9050 gcc_assert (mode0
== mode1
);
9052 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
9056 || GET_MODE (target
) != SImode
9057 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
9058 target
= gen_reg_rtx (SImode
);
9060 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
9061 op0
= copy_to_mode_reg (mode0
, op0
);
9062 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
9063 op1
= copy_to_mode_reg (mode1
, op1
);
9065 scratch
= gen_reg_rtx (CCmode
);
9067 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
9072 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
9073 _lower_. We use one compare, but look in different bits of the
9074 CR for each variant.
9076 There are 2 elements in each SPE simd type (upper/lower). The CR
9077 bits are set as follows:
9079 BIT0 | BIT 1 | BIT 2 | BIT 3
9080 U | L | (U | L) | (U & L)
9082 So, for an "all" relationship, BIT 3 would be set.
9083 For an "any" relationship, BIT 2 would be set. Etc.
9085 Following traditional nomenclature, these bits map to:
9087 BIT0 | BIT 1 | BIT 2 | BIT 3
9090 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
9095 /* All variant. OV bit. */
9097 /* We need to get to the OV bit, which is the ORDERED bit. We
9098 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
9099 that's ugly and will make validate_condition_mode die.
9100 So let's just use another pattern. */
9101 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
9103 /* Any variant. EQ bit. */
9107 /* Upper variant. LT bit. */
9111 /* Lower variant. GT bit. */
9116 error ("argument 1 of __builtin_spe_predicate is out of range");
9120 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
9121 emit_move_insn (target
, tmp
);
9126 /* The evsel builtins look like this:
9128 e = __builtin_spe_evsel_OP (a, b, c, d);
9132 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
9133 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
9137 spe_expand_evsel_builtin (enum insn_code icode
, tree exp
, rtx target
)
9140 tree arg0
= CALL_EXPR_ARG (exp
, 0);
9141 tree arg1
= CALL_EXPR_ARG (exp
, 1);
9142 tree arg2
= CALL_EXPR_ARG (exp
, 2);
9143 tree arg3
= CALL_EXPR_ARG (exp
, 3);
9144 rtx op0
= expand_normal (arg0
);
9145 rtx op1
= expand_normal (arg1
);
9146 rtx op2
= expand_normal (arg2
);
9147 rtx op3
= expand_normal (arg3
);
9148 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
9149 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
9151 gcc_assert (mode0
== mode1
);
9153 if (arg0
== error_mark_node
|| arg1
== error_mark_node
9154 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
9158 || GET_MODE (target
) != mode0
9159 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
9160 target
= gen_reg_rtx (mode0
);
9162 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
9163 op0
= copy_to_mode_reg (mode0
, op0
);
9164 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
9165 op1
= copy_to_mode_reg (mode0
, op1
);
9166 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
9167 op2
= copy_to_mode_reg (mode0
, op2
);
9168 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
9169 op3
= copy_to_mode_reg (mode0
, op3
);
9171 /* Generate the compare. */
9172 scratch
= gen_reg_rtx (CCmode
);
9173 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
9178 if (mode0
== V2SImode
)
9179 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
9181 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
9186 /* Expand an expression EXP that calls a built-in function,
9187 with result going to TARGET if that's convenient
9188 (and in mode MODE if that's convenient).
9189 SUBTARGET may be used as the target for computing one of EXP's operands.
9190 IGNORE is nonzero if the value is to be ignored. */
9193 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
9194 enum machine_mode mode ATTRIBUTE_UNUSED
,
9195 int ignore ATTRIBUTE_UNUSED
)
9197 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
9198 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
9199 const struct builtin_description
*d
;
9204 if (fcode
== RS6000_BUILTIN_RECIP
)
9205 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3
, exp
, target
);
9207 if (fcode
== RS6000_BUILTIN_RECIPF
)
9208 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3
, exp
, target
);
9210 if (fcode
== RS6000_BUILTIN_RSQRTF
)
9211 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2
, exp
, target
);
9213 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_LOAD
9214 || fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
9216 int icode
= (int) CODE_FOR_altivec_lvsr
;
9217 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
9218 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
9222 gcc_assert (TARGET_ALTIVEC
);
9224 arg
= CALL_EXPR_ARG (exp
, 0);
9225 gcc_assert (TREE_CODE (TREE_TYPE (arg
)) == POINTER_TYPE
);
9226 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
9227 addr
= memory_address (mode
, op
);
9228 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
9232 /* For the load case need to negate the address. */
9233 op
= gen_reg_rtx (GET_MODE (addr
));
9234 emit_insn (gen_rtx_SET (VOIDmode
, op
,
9235 gen_rtx_NEG (GET_MODE (addr
), addr
)));
9237 op
= gen_rtx_MEM (mode
, op
);
9240 || GET_MODE (target
) != tmode
9241 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
9242 target
= gen_reg_rtx (tmode
);
9244 /*pat = gen_altivec_lvsr (target, op);*/
9245 pat
= GEN_FCN (icode
) (target
, op
);
9253 /* FIXME: There's got to be a nicer way to handle this case than
9254 constructing a new CALL_EXPR. */
9255 if (fcode
== ALTIVEC_BUILTIN_VCFUX
9256 || fcode
== ALTIVEC_BUILTIN_VCFSX
9257 || fcode
== ALTIVEC_BUILTIN_VCTUXS
9258 || fcode
== ALTIVEC_BUILTIN_VCTSXS
)
9260 if (call_expr_nargs (exp
) == 1)
9261 exp
= build_call_nary (TREE_TYPE (exp
), CALL_EXPR_FN (exp
),
9262 2, CALL_EXPR_ARG (exp
, 0), integer_zero_node
);
9267 ret
= altivec_expand_builtin (exp
, target
, &success
);
9274 ret
= spe_expand_builtin (exp
, target
, &success
);
9279 if (TARGET_PAIRED_FLOAT
)
9281 ret
= paired_expand_builtin (exp
, target
, &success
);
9287 gcc_assert (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
);
9289 /* Handle simple unary operations. */
9290 d
= (struct builtin_description
*) bdesc_1arg
;
9291 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
9292 if (d
->code
== fcode
)
9293 return rs6000_expand_unop_builtin (d
->icode
, exp
, target
);
9295 /* Handle simple binary operations. */
9296 d
= (struct builtin_description
*) bdesc_2arg
;
9297 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
9298 if (d
->code
== fcode
)
9299 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
9301 /* Handle simple ternary operations. */
9303 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
9304 if (d
->code
== fcode
)
9305 return rs6000_expand_ternop_builtin (d
->icode
, exp
, target
);
9311 build_opaque_vector_type (tree node
, int nunits
)
9313 node
= copy_node (node
);
9314 TYPE_MAIN_VARIANT (node
) = node
;
9315 TYPE_CANONICAL (node
) = node
;
9316 return build_vector_type (node
, nunits
);
9320 rs6000_init_builtins (void)
9322 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
9323 V2SF_type_node
= build_vector_type (float_type_node
, 2);
9324 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
9325 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
9326 V4SF_type_node
= build_vector_type (float_type_node
, 4);
9327 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
9328 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
9330 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
9331 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
9332 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
9334 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
9335 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
9336 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
9337 opaque_V4SI_type_node
= copy_node (V4SI_type_node
);
9339 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
9340 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
9341 'vector unsigned short'. */
9343 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
9344 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
9345 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
9346 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
9348 long_integer_type_internal_node
= long_integer_type_node
;
9349 long_unsigned_type_internal_node
= long_unsigned_type_node
;
9350 intQI_type_internal_node
= intQI_type_node
;
9351 uintQI_type_internal_node
= unsigned_intQI_type_node
;
9352 intHI_type_internal_node
= intHI_type_node
;
9353 uintHI_type_internal_node
= unsigned_intHI_type_node
;
9354 intSI_type_internal_node
= intSI_type_node
;
9355 uintSI_type_internal_node
= unsigned_intSI_type_node
;
9356 float_type_internal_node
= float_type_node
;
9357 void_type_internal_node
= void_type_node
;
9359 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9360 get_identifier ("__bool char"),
9361 bool_char_type_node
));
9362 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9363 get_identifier ("__bool short"),
9364 bool_short_type_node
));
9365 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9366 get_identifier ("__bool int"),
9367 bool_int_type_node
));
9368 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9369 get_identifier ("__pixel"),
9372 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
9373 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
9374 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
9375 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
9377 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9378 get_identifier ("__vector unsigned char"),
9379 unsigned_V16QI_type_node
));
9380 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9381 get_identifier ("__vector signed char"),
9383 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9384 get_identifier ("__vector __bool char"),
9385 bool_V16QI_type_node
));
9387 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9388 get_identifier ("__vector unsigned short"),
9389 unsigned_V8HI_type_node
));
9390 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9391 get_identifier ("__vector signed short"),
9393 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9394 get_identifier ("__vector __bool short"),
9395 bool_V8HI_type_node
));
9397 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9398 get_identifier ("__vector unsigned int"),
9399 unsigned_V4SI_type_node
));
9400 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9401 get_identifier ("__vector signed int"),
9403 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9404 get_identifier ("__vector __bool int"),
9405 bool_V4SI_type_node
));
9407 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9408 get_identifier ("__vector float"),
9410 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9411 get_identifier ("__vector __pixel"),
9412 pixel_V8HI_type_node
));
9414 if (TARGET_PAIRED_FLOAT
)
9415 paired_init_builtins ();
9417 spe_init_builtins ();
9419 altivec_init_builtins ();
9420 if (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
)
9421 rs6000_common_init_builtins ();
9422 if (TARGET_PPC_GFXOPT
)
9424 tree ftype
= build_function_type_list (float_type_node
,
9428 def_builtin (MASK_PPC_GFXOPT
, "__builtin_recipdivf", ftype
,
9429 RS6000_BUILTIN_RECIPF
);
9431 ftype
= build_function_type_list (float_type_node
,
9434 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrtf", ftype
,
9435 RS6000_BUILTIN_RSQRTF
);
9439 tree ftype
= build_function_type_list (double_type_node
,
9443 def_builtin (MASK_POPCNTB
, "__builtin_recipdiv", ftype
,
9444 RS6000_BUILTIN_RECIP
);
9449 /* AIX libm provides clog as __clog. */
9450 if (built_in_decls
[BUILT_IN_CLOG
])
9451 set_user_assembler_name (built_in_decls
[BUILT_IN_CLOG
], "__clog");
9454 #ifdef SUBTARGET_INIT_BUILTINS
9455 SUBTARGET_INIT_BUILTINS
;
9459 /* Search through a set of builtins and enable the mask bits.
9460 DESC is an array of builtins.
9461 SIZE is the total number of builtins.
9462 START is the builtin enum at which to start.
9463 END is the builtin enum at which to end. */
9465 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
9466 enum rs6000_builtins start
,
9467 enum rs6000_builtins end
)
9471 for (i
= 0; i
< size
; ++i
)
9472 if (desc
[i
].code
== start
)
9478 for (; i
< size
; ++i
)
9480 /* Flip all the bits on. */
9481 desc
[i
].mask
= target_flags
;
9482 if (desc
[i
].code
== end
)
9488 spe_init_builtins (void)
9490 tree endlink
= void_list_node
;
9491 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
9492 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
9493 struct builtin_description
*d
;
9496 tree v2si_ftype_4_v2si
9497 = build_function_type
9498 (opaque_V2SI_type_node
,
9499 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9500 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9501 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9502 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9505 tree v2sf_ftype_4_v2sf
9506 = build_function_type
9507 (opaque_V2SF_type_node
,
9508 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9509 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9510 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9511 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9514 tree int_ftype_int_v2si_v2si
9515 = build_function_type
9517 tree_cons (NULL_TREE
, integer_type_node
,
9518 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9519 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9522 tree int_ftype_int_v2sf_v2sf
9523 = build_function_type
9525 tree_cons (NULL_TREE
, integer_type_node
,
9526 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9527 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9530 tree void_ftype_v2si_puint_int
9531 = build_function_type (void_type_node
,
9532 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9533 tree_cons (NULL_TREE
, puint_type_node
,
9534 tree_cons (NULL_TREE
,
9538 tree void_ftype_v2si_puint_char
9539 = build_function_type (void_type_node
,
9540 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9541 tree_cons (NULL_TREE
, puint_type_node
,
9542 tree_cons (NULL_TREE
,
9546 tree void_ftype_v2si_pv2si_int
9547 = build_function_type (void_type_node
,
9548 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9549 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
9550 tree_cons (NULL_TREE
,
9554 tree void_ftype_v2si_pv2si_char
9555 = build_function_type (void_type_node
,
9556 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9557 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
9558 tree_cons (NULL_TREE
,
9563 = build_function_type (void_type_node
,
9564 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
9567 = build_function_type (integer_type_node
, endlink
);
9569 tree v2si_ftype_pv2si_int
9570 = build_function_type (opaque_V2SI_type_node
,
9571 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
9572 tree_cons (NULL_TREE
, integer_type_node
,
9575 tree v2si_ftype_puint_int
9576 = build_function_type (opaque_V2SI_type_node
,
9577 tree_cons (NULL_TREE
, puint_type_node
,
9578 tree_cons (NULL_TREE
, integer_type_node
,
9581 tree v2si_ftype_pushort_int
9582 = build_function_type (opaque_V2SI_type_node
,
9583 tree_cons (NULL_TREE
, pushort_type_node
,
9584 tree_cons (NULL_TREE
, integer_type_node
,
9587 tree v2si_ftype_signed_char
9588 = build_function_type (opaque_V2SI_type_node
,
9589 tree_cons (NULL_TREE
, signed_char_type_node
,
9592 /* The initialization of the simple binary and unary builtins is
9593 done in rs6000_common_init_builtins, but we have to enable the
9594 mask bits here manually because we have run out of `target_flags'
9595 bits. We really need to redesign this mask business. */
9597 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
9598 ARRAY_SIZE (bdesc_2arg
),
9601 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
9602 ARRAY_SIZE (bdesc_1arg
),
9604 SPE_BUILTIN_EVSUBFUSIAAW
);
9605 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
9606 ARRAY_SIZE (bdesc_spe_predicates
),
9607 SPE_BUILTIN_EVCMPEQ
,
9608 SPE_BUILTIN_EVFSTSTLT
);
9609 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
9610 ARRAY_SIZE (bdesc_spe_evsel
),
9611 SPE_BUILTIN_EVSEL_CMPGTS
,
9612 SPE_BUILTIN_EVSEL_FSTSTEQ
);
9614 (*lang_hooks
.decls
.pushdecl
)
9615 (build_decl (TYPE_DECL
, get_identifier ("__ev64_opaque__"),
9616 opaque_V2SI_type_node
));
9618 /* Initialize irregular SPE builtins. */
9620 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
9621 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
9622 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
9623 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
9624 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
9625 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
9626 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
9627 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
9628 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
9629 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
9630 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
9631 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
9632 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
9633 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
9634 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
9635 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
9636 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
9637 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
9640 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
9641 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
9642 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
9643 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
9644 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
9645 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
9646 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
9647 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
9648 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
9649 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
9650 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
9651 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
9652 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
9653 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
9654 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
9655 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
9656 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
9657 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
9658 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
9659 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
9660 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
9661 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
9664 d
= (struct builtin_description
*) bdesc_spe_predicates
;
9665 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
9669 switch (insn_data
[d
->icode
].operand
[1].mode
)
9672 type
= int_ftype_int_v2si_v2si
;
9675 type
= int_ftype_int_v2sf_v2sf
;
9681 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9684 /* Evsel predicates. */
9685 d
= (struct builtin_description
*) bdesc_spe_evsel
;
9686 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
9690 switch (insn_data
[d
->icode
].operand
[1].mode
)
9693 type
= v2si_ftype_4_v2si
;
9696 type
= v2sf_ftype_4_v2sf
;
9702 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9707 paired_init_builtins (void)
9709 const struct builtin_description
*d
;
9711 tree endlink
= void_list_node
;
9713 tree int_ftype_int_v2sf_v2sf
9714 = build_function_type
9716 tree_cons (NULL_TREE
, integer_type_node
,
9717 tree_cons (NULL_TREE
, V2SF_type_node
,
9718 tree_cons (NULL_TREE
, V2SF_type_node
,
9720 tree pcfloat_type_node
=
9721 build_pointer_type (build_qualified_type
9722 (float_type_node
, TYPE_QUAL_CONST
));
9724 tree v2sf_ftype_long_pcfloat
= build_function_type_list (V2SF_type_node
,
9725 long_integer_type_node
,
9728 tree void_ftype_v2sf_long_pcfloat
=
9729 build_function_type_list (void_type_node
,
9731 long_integer_type_node
,
9736 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat
,
9740 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat
,
9741 PAIRED_BUILTIN_STX
);
9744 d
= bdesc_paired_preds
;
9745 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); ++i
, d
++)
9749 switch (insn_data
[d
->icode
].operand
[1].mode
)
9752 type
= int_ftype_int_v2sf_v2sf
;
9758 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9763 altivec_init_builtins (void)
9765 const struct builtin_description
*d
;
9766 const struct builtin_description_predicates
*dp
;
9770 tree pfloat_type_node
= build_pointer_type (float_type_node
);
9771 tree pint_type_node
= build_pointer_type (integer_type_node
);
9772 tree pshort_type_node
= build_pointer_type (short_integer_type_node
);
9773 tree pchar_type_node
= build_pointer_type (char_type_node
);
9775 tree pvoid_type_node
= build_pointer_type (void_type_node
);
9777 tree pcfloat_type_node
= build_pointer_type (build_qualified_type (float_type_node
, TYPE_QUAL_CONST
));
9778 tree pcint_type_node
= build_pointer_type (build_qualified_type (integer_type_node
, TYPE_QUAL_CONST
));
9779 tree pcshort_type_node
= build_pointer_type (build_qualified_type (short_integer_type_node
, TYPE_QUAL_CONST
));
9780 tree pcchar_type_node
= build_pointer_type (build_qualified_type (char_type_node
, TYPE_QUAL_CONST
));
9782 tree pcvoid_type_node
= build_pointer_type (build_qualified_type (void_type_node
, TYPE_QUAL_CONST
));
9784 tree int_ftype_opaque
9785 = build_function_type_list (integer_type_node
,
9786 opaque_V4SI_type_node
, NULL_TREE
);
9787 tree opaque_ftype_opaque
9788 = build_function_type (integer_type_node
,
9790 tree opaque_ftype_opaque_int
9791 = build_function_type_list (opaque_V4SI_type_node
,
9792 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
9793 tree opaque_ftype_opaque_opaque_int
9794 = build_function_type_list (opaque_V4SI_type_node
,
9795 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
9796 integer_type_node
, NULL_TREE
);
9797 tree int_ftype_int_opaque_opaque
9798 = build_function_type_list (integer_type_node
,
9799 integer_type_node
, opaque_V4SI_type_node
,
9800 opaque_V4SI_type_node
, NULL_TREE
);
9801 tree int_ftype_int_v4si_v4si
9802 = build_function_type_list (integer_type_node
,
9803 integer_type_node
, V4SI_type_node
,
9804 V4SI_type_node
, NULL_TREE
);
9805 tree v4sf_ftype_pcfloat
9806 = build_function_type_list (V4SF_type_node
, pcfloat_type_node
, NULL_TREE
);
9807 tree void_ftype_pfloat_v4sf
9808 = build_function_type_list (void_type_node
,
9809 pfloat_type_node
, V4SF_type_node
, NULL_TREE
);
9810 tree v4si_ftype_pcint
9811 = build_function_type_list (V4SI_type_node
, pcint_type_node
, NULL_TREE
);
9812 tree void_ftype_pint_v4si
9813 = build_function_type_list (void_type_node
,
9814 pint_type_node
, V4SI_type_node
, NULL_TREE
);
9815 tree v8hi_ftype_pcshort
9816 = build_function_type_list (V8HI_type_node
, pcshort_type_node
, NULL_TREE
);
9817 tree void_ftype_pshort_v8hi
9818 = build_function_type_list (void_type_node
,
9819 pshort_type_node
, V8HI_type_node
, NULL_TREE
);
9820 tree v16qi_ftype_pcchar
9821 = build_function_type_list (V16QI_type_node
, pcchar_type_node
, NULL_TREE
);
9822 tree void_ftype_pchar_v16qi
9823 = build_function_type_list (void_type_node
,
9824 pchar_type_node
, V16QI_type_node
, NULL_TREE
);
9825 tree void_ftype_v4si
9826 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
9827 tree v8hi_ftype_void
9828 = build_function_type (V8HI_type_node
, void_list_node
);
9829 tree void_ftype_void
9830 = build_function_type (void_type_node
, void_list_node
);
9832 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
9834 tree opaque_ftype_long_pcvoid
9835 = build_function_type_list (opaque_V4SI_type_node
,
9836 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9837 tree v16qi_ftype_long_pcvoid
9838 = build_function_type_list (V16QI_type_node
,
9839 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9840 tree v8hi_ftype_long_pcvoid
9841 = build_function_type_list (V8HI_type_node
,
9842 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9843 tree v4si_ftype_long_pcvoid
9844 = build_function_type_list (V4SI_type_node
,
9845 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9847 tree void_ftype_opaque_long_pvoid
9848 = build_function_type_list (void_type_node
,
9849 opaque_V4SI_type_node
, long_integer_type_node
,
9850 pvoid_type_node
, NULL_TREE
);
9851 tree void_ftype_v4si_long_pvoid
9852 = build_function_type_list (void_type_node
,
9853 V4SI_type_node
, long_integer_type_node
,
9854 pvoid_type_node
, NULL_TREE
);
9855 tree void_ftype_v16qi_long_pvoid
9856 = build_function_type_list (void_type_node
,
9857 V16QI_type_node
, long_integer_type_node
,
9858 pvoid_type_node
, NULL_TREE
);
9859 tree void_ftype_v8hi_long_pvoid
9860 = build_function_type_list (void_type_node
,
9861 V8HI_type_node
, long_integer_type_node
,
9862 pvoid_type_node
, NULL_TREE
);
9863 tree int_ftype_int_v8hi_v8hi
9864 = build_function_type_list (integer_type_node
,
9865 integer_type_node
, V8HI_type_node
,
9866 V8HI_type_node
, NULL_TREE
);
9867 tree int_ftype_int_v16qi_v16qi
9868 = build_function_type_list (integer_type_node
,
9869 integer_type_node
, V16QI_type_node
,
9870 V16QI_type_node
, NULL_TREE
);
9871 tree int_ftype_int_v4sf_v4sf
9872 = build_function_type_list (integer_type_node
,
9873 integer_type_node
, V4SF_type_node
,
9874 V4SF_type_node
, NULL_TREE
);
9875 tree v4si_ftype_v4si
9876 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
9877 tree v8hi_ftype_v8hi
9878 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
9879 tree v16qi_ftype_v16qi
9880 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
9881 tree v4sf_ftype_v4sf
9882 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
9883 tree void_ftype_pcvoid_int_int
9884 = build_function_type_list (void_type_node
,
9885 pcvoid_type_node
, integer_type_node
,
9886 integer_type_node
, NULL_TREE
);
9888 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat
,
9889 ALTIVEC_BUILTIN_LD_INTERNAL_4sf
);
9890 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf
,
9891 ALTIVEC_BUILTIN_ST_INTERNAL_4sf
);
9892 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint
,
9893 ALTIVEC_BUILTIN_LD_INTERNAL_4si
);
9894 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si
,
9895 ALTIVEC_BUILTIN_ST_INTERNAL_4si
);
9896 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort
,
9897 ALTIVEC_BUILTIN_LD_INTERNAL_8hi
);
9898 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi
,
9899 ALTIVEC_BUILTIN_ST_INTERNAL_8hi
);
9900 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar
,
9901 ALTIVEC_BUILTIN_LD_INTERNAL_16qi
);
9902 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi
,
9903 ALTIVEC_BUILTIN_ST_INTERNAL_16qi
);
9904 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
9905 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
9906 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
9907 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
9908 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
9909 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
9910 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
9911 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
9912 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
9913 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
9914 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
9915 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
9916 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
9917 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
9918 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
9919 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
9920 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
9921 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
9922 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
9923 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
9924 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
9925 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
9926 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
9927 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
9928 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
9929 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
9930 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
9931 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
9932 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
9933 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
9935 if (rs6000_cpu
== PROCESSOR_CELL
)
9937 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLX
);
9938 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLXL
);
9939 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRX
);
9940 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRXL
);
9942 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLX
);
9943 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLXL
);
9944 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRX
);
9945 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRXL
);
9947 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLX
);
9948 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLXL
);
9949 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRX
);
9950 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRXL
);
9952 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLX
);
9953 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLXL
);
9954 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRX
);
9955 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRXL
);
9957 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
9958 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splats", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_SPLATS
);
9959 def_builtin (MASK_ALTIVEC
, "__builtin_vec_promote", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_PROMOTE
);
9961 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
9962 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
9963 def_builtin (MASK_ALTIVEC
, "__builtin_vec_extract", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_EXTRACT
);
9964 def_builtin (MASK_ALTIVEC
, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_INSERT
);
9965 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
9966 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
9967 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
9968 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
9969 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
9970 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
9971 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
9972 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
9974 /* Add the DST variants. */
9976 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
9977 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
9979 /* Initialize the predicates. */
9980 dp
= bdesc_altivec_preds
;
9981 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
9983 enum machine_mode mode1
;
9985 bool is_overloaded
= dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9986 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
9991 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
9996 type
= int_ftype_int_opaque_opaque
;
9999 type
= int_ftype_int_v4si_v4si
;
10002 type
= int_ftype_int_v8hi_v8hi
;
10005 type
= int_ftype_int_v16qi_v16qi
;
10008 type
= int_ftype_int_v4sf_v4sf
;
10011 gcc_unreachable ();
10014 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
10017 /* Initialize the abs* operators. */
10019 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
10021 enum machine_mode mode0
;
10024 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10029 type
= v4si_ftype_v4si
;
10032 type
= v8hi_ftype_v8hi
;
10035 type
= v16qi_ftype_v16qi
;
10038 type
= v4sf_ftype_v4sf
;
10041 gcc_unreachable ();
10044 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10047 if (TARGET_ALTIVEC
)
10051 /* Initialize target builtin that implements
10052 targetm.vectorize.builtin_mask_for_load. */
10054 decl
= add_builtin_function ("__builtin_altivec_mask_for_load",
10055 v16qi_ftype_long_pcvoid
,
10056 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
10057 BUILT_IN_MD
, NULL
, NULL_TREE
);
10058 TREE_READONLY (decl
) = 1;
10059 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
10060 altivec_builtin_mask_for_load
= decl
;
10063 /* Access to the vec_init patterns. */
10064 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
10065 integer_type_node
, integer_type_node
,
10066 integer_type_node
, NULL_TREE
);
10067 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4si", ftype
,
10068 ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
10070 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
10071 short_integer_type_node
,
10072 short_integer_type_node
,
10073 short_integer_type_node
,
10074 short_integer_type_node
,
10075 short_integer_type_node
,
10076 short_integer_type_node
,
10077 short_integer_type_node
, NULL_TREE
);
10078 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v8hi", ftype
,
10079 ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
10081 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
10082 char_type_node
, char_type_node
,
10083 char_type_node
, char_type_node
,
10084 char_type_node
, char_type_node
,
10085 char_type_node
, char_type_node
,
10086 char_type_node
, char_type_node
,
10087 char_type_node
, char_type_node
,
10088 char_type_node
, char_type_node
,
10089 char_type_node
, NULL_TREE
);
10090 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v16qi", ftype
,
10091 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
10093 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
10094 float_type_node
, float_type_node
,
10095 float_type_node
, NULL_TREE
);
10096 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4sf", ftype
,
10097 ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
10099 /* Access to the vec_set patterns. */
10100 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
10102 integer_type_node
, NULL_TREE
);
10103 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4si", ftype
,
10104 ALTIVEC_BUILTIN_VEC_SET_V4SI
);
10106 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
10108 integer_type_node
, NULL_TREE
);
10109 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v8hi", ftype
,
10110 ALTIVEC_BUILTIN_VEC_SET_V8HI
);
10112 ftype
= build_function_type_list (V8HI_type_node
, V16QI_type_node
,
10114 integer_type_node
, NULL_TREE
);
10115 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v16qi", ftype
,
10116 ALTIVEC_BUILTIN_VEC_SET_V16QI
);
10118 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
10120 integer_type_node
, NULL_TREE
);
10121 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4sf", ftype
,
10122 ALTIVEC_BUILTIN_VEC_SET_V4SF
);
10124 /* Access to the vec_extract patterns. */
10125 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
10126 integer_type_node
, NULL_TREE
);
10127 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4si", ftype
,
10128 ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
10130 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
10131 integer_type_node
, NULL_TREE
);
10132 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v8hi", ftype
,
10133 ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
10135 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
10136 integer_type_node
, NULL_TREE
);
10137 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v16qi", ftype
,
10138 ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
10140 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
10141 integer_type_node
, NULL_TREE
);
10142 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4sf", ftype
,
10143 ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
10147 rs6000_common_init_builtins (void)
10149 const struct builtin_description
*d
;
10152 tree v2sf_ftype_v2sf_v2sf_v2sf
10153 = build_function_type_list (V2SF_type_node
,
10154 V2SF_type_node
, V2SF_type_node
,
10155 V2SF_type_node
, NULL_TREE
);
10157 tree v4sf_ftype_v4sf_v4sf_v16qi
10158 = build_function_type_list (V4SF_type_node
,
10159 V4SF_type_node
, V4SF_type_node
,
10160 V16QI_type_node
, NULL_TREE
);
10161 tree v4si_ftype_v4si_v4si_v16qi
10162 = build_function_type_list (V4SI_type_node
,
10163 V4SI_type_node
, V4SI_type_node
,
10164 V16QI_type_node
, NULL_TREE
);
10165 tree v8hi_ftype_v8hi_v8hi_v16qi
10166 = build_function_type_list (V8HI_type_node
,
10167 V8HI_type_node
, V8HI_type_node
,
10168 V16QI_type_node
, NULL_TREE
);
10169 tree v16qi_ftype_v16qi_v16qi_v16qi
10170 = build_function_type_list (V16QI_type_node
,
10171 V16QI_type_node
, V16QI_type_node
,
10172 V16QI_type_node
, NULL_TREE
);
10173 tree v4si_ftype_int
10174 = build_function_type_list (V4SI_type_node
, integer_type_node
, NULL_TREE
);
10175 tree v8hi_ftype_int
10176 = build_function_type_list (V8HI_type_node
, integer_type_node
, NULL_TREE
);
10177 tree v16qi_ftype_int
10178 = build_function_type_list (V16QI_type_node
, integer_type_node
, NULL_TREE
);
10179 tree v8hi_ftype_v16qi
10180 = build_function_type_list (V8HI_type_node
, V16QI_type_node
, NULL_TREE
);
10181 tree v4sf_ftype_v4sf
10182 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10184 tree v2si_ftype_v2si_v2si
10185 = build_function_type_list (opaque_V2SI_type_node
,
10186 opaque_V2SI_type_node
,
10187 opaque_V2SI_type_node
, NULL_TREE
);
10189 tree v2sf_ftype_v2sf_v2sf_spe
10190 = build_function_type_list (opaque_V2SF_type_node
,
10191 opaque_V2SF_type_node
,
10192 opaque_V2SF_type_node
, NULL_TREE
);
10194 tree v2sf_ftype_v2sf_v2sf
10195 = build_function_type_list (V2SF_type_node
,
10197 V2SF_type_node
, NULL_TREE
);
10200 tree v2si_ftype_int_int
10201 = build_function_type_list (opaque_V2SI_type_node
,
10202 integer_type_node
, integer_type_node
,
10205 tree opaque_ftype_opaque
10206 = build_function_type_list (opaque_V4SI_type_node
,
10207 opaque_V4SI_type_node
, NULL_TREE
);
10209 tree v2si_ftype_v2si
10210 = build_function_type_list (opaque_V2SI_type_node
,
10211 opaque_V2SI_type_node
, NULL_TREE
);
10213 tree v2sf_ftype_v2sf_spe
10214 = build_function_type_list (opaque_V2SF_type_node
,
10215 opaque_V2SF_type_node
, NULL_TREE
);
10217 tree v2sf_ftype_v2sf
10218 = build_function_type_list (V2SF_type_node
,
10219 V2SF_type_node
, NULL_TREE
);
10221 tree v2sf_ftype_v2si
10222 = build_function_type_list (opaque_V2SF_type_node
,
10223 opaque_V2SI_type_node
, NULL_TREE
);
10225 tree v2si_ftype_v2sf
10226 = build_function_type_list (opaque_V2SI_type_node
,
10227 opaque_V2SF_type_node
, NULL_TREE
);
10229 tree v2si_ftype_v2si_char
10230 = build_function_type_list (opaque_V2SI_type_node
,
10231 opaque_V2SI_type_node
,
10232 char_type_node
, NULL_TREE
);
10234 tree v2si_ftype_int_char
10235 = build_function_type_list (opaque_V2SI_type_node
,
10236 integer_type_node
, char_type_node
, NULL_TREE
);
10238 tree v2si_ftype_char
10239 = build_function_type_list (opaque_V2SI_type_node
,
10240 char_type_node
, NULL_TREE
);
10242 tree int_ftype_int_int
10243 = build_function_type_list (integer_type_node
,
10244 integer_type_node
, integer_type_node
,
10247 tree opaque_ftype_opaque_opaque
10248 = build_function_type_list (opaque_V4SI_type_node
,
10249 opaque_V4SI_type_node
, opaque_V4SI_type_node
, NULL_TREE
);
10250 tree v4si_ftype_v4si_v4si
10251 = build_function_type_list (V4SI_type_node
,
10252 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
10253 tree v4sf_ftype_v4si_int
10254 = build_function_type_list (V4SF_type_node
,
10255 V4SI_type_node
, integer_type_node
, NULL_TREE
);
10256 tree v4si_ftype_v4sf_int
10257 = build_function_type_list (V4SI_type_node
,
10258 V4SF_type_node
, integer_type_node
, NULL_TREE
);
10259 tree v4si_ftype_v4si_int
10260 = build_function_type_list (V4SI_type_node
,
10261 V4SI_type_node
, integer_type_node
, NULL_TREE
);
10262 tree v8hi_ftype_v8hi_int
10263 = build_function_type_list (V8HI_type_node
,
10264 V8HI_type_node
, integer_type_node
, NULL_TREE
);
10265 tree v16qi_ftype_v16qi_int
10266 = build_function_type_list (V16QI_type_node
,
10267 V16QI_type_node
, integer_type_node
, NULL_TREE
);
10268 tree v16qi_ftype_v16qi_v16qi_int
10269 = build_function_type_list (V16QI_type_node
,
10270 V16QI_type_node
, V16QI_type_node
,
10271 integer_type_node
, NULL_TREE
);
10272 tree v8hi_ftype_v8hi_v8hi_int
10273 = build_function_type_list (V8HI_type_node
,
10274 V8HI_type_node
, V8HI_type_node
,
10275 integer_type_node
, NULL_TREE
);
10276 tree v4si_ftype_v4si_v4si_int
10277 = build_function_type_list (V4SI_type_node
,
10278 V4SI_type_node
, V4SI_type_node
,
10279 integer_type_node
, NULL_TREE
);
10280 tree v4sf_ftype_v4sf_v4sf_int
10281 = build_function_type_list (V4SF_type_node
,
10282 V4SF_type_node
, V4SF_type_node
,
10283 integer_type_node
, NULL_TREE
);
10284 tree v4sf_ftype_v4sf_v4sf
10285 = build_function_type_list (V4SF_type_node
,
10286 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10287 tree opaque_ftype_opaque_opaque_opaque
10288 = build_function_type_list (opaque_V4SI_type_node
,
10289 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
10290 opaque_V4SI_type_node
, NULL_TREE
);
10291 tree v4sf_ftype_v4sf_v4sf_v4si
10292 = build_function_type_list (V4SF_type_node
,
10293 V4SF_type_node
, V4SF_type_node
,
10294 V4SI_type_node
, NULL_TREE
);
10295 tree v4sf_ftype_v4sf_v4sf_v4sf
10296 = build_function_type_list (V4SF_type_node
,
10297 V4SF_type_node
, V4SF_type_node
,
10298 V4SF_type_node
, NULL_TREE
);
10299 tree v4si_ftype_v4si_v4si_v4si
10300 = build_function_type_list (V4SI_type_node
,
10301 V4SI_type_node
, V4SI_type_node
,
10302 V4SI_type_node
, NULL_TREE
);
10303 tree v8hi_ftype_v8hi_v8hi
10304 = build_function_type_list (V8HI_type_node
,
10305 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10306 tree v8hi_ftype_v8hi_v8hi_v8hi
10307 = build_function_type_list (V8HI_type_node
,
10308 V8HI_type_node
, V8HI_type_node
,
10309 V8HI_type_node
, NULL_TREE
);
10310 tree v4si_ftype_v8hi_v8hi_v4si
10311 = build_function_type_list (V4SI_type_node
,
10312 V8HI_type_node
, V8HI_type_node
,
10313 V4SI_type_node
, NULL_TREE
);
10314 tree v4si_ftype_v16qi_v16qi_v4si
10315 = build_function_type_list (V4SI_type_node
,
10316 V16QI_type_node
, V16QI_type_node
,
10317 V4SI_type_node
, NULL_TREE
);
10318 tree v16qi_ftype_v16qi_v16qi
10319 = build_function_type_list (V16QI_type_node
,
10320 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10321 tree v4si_ftype_v4sf_v4sf
10322 = build_function_type_list (V4SI_type_node
,
10323 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10324 tree v8hi_ftype_v16qi_v16qi
10325 = build_function_type_list (V8HI_type_node
,
10326 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10327 tree v4si_ftype_v8hi_v8hi
10328 = build_function_type_list (V4SI_type_node
,
10329 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10330 tree v8hi_ftype_v4si_v4si
10331 = build_function_type_list (V8HI_type_node
,
10332 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
10333 tree v16qi_ftype_v8hi_v8hi
10334 = build_function_type_list (V16QI_type_node
,
10335 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10336 tree v4si_ftype_v16qi_v4si
10337 = build_function_type_list (V4SI_type_node
,
10338 V16QI_type_node
, V4SI_type_node
, NULL_TREE
);
10339 tree v4si_ftype_v16qi_v16qi
10340 = build_function_type_list (V4SI_type_node
,
10341 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10342 tree v4si_ftype_v8hi_v4si
10343 = build_function_type_list (V4SI_type_node
,
10344 V8HI_type_node
, V4SI_type_node
, NULL_TREE
);
10345 tree v4si_ftype_v8hi
10346 = build_function_type_list (V4SI_type_node
, V8HI_type_node
, NULL_TREE
);
10347 tree int_ftype_v4si_v4si
10348 = build_function_type_list (integer_type_node
,
10349 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
10350 tree int_ftype_v4sf_v4sf
10351 = build_function_type_list (integer_type_node
,
10352 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10353 tree int_ftype_v16qi_v16qi
10354 = build_function_type_list (integer_type_node
,
10355 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10356 tree int_ftype_v8hi_v8hi
10357 = build_function_type_list (integer_type_node
,
10358 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10360 /* Add the simple ternary operators. */
10362 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
10364 enum machine_mode mode0
, mode1
, mode2
, mode3
;
10366 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10367 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10378 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
10381 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10382 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10383 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
10384 mode3
= insn_data
[d
->icode
].operand
[3].mode
;
10387 /* When all four are of the same mode. */
10388 if (mode0
== mode1
&& mode1
== mode2
&& mode2
== mode3
)
10393 type
= opaque_ftype_opaque_opaque_opaque
;
10396 type
= v4si_ftype_v4si_v4si_v4si
;
10399 type
= v4sf_ftype_v4sf_v4sf_v4sf
;
10402 type
= v8hi_ftype_v8hi_v8hi_v8hi
;
10405 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
10408 type
= v2sf_ftype_v2sf_v2sf_v2sf
;
10411 gcc_unreachable ();
10414 else if (mode0
== mode1
&& mode1
== mode2
&& mode3
== V16QImode
)
10419 type
= v4si_ftype_v4si_v4si_v16qi
;
10422 type
= v4sf_ftype_v4sf_v4sf_v16qi
;
10425 type
= v8hi_ftype_v8hi_v8hi_v16qi
;
10428 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
10431 gcc_unreachable ();
10434 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
10435 && mode3
== V4SImode
)
10436 type
= v4si_ftype_v16qi_v16qi_v4si
;
10437 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
10438 && mode3
== V4SImode
)
10439 type
= v4si_ftype_v8hi_v8hi_v4si
;
10440 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
10441 && mode3
== V4SImode
)
10442 type
= v4sf_ftype_v4sf_v4sf_v4si
;
10444 /* vchar, vchar, vchar, 4-bit literal. */
10445 else if (mode0
== V16QImode
&& mode1
== mode0
&& mode2
== mode0
10446 && mode3
== QImode
)
10447 type
= v16qi_ftype_v16qi_v16qi_int
;
10449 /* vshort, vshort, vshort, 4-bit literal. */
10450 else if (mode0
== V8HImode
&& mode1
== mode0
&& mode2
== mode0
10451 && mode3
== QImode
)
10452 type
= v8hi_ftype_v8hi_v8hi_int
;
10454 /* vint, vint, vint, 4-bit literal. */
10455 else if (mode0
== V4SImode
&& mode1
== mode0
&& mode2
== mode0
10456 && mode3
== QImode
)
10457 type
= v4si_ftype_v4si_v4si_int
;
10459 /* vfloat, vfloat, vfloat, 4-bit literal. */
10460 else if (mode0
== V4SFmode
&& mode1
== mode0
&& mode2
== mode0
10461 && mode3
== QImode
)
10462 type
= v4sf_ftype_v4sf_v4sf_int
;
10465 gcc_unreachable ();
10467 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10470 /* Add the simple binary operators. */
10471 d
= (struct builtin_description
*) bdesc_2arg
;
10472 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
10474 enum machine_mode mode0
, mode1
, mode2
;
10476 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10477 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10487 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
10490 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10491 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10492 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
10495 /* When all three operands are of the same mode. */
10496 if (mode0
== mode1
&& mode1
== mode2
)
10501 type
= opaque_ftype_opaque_opaque
;
10504 type
= v4sf_ftype_v4sf_v4sf
;
10507 type
= v4si_ftype_v4si_v4si
;
10510 type
= v16qi_ftype_v16qi_v16qi
;
10513 type
= v8hi_ftype_v8hi_v8hi
;
10516 type
= v2si_ftype_v2si_v2si
;
10519 if (TARGET_PAIRED_FLOAT
)
10520 type
= v2sf_ftype_v2sf_v2sf
;
10522 type
= v2sf_ftype_v2sf_v2sf_spe
;
10525 type
= int_ftype_int_int
;
10528 gcc_unreachable ();
10532 /* A few other combos we really don't want to do manually. */
10534 /* vint, vfloat, vfloat. */
10535 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
)
10536 type
= v4si_ftype_v4sf_v4sf
;
10538 /* vshort, vchar, vchar. */
10539 else if (mode0
== V8HImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
10540 type
= v8hi_ftype_v16qi_v16qi
;
10542 /* vint, vshort, vshort. */
10543 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
10544 type
= v4si_ftype_v8hi_v8hi
;
10546 /* vshort, vint, vint. */
10547 else if (mode0
== V8HImode
&& mode1
== V4SImode
&& mode2
== V4SImode
)
10548 type
= v8hi_ftype_v4si_v4si
;
10550 /* vchar, vshort, vshort. */
10551 else if (mode0
== V16QImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
10552 type
= v16qi_ftype_v8hi_v8hi
;
10554 /* vint, vchar, vint. */
10555 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V4SImode
)
10556 type
= v4si_ftype_v16qi_v4si
;
10558 /* vint, vchar, vchar. */
10559 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
10560 type
= v4si_ftype_v16qi_v16qi
;
10562 /* vint, vshort, vint. */
10563 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V4SImode
)
10564 type
= v4si_ftype_v8hi_v4si
;
10566 /* vint, vint, 5-bit literal. */
10567 else if (mode0
== V4SImode
&& mode1
== V4SImode
&& mode2
== QImode
)
10568 type
= v4si_ftype_v4si_int
;
10570 /* vshort, vshort, 5-bit literal. */
10571 else if (mode0
== V8HImode
&& mode1
== V8HImode
&& mode2
== QImode
)
10572 type
= v8hi_ftype_v8hi_int
;
10574 /* vchar, vchar, 5-bit literal. */
10575 else if (mode0
== V16QImode
&& mode1
== V16QImode
&& mode2
== QImode
)
10576 type
= v16qi_ftype_v16qi_int
;
10578 /* vfloat, vint, 5-bit literal. */
10579 else if (mode0
== V4SFmode
&& mode1
== V4SImode
&& mode2
== QImode
)
10580 type
= v4sf_ftype_v4si_int
;
10582 /* vint, vfloat, 5-bit literal. */
10583 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== QImode
)
10584 type
= v4si_ftype_v4sf_int
;
10586 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== SImode
)
10587 type
= v2si_ftype_int_int
;
10589 else if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
10590 type
= v2si_ftype_v2si_char
;
10592 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== QImode
)
10593 type
= v2si_ftype_int_char
;
10598 gcc_assert (mode0
== SImode
);
10602 type
= int_ftype_v4si_v4si
;
10605 type
= int_ftype_v4sf_v4sf
;
10608 type
= int_ftype_v16qi_v16qi
;
10611 type
= int_ftype_v8hi_v8hi
;
10614 gcc_unreachable ();
10618 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10621 /* Add the simple unary operators. */
10622 d
= (struct builtin_description
*) bdesc_1arg
;
10623 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
10625 enum machine_mode mode0
, mode1
;
10627 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10628 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10637 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
10640 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10641 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10644 if (mode0
== V4SImode
&& mode1
== QImode
)
10645 type
= v4si_ftype_int
;
10646 else if (mode0
== V8HImode
&& mode1
== QImode
)
10647 type
= v8hi_ftype_int
;
10648 else if (mode0
== V16QImode
&& mode1
== QImode
)
10649 type
= v16qi_ftype_int
;
10650 else if (mode0
== VOIDmode
&& mode1
== VOIDmode
)
10651 type
= opaque_ftype_opaque
;
10652 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
)
10653 type
= v4sf_ftype_v4sf
;
10654 else if (mode0
== V8HImode
&& mode1
== V16QImode
)
10655 type
= v8hi_ftype_v16qi
;
10656 else if (mode0
== V4SImode
&& mode1
== V8HImode
)
10657 type
= v4si_ftype_v8hi
;
10658 else if (mode0
== V2SImode
&& mode1
== V2SImode
)
10659 type
= v2si_ftype_v2si
;
10660 else if (mode0
== V2SFmode
&& mode1
== V2SFmode
)
10662 if (TARGET_PAIRED_FLOAT
)
10663 type
= v2sf_ftype_v2sf
;
10665 type
= v2sf_ftype_v2sf_spe
;
10667 else if (mode0
== V2SFmode
&& mode1
== V2SImode
)
10668 type
= v2sf_ftype_v2si
;
10669 else if (mode0
== V2SImode
&& mode1
== V2SFmode
)
10670 type
= v2si_ftype_v2sf
;
10671 else if (mode0
== V2SImode
&& mode1
== QImode
)
10672 type
= v2si_ftype_char
;
10674 gcc_unreachable ();
10676 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10681 rs6000_init_libfuncs (void)
10683 if (DEFAULT_ABI
!= ABI_V4
&& TARGET_XCOFF
10684 && !TARGET_POWER2
&& !TARGET_POWERPC
)
10686 /* AIX library routines for float->int conversion. */
10687 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
10688 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
10689 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
10690 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
10693 if (!TARGET_IEEEQUAD
)
10694 /* AIX/Darwin/64-bit Linux quad floating point routines. */
10695 if (!TARGET_XL_COMPAT
)
10697 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
10698 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
10699 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
10700 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
10702 if (!(TARGET_HARD_FLOAT
&& (TARGET_FPRS
|| TARGET_E500_DOUBLE
)))
10704 set_optab_libfunc (neg_optab
, TFmode
, "__gcc_qneg");
10705 set_optab_libfunc (eq_optab
, TFmode
, "__gcc_qeq");
10706 set_optab_libfunc (ne_optab
, TFmode
, "__gcc_qne");
10707 set_optab_libfunc (gt_optab
, TFmode
, "__gcc_qgt");
10708 set_optab_libfunc (ge_optab
, TFmode
, "__gcc_qge");
10709 set_optab_libfunc (lt_optab
, TFmode
, "__gcc_qlt");
10710 set_optab_libfunc (le_optab
, TFmode
, "__gcc_qle");
10712 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "__gcc_stoq");
10713 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "__gcc_dtoq");
10714 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "__gcc_qtos");
10715 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "__gcc_qtod");
10716 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "__gcc_qtoi");
10717 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "__gcc_qtou");
10718 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "__gcc_itoq");
10719 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "__gcc_utoq");
10722 if (!(TARGET_HARD_FLOAT
&& TARGET_FPRS
))
10723 set_optab_libfunc (unord_optab
, TFmode
, "__gcc_qunord");
10727 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
10728 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
10729 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
10730 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
10734 /* 32-bit SVR4 quad floating point routines. */
10736 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
10737 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
10738 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
10739 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
10740 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
10741 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
10742 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
10744 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
10745 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
10746 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
10747 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
10748 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
10749 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
10751 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
10752 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
10753 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
10754 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
10755 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
10756 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
10757 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
10758 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "_q_utoq");
10763 /* Expand a block clear operation, and return 1 if successful. Return 0
10764 if we should let the compiler generate normal code.
10766 operands[0] is the destination
10767 operands[1] is the length
10768 operands[3] is the alignment */
10771 expand_block_clear (rtx operands
[])
10773 rtx orig_dest
= operands
[0];
10774 rtx bytes_rtx
= operands
[1];
10775 rtx align_rtx
= operands
[3];
10776 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
10777 HOST_WIDE_INT align
;
10778 HOST_WIDE_INT bytes
;
10783 /* If this is not a fixed size move, just call memcpy */
10787 /* This must be a fixed size alignment */
10788 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
10789 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
10791 /* Anything to clear? */
10792 bytes
= INTVAL (bytes_rtx
);
10796 /* Use the builtin memset after a point, to avoid huge code bloat.
10797 When optimize_size, avoid any significant code bloat; calling
10798 memset is about 4 instructions, so allow for one instruction to
10799 load zero and three to do clearing. */
10800 if (TARGET_ALTIVEC
&& align
>= 128)
10802 else if (TARGET_POWERPC64
&& align
>= 32)
10804 else if (TARGET_SPE
&& align
>= 64)
10809 if (optimize_size
&& bytes
> 3 * clear_step
)
10811 if (! optimize_size
&& bytes
> 8 * clear_step
)
10814 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
10816 enum machine_mode mode
= BLKmode
;
10819 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
10824 else if (bytes
>= 8 && TARGET_SPE
&& align
>= 64)
10829 else if (bytes
>= 8 && TARGET_POWERPC64
10830 /* 64-bit loads and stores require word-aligned
10832 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
10837 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
10838 { /* move 4 bytes */
10842 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
10843 { /* move 2 bytes */
10847 else /* move 1 byte at a time */
10853 dest
= adjust_address (orig_dest
, mode
, offset
);
10855 emit_move_insn (dest
, CONST0_RTX (mode
));
10862 /* Expand a block move operation, and return 1 if successful. Return 0
10863 if we should let the compiler generate normal code.
10865 operands[0] is the destination
10866 operands[1] is the source
10867 operands[2] is the length
10868 operands[3] is the alignment */
10870 #define MAX_MOVE_REG 4
10873 expand_block_move (rtx operands
[])
10875 rtx orig_dest
= operands
[0];
10876 rtx orig_src
= operands
[1];
10877 rtx bytes_rtx
= operands
[2];
10878 rtx align_rtx
= operands
[3];
10879 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
10884 rtx stores
[MAX_MOVE_REG
];
10887 /* If this is not a fixed size move, just call memcpy */
10891 /* This must be a fixed size alignment */
10892 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
10893 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
10895 /* Anything to move? */
10896 bytes
= INTVAL (bytes_rtx
);
10900 /* store_one_arg depends on expand_block_move to handle at least the size of
10901 reg_parm_stack_space. */
10902 if (bytes
> (TARGET_POWERPC64
? 64 : 32))
10905 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
10908 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
10909 rtx (*mov
) (rtx
, rtx
);
10911 enum machine_mode mode
= BLKmode
;
10914 /* Altivec first, since it will be faster than a string move
10915 when it applies, and usually not significantly larger. */
10916 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
10920 gen_func
.mov
= gen_movv4si
;
10922 else if (TARGET_SPE
&& bytes
>= 8 && align
>= 64)
10926 gen_func
.mov
= gen_movv2si
;
10928 else if (TARGET_STRING
10929 && bytes
> 24 /* move up to 32 bytes at a time */
10935 && ! fixed_regs
[10]
10936 && ! fixed_regs
[11]
10937 && ! fixed_regs
[12])
10939 move_bytes
= (bytes
> 32) ? 32 : bytes
;
10940 gen_func
.movmemsi
= gen_movmemsi_8reg
;
10942 else if (TARGET_STRING
10943 && bytes
> 16 /* move up to 24 bytes at a time */
10949 && ! fixed_regs
[10])
10951 move_bytes
= (bytes
> 24) ? 24 : bytes
;
10952 gen_func
.movmemsi
= gen_movmemsi_6reg
;
10954 else if (TARGET_STRING
10955 && bytes
> 8 /* move up to 16 bytes at a time */
10959 && ! fixed_regs
[8])
10961 move_bytes
= (bytes
> 16) ? 16 : bytes
;
10962 gen_func
.movmemsi
= gen_movmemsi_4reg
;
10964 else if (bytes
>= 8 && TARGET_POWERPC64
10965 /* 64-bit loads and stores require word-aligned
10967 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
10971 gen_func
.mov
= gen_movdi
;
10973 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
10974 { /* move up to 8 bytes at a time */
10975 move_bytes
= (bytes
> 8) ? 8 : bytes
;
10976 gen_func
.movmemsi
= gen_movmemsi_2reg
;
10978 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
10979 { /* move 4 bytes */
10982 gen_func
.mov
= gen_movsi
;
10984 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
10985 { /* move 2 bytes */
10988 gen_func
.mov
= gen_movhi
;
10990 else if (TARGET_STRING
&& bytes
> 1)
10991 { /* move up to 4 bytes at a time */
10992 move_bytes
= (bytes
> 4) ? 4 : bytes
;
10993 gen_func
.movmemsi
= gen_movmemsi_1reg
;
10995 else /* move 1 byte at a time */
10999 gen_func
.mov
= gen_movqi
;
11002 src
= adjust_address (orig_src
, mode
, offset
);
11003 dest
= adjust_address (orig_dest
, mode
, offset
);
11005 if (mode
!= BLKmode
)
11007 rtx tmp_reg
= gen_reg_rtx (mode
);
11009 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
11010 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
11013 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
11016 for (i
= 0; i
< num_reg
; i
++)
11017 emit_insn (stores
[i
]);
11021 if (mode
== BLKmode
)
11023 /* Move the address into scratch registers. The movmemsi
11024 patterns require zero offset. */
11025 if (!REG_P (XEXP (src
, 0)))
11027 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
11028 src
= replace_equiv_address (src
, src_reg
);
11030 set_mem_size (src
, GEN_INT (move_bytes
));
11032 if (!REG_P (XEXP (dest
, 0)))
11034 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
11035 dest
= replace_equiv_address (dest
, dest_reg
);
11037 set_mem_size (dest
, GEN_INT (move_bytes
));
11039 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
11040 GEN_INT (move_bytes
& 31),
11049 /* Return a string to perform a load_multiple operation.
11050 operands[0] is the vector.
11051 operands[1] is the source address.
11052 operands[2] is the first destination register. */
11055 rs6000_output_load_multiple (rtx operands
[3])
11057 /* We have to handle the case where the pseudo used to contain the address
11058 is assigned to one of the output registers. */
11060 int words
= XVECLEN (operands
[0], 0);
11063 if (XVECLEN (operands
[0], 0) == 1)
11064 return "{l|lwz} %2,0(%1)";
11066 for (i
= 0; i
< words
; i
++)
11067 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
11068 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
11072 xop
[0] = GEN_INT (4 * (words
-1));
11073 xop
[1] = operands
[1];
11074 xop
[2] = operands
[2];
11075 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
11080 xop
[0] = GEN_INT (4 * (words
-1));
11081 xop
[1] = operands
[1];
11082 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
11083 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
);
11088 for (j
= 0; j
< words
; j
++)
11091 xop
[0] = GEN_INT (j
* 4);
11092 xop
[1] = operands
[1];
11093 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
11094 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
11096 xop
[0] = GEN_INT (i
* 4);
11097 xop
[1] = operands
[1];
11098 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
11103 return "{lsi|lswi} %2,%1,%N0";
11107 /* A validation routine: say whether CODE, a condition code, and MODE
11108 match. The other alternatives either don't make sense or should
11109 never be generated. */
11112 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
11114 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
11115 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
11116 && GET_MODE_CLASS (mode
) == MODE_CC
);
11118 /* These don't make sense. */
11119 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
11120 || mode
!= CCUNSmode
);
11122 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
11123 || mode
== CCUNSmode
);
11125 gcc_assert (mode
== CCFPmode
11126 || (code
!= ORDERED
&& code
!= UNORDERED
11127 && code
!= UNEQ
&& code
!= LTGT
11128 && code
!= UNGT
&& code
!= UNLT
11129 && code
!= UNGE
&& code
!= UNLE
));
11131 /* These should never be generated except for
11132 flag_finite_math_only. */
11133 gcc_assert (mode
!= CCFPmode
11134 || flag_finite_math_only
11135 || (code
!= LE
&& code
!= GE
11136 && code
!= UNEQ
&& code
!= LTGT
11137 && code
!= UNGT
&& code
!= UNLT
));
11139 /* These are invalid; the information is not there. */
11140 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
11144 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
11145 mask required to convert the result of a rotate insn into a shift
11146 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
11149 includes_lshift_p (rtx shiftop
, rtx andop
)
11151 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
11153 shift_mask
<<= INTVAL (shiftop
);
11155 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
11158 /* Similar, but for right shift. */
11161 includes_rshift_p (rtx shiftop
, rtx andop
)
11163 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
11165 shift_mask
>>= INTVAL (shiftop
);
11167 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
11170 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
11171 to perform a left shift. It must have exactly SHIFTOP least
11172 significant 0's, then one or more 1's, then zero or more 0's. */
11175 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
11177 if (GET_CODE (andop
) == CONST_INT
)
11179 HOST_WIDE_INT c
, lsb
, shift_mask
;
11181 c
= INTVAL (andop
);
11182 if (c
== 0 || c
== ~0)
11186 shift_mask
<<= INTVAL (shiftop
);
11188 /* Find the least significant one bit. */
11191 /* It must coincide with the LSB of the shift mask. */
11192 if (-lsb
!= shift_mask
)
11195 /* Invert to look for the next transition (if any). */
11198 /* Remove the low group of ones (originally low group of zeros). */
11201 /* Again find the lsb, and check we have all 1's above. */
11205 else if (GET_CODE (andop
) == CONST_DOUBLE
11206 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
11208 HOST_WIDE_INT low
, high
, lsb
;
11209 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
11211 low
= CONST_DOUBLE_LOW (andop
);
11212 if (HOST_BITS_PER_WIDE_INT
< 64)
11213 high
= CONST_DOUBLE_HIGH (andop
);
11215 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
11216 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
11219 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
11221 shift_mask_high
= ~0;
11222 if (INTVAL (shiftop
) > 32)
11223 shift_mask_high
<<= INTVAL (shiftop
) - 32;
11225 lsb
= high
& -high
;
11227 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
11233 lsb
= high
& -high
;
11234 return high
== -lsb
;
11237 shift_mask_low
= ~0;
11238 shift_mask_low
<<= INTVAL (shiftop
);
11242 if (-lsb
!= shift_mask_low
)
11245 if (HOST_BITS_PER_WIDE_INT
< 64)
11250 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
11252 lsb
= high
& -high
;
11253 return high
== -lsb
;
11257 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
11263 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
11264 to perform a left shift. It must have SHIFTOP or more least
11265 significant 0's, with the remainder of the word 1's. */
11268 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
11270 if (GET_CODE (andop
) == CONST_INT
)
11272 HOST_WIDE_INT c
, lsb
, shift_mask
;
11275 shift_mask
<<= INTVAL (shiftop
);
11276 c
= INTVAL (andop
);
11278 /* Find the least significant one bit. */
11281 /* It must be covered by the shift mask.
11282 This test also rejects c == 0. */
11283 if ((lsb
& shift_mask
) == 0)
11286 /* Check we have all 1's above the transition, and reject all 1's. */
11287 return c
== -lsb
&& lsb
!= 1;
11289 else if (GET_CODE (andop
) == CONST_DOUBLE
11290 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
11292 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
11294 low
= CONST_DOUBLE_LOW (andop
);
11296 if (HOST_BITS_PER_WIDE_INT
< 64)
11298 HOST_WIDE_INT high
, shift_mask_high
;
11300 high
= CONST_DOUBLE_HIGH (andop
);
11304 shift_mask_high
= ~0;
11305 if (INTVAL (shiftop
) > 32)
11306 shift_mask_high
<<= INTVAL (shiftop
) - 32;
11308 lsb
= high
& -high
;
11310 if ((lsb
& shift_mask_high
) == 0)
11313 return high
== -lsb
;
11319 shift_mask_low
= ~0;
11320 shift_mask_low
<<= INTVAL (shiftop
);
11324 if ((lsb
& shift_mask_low
) == 0)
11327 return low
== -lsb
&& lsb
!= 1;
11333 /* Return 1 if operands will generate a valid arguments to rlwimi
11334 instruction for insert with right shift in 64-bit mode. The mask may
11335 not start on the first bit or stop on the last bit because wrap-around
11336 effects of instruction do not correspond to semantics of RTL insn. */
11339 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
11341 if (INTVAL (startop
) > 32
11342 && INTVAL (startop
) < 64
11343 && INTVAL (sizeop
) > 1
11344 && INTVAL (sizeop
) + INTVAL (startop
) < 64
11345 && INTVAL (shiftop
) > 0
11346 && INTVAL (sizeop
) + INTVAL (shiftop
) < 32
11347 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
11353 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
11354 for lfq and stfq insns iff the registers are hard registers. */
11357 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
11359 /* We might have been passed a SUBREG. */
11360 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
11363 /* We might have been passed non floating point registers. */
11364 if (!FP_REGNO_P (REGNO (reg1
))
11365 || !FP_REGNO_P (REGNO (reg2
)))
11368 return (REGNO (reg1
) == REGNO (reg2
) - 1);
11371 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
11372 addr1 and addr2 must be in consecutive memory locations
11373 (addr2 == addr1 + 8). */
11376 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
11379 unsigned int reg1
, reg2
;
11380 int offset1
, offset2
;
11382 /* The mems cannot be volatile. */
11383 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
11386 addr1
= XEXP (mem1
, 0);
11387 addr2
= XEXP (mem2
, 0);
11389 /* Extract an offset (if used) from the first addr. */
11390 if (GET_CODE (addr1
) == PLUS
)
11392 /* If not a REG, return zero. */
11393 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
11397 reg1
= REGNO (XEXP (addr1
, 0));
11398 /* The offset must be constant! */
11399 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
11401 offset1
= INTVAL (XEXP (addr1
, 1));
11404 else if (GET_CODE (addr1
) != REG
)
11408 reg1
= REGNO (addr1
);
11409 /* This was a simple (mem (reg)) expression. Offset is 0. */
11413 /* And now for the second addr. */
11414 if (GET_CODE (addr2
) == PLUS
)
11416 /* If not a REG, return zero. */
11417 if (GET_CODE (XEXP (addr2
, 0)) != REG
)
11421 reg2
= REGNO (XEXP (addr2
, 0));
11422 /* The offset must be constant. */
11423 if (GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
11425 offset2
= INTVAL (XEXP (addr2
, 1));
11428 else if (GET_CODE (addr2
) != REG
)
11432 reg2
= REGNO (addr2
);
11433 /* This was a simple (mem (reg)) expression. Offset is 0. */
11437 /* Both of these must have the same base register. */
11441 /* The offset for the second addr must be 8 more than the first addr. */
11442 if (offset2
!= offset1
+ 8)
11445 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
11452 rs6000_secondary_memory_needed_rtx (enum machine_mode mode
)
11454 static bool eliminated
= false;
11455 if (mode
!= SDmode
)
11456 return assign_stack_local (mode
, GET_MODE_SIZE (mode
), 0);
11459 rtx mem
= cfun
->machine
->sdmode_stack_slot
;
11460 gcc_assert (mem
!= NULL_RTX
);
11464 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
11465 cfun
->machine
->sdmode_stack_slot
= mem
;
11473 rs6000_check_sdmode (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
11475 /* Don't walk into types. */
11476 if (*tp
== NULL_TREE
|| *tp
== error_mark_node
|| TYPE_P (*tp
))
11478 *walk_subtrees
= 0;
11482 switch (TREE_CODE (*tp
))
11490 case ALIGN_INDIRECT_REF
:
11491 case MISALIGNED_INDIRECT_REF
:
11492 case VIEW_CONVERT_EXPR
:
11493 if (TYPE_MODE (TREE_TYPE (*tp
)) == SDmode
)
11504 /* Allocate a 64-bit stack slot to be used for copying SDmode
11505 values through if this function has any SDmode references. */
11508 rs6000_alloc_sdmode_stack_slot (void)
11512 gimple_stmt_iterator gsi
;
11514 gcc_assert (cfun
->machine
->sdmode_stack_slot
== NULL_RTX
);
11517 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
11519 tree ret
= walk_gimple_op (gsi_stmt (gsi
), rs6000_check_sdmode
, NULL
);
11522 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
11523 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
11529 /* Check for any SDmode parameters of the function. */
11530 for (t
= DECL_ARGUMENTS (cfun
->decl
); t
; t
= TREE_CHAIN (t
))
11532 if (TREE_TYPE (t
) == error_mark_node
)
11535 if (TYPE_MODE (TREE_TYPE (t
)) == SDmode
11536 || TYPE_MODE (DECL_ARG_TYPE (t
)) == SDmode
)
11538 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
11539 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
11547 rs6000_instantiate_decls (void)
11549 if (cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
11550 instantiate_decl_rtl (cfun
->machine
->sdmode_stack_slot
);
11553 /* Return the register class of a scratch register needed to copy IN into
11554 or out of a register in RCLASS in MODE. If it can be done directly,
11555 NO_REGS is returned. */
11558 rs6000_secondary_reload_class (enum reg_class rclass
,
11559 enum machine_mode mode ATTRIBUTE_UNUSED
,
11564 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
11566 && MACHOPIC_INDIRECT
11570 /* We cannot copy a symbolic operand directly into anything
11571 other than BASE_REGS for TARGET_ELF. So indicate that a
11572 register from BASE_REGS is needed as an intermediate
11575 On Darwin, pic addresses require a load from memory, which
11576 needs a base register. */
11577 if (rclass
!= BASE_REGS
11578 && (GET_CODE (in
) == SYMBOL_REF
11579 || GET_CODE (in
) == HIGH
11580 || GET_CODE (in
) == LABEL_REF
11581 || GET_CODE (in
) == CONST
))
11585 if (GET_CODE (in
) == REG
)
11587 regno
= REGNO (in
);
11588 if (regno
>= FIRST_PSEUDO_REGISTER
)
11590 regno
= true_regnum (in
);
11591 if (regno
>= FIRST_PSEUDO_REGISTER
)
11595 else if (GET_CODE (in
) == SUBREG
)
11597 regno
= true_regnum (in
);
11598 if (regno
>= FIRST_PSEUDO_REGISTER
)
11604 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
11606 if (rclass
== GENERAL_REGS
|| rclass
== BASE_REGS
11607 || (regno
>= 0 && INT_REGNO_P (regno
)))
11610 /* Constants, memory, and FP registers can go into FP registers. */
11611 if ((regno
== -1 || FP_REGNO_P (regno
))
11612 && (rclass
== FLOAT_REGS
|| rclass
== NON_SPECIAL_REGS
))
11613 return (mode
!= SDmode
) ? NO_REGS
: GENERAL_REGS
;
11615 /* Memory, and AltiVec registers can go into AltiVec registers. */
11616 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
11617 && rclass
== ALTIVEC_REGS
)
11620 /* We can copy among the CR registers. */
11621 if ((rclass
== CR_REGS
|| rclass
== CR0_REGS
)
11622 && regno
>= 0 && CR_REGNO_P (regno
))
11625 /* Otherwise, we need GENERAL_REGS. */
11626 return GENERAL_REGS
;
11629 /* Given a comparison operation, return the bit number in CCR to test. We
11630 know this is a valid comparison.
11632 SCC_P is 1 if this is for an scc. That means that %D will have been
11633 used instead of %C, so the bits will be in different places.
11635 Return -1 if OP isn't a valid comparison for some reason. */
11638 ccr_bit (rtx op
, int scc_p
)
11640 enum rtx_code code
= GET_CODE (op
);
11641 enum machine_mode cc_mode
;
11646 if (!COMPARISON_P (op
))
11649 reg
= XEXP (op
, 0);
11651 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
11653 cc_mode
= GET_MODE (reg
);
11654 cc_regnum
= REGNO (reg
);
11655 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
11657 validate_condition_mode (code
, cc_mode
);
11659 /* When generating a sCOND operation, only positive conditions are
11662 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
11663 || code
== GTU
|| code
== LTU
);
11668 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
11670 return base_bit
+ 2;
11671 case GT
: case GTU
: case UNLE
:
11672 return base_bit
+ 1;
11673 case LT
: case LTU
: case UNGE
:
11675 case ORDERED
: case UNORDERED
:
11676 return base_bit
+ 3;
11679 /* If scc, we will have done a cror to put the bit in the
11680 unordered position. So test that bit. For integer, this is ! LT
11681 unless this is an scc insn. */
11682 return scc_p
? base_bit
+ 3 : base_bit
;
11685 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
11688 gcc_unreachable ();
11692 /* Return the GOT register. */
11695 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
11697 /* The second flow pass currently (June 1999) can't update
11698 regs_ever_live without disturbing other parts of the compiler, so
11699 update it here to make the prolog/epilogue code happy. */
11700 if (!can_create_pseudo_p ()
11701 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
))
11702 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM
, true);
11704 crtl
->uses_pic_offset_table
= 1;
11706 return pic_offset_table_rtx
;
11709 /* Function to init struct machine_function.
11710 This will be called, via a pointer variable,
11711 from push_function_context. */
11713 static struct machine_function
*
11714 rs6000_init_machine_status (void)
11716 return GGC_CNEW (machine_function
);
11719 /* These macros test for integers and extract the low-order bits. */
11721 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
11722 && GET_MODE (X) == VOIDmode)
11724 #define INT_LOWPART(X) \
11725 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
11728 extract_MB (rtx op
)
11731 unsigned long val
= INT_LOWPART (op
);
11733 /* If the high bit is zero, the value is the first 1 bit we find
11735 if ((val
& 0x80000000) == 0)
11737 gcc_assert (val
& 0xffffffff);
11740 while (((val
<<= 1) & 0x80000000) == 0)
11745 /* If the high bit is set and the low bit is not, or the mask is all
11746 1's, the value is zero. */
11747 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
11750 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11753 while (((val
>>= 1) & 1) != 0)
11760 extract_ME (rtx op
)
11763 unsigned long val
= INT_LOWPART (op
);
11765 /* If the low bit is zero, the value is the first 1 bit we find from
11767 if ((val
& 1) == 0)
11769 gcc_assert (val
& 0xffffffff);
11772 while (((val
>>= 1) & 1) == 0)
11778 /* If the low bit is set and the high bit is not, or the mask is all
11779 1's, the value is 31. */
11780 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
11783 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11786 while (((val
<<= 1) & 0x80000000) != 0)
11792 /* Locate some local-dynamic symbol still in use by this function
11793 so that we can print its name in some tls_ld pattern. */
11795 static const char *
11796 rs6000_get_some_local_dynamic_name (void)
11800 if (cfun
->machine
->some_ld_name
)
11801 return cfun
->machine
->some_ld_name
;
11803 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
11805 && for_each_rtx (&PATTERN (insn
),
11806 rs6000_get_some_local_dynamic_name_1
, 0))
11807 return cfun
->machine
->some_ld_name
;
11809 gcc_unreachable ();
11812 /* Helper function for rs6000_get_some_local_dynamic_name. */
11815 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
11819 if (GET_CODE (x
) == SYMBOL_REF
)
11821 const char *str
= XSTR (x
, 0);
11822 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
11824 cfun
->machine
->some_ld_name
= str
;
11832 /* Write out a function code label. */
11835 rs6000_output_function_entry (FILE *file
, const char *fname
)
11837 if (fname
[0] != '.')
11839 switch (DEFAULT_ABI
)
11842 gcc_unreachable ();
11848 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
11857 RS6000_OUTPUT_BASENAME (file
, fname
);
11859 assemble_name (file
, fname
);
11862 /* Print an operand. Recognize special options, documented below. */
11865 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
11866 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
11868 #define SMALL_DATA_RELOC "sda21"
11869 #define SMALL_DATA_REG 0
11873 print_operand (FILE *file
, rtx x
, int code
)
11877 unsigned HOST_WIDE_INT uval
;
11882 /* Write out an instruction after the call which may be replaced
11883 with glue code by the loader. This depends on the AIX version. */
11884 asm_fprintf (file
, RS6000_CALL_GLUE
);
11887 /* %a is output_address. */
11890 /* If X is a constant integer whose low-order 5 bits are zero,
11891 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
11892 in the AIX assembler where "sri" with a zero shift count
11893 writes a trash instruction. */
11894 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
11901 /* If constant, low-order 16 bits of constant, unsigned.
11902 Otherwise, write normally. */
11904 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
11906 print_operand (file
, x
, 0);
11910 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
11911 for 64-bit mask direction. */
11912 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
11915 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
11919 /* X is a CR register. Print the number of the GT bit of the CR. */
11920 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
11921 output_operand_lossage ("invalid %%E value");
11923 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
11927 /* Like 'J' but get to the GT bit only. */
11928 gcc_assert (GET_CODE (x
) == REG
);
11930 /* Bit 1 is GT bit. */
11931 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 1;
11933 /* Add one for shift count in rlinm for scc. */
11934 fprintf (file
, "%d", i
+ 1);
11938 /* X is a CR register. Print the number of the EQ bit of the CR */
11939 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
11940 output_operand_lossage ("invalid %%E value");
11942 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
11946 /* X is a CR register. Print the shift count needed to move it
11947 to the high-order four bits. */
11948 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
11949 output_operand_lossage ("invalid %%f value");
11951 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
11955 /* Similar, but print the count for the rotate in the opposite
11957 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
11958 output_operand_lossage ("invalid %%F value");
11960 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
11964 /* X is a constant integer. If it is negative, print "m",
11965 otherwise print "z". This is to make an aze or ame insn. */
11966 if (GET_CODE (x
) != CONST_INT
)
11967 output_operand_lossage ("invalid %%G value");
11968 else if (INTVAL (x
) >= 0)
11975 /* If constant, output low-order five bits. Otherwise, write
11978 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
11980 print_operand (file
, x
, 0);
11984 /* If constant, output low-order six bits. Otherwise, write
11987 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
11989 print_operand (file
, x
, 0);
11993 /* Print `i' if this is a constant, else nothing. */
11999 /* Write the bit number in CCR for jump. */
12000 i
= ccr_bit (x
, 0);
12002 output_operand_lossage ("invalid %%j code");
12004 fprintf (file
, "%d", i
);
12008 /* Similar, but add one for shift count in rlinm for scc and pass
12009 scc flag to `ccr_bit'. */
12010 i
= ccr_bit (x
, 1);
12012 output_operand_lossage ("invalid %%J code");
12014 /* If we want bit 31, write a shift count of zero, not 32. */
12015 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
12019 /* X must be a constant. Write the 1's complement of the
12022 output_operand_lossage ("invalid %%k value");
12024 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
12028 /* X must be a symbolic constant on ELF. Write an
12029 expression suitable for an 'addi' that adds in the low 16
12030 bits of the MEM. */
12031 if (GET_CODE (x
) != CONST
)
12033 print_operand_address (file
, x
);
12034 fputs ("@l", file
);
12038 if (GET_CODE (XEXP (x
, 0)) != PLUS
12039 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
12040 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
12041 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
12042 output_operand_lossage ("invalid %%K value");
12043 print_operand_address (file
, XEXP (XEXP (x
, 0), 0));
12044 fputs ("@l", file
);
12045 /* For GNU as, there must be a non-alphanumeric character
12046 between 'l' and the number. The '-' is added by
12047 print_operand() already. */
12048 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
12050 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
12054 /* %l is output_asm_label. */
12057 /* Write second word of DImode or DFmode reference. Works on register
12058 or non-indexed memory only. */
12059 if (GET_CODE (x
) == REG
)
12060 fputs (reg_names
[REGNO (x
) + 1], file
);
12061 else if (GET_CODE (x
) == MEM
)
12063 /* Handle possible auto-increment. Since it is pre-increment and
12064 we have already done it, we can just use an offset of word. */
12065 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
12066 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12067 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
12069 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12070 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
12073 output_address (XEXP (adjust_address_nv (x
, SImode
,
12077 if (small_data_operand (x
, GET_MODE (x
)))
12078 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12079 reg_names
[SMALL_DATA_REG
]);
12084 /* MB value for a mask operand. */
12085 if (! mask_operand (x
, SImode
))
12086 output_operand_lossage ("invalid %%m value");
12088 fprintf (file
, "%d", extract_MB (x
));
12092 /* ME value for a mask operand. */
12093 if (! mask_operand (x
, SImode
))
12094 output_operand_lossage ("invalid %%M value");
12096 fprintf (file
, "%d", extract_ME (x
));
12099 /* %n outputs the negative of its operand. */
12102 /* Write the number of elements in the vector times 4. */
12103 if (GET_CODE (x
) != PARALLEL
)
12104 output_operand_lossage ("invalid %%N value");
12106 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
12110 /* Similar, but subtract 1 first. */
12111 if (GET_CODE (x
) != PARALLEL
)
12112 output_operand_lossage ("invalid %%O value");
12114 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
12118 /* X is a CONST_INT that is a power of two. Output the logarithm. */
12120 || INT_LOWPART (x
) < 0
12121 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
12122 output_operand_lossage ("invalid %%p value");
12124 fprintf (file
, "%d", i
);
12128 /* The operand must be an indirect memory reference. The result
12129 is the register name. */
12130 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
12131 || REGNO (XEXP (x
, 0)) >= 32)
12132 output_operand_lossage ("invalid %%P value");
12134 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
12138 /* This outputs the logical code corresponding to a boolean
12139 expression. The expression may have one or both operands
12140 negated (if one, only the first one). For condition register
12141 logical operations, it will also treat the negated
12142 CR codes as NOTs, but not handle NOTs of them. */
12144 const char *const *t
= 0;
12146 enum rtx_code code
= GET_CODE (x
);
12147 static const char * const tbl
[3][3] = {
12148 { "and", "andc", "nor" },
12149 { "or", "orc", "nand" },
12150 { "xor", "eqv", "xor" } };
12154 else if (code
== IOR
)
12156 else if (code
== XOR
)
12159 output_operand_lossage ("invalid %%q value");
12161 if (GET_CODE (XEXP (x
, 0)) != NOT
)
12165 if (GET_CODE (XEXP (x
, 1)) == NOT
)
12183 /* X is a CR register. Print the mask for `mtcrf'. */
12184 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
12185 output_operand_lossage ("invalid %%R value");
12187 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
12191 /* Low 5 bits of 32 - value */
12193 output_operand_lossage ("invalid %%s value");
12195 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
12199 /* PowerPC64 mask position. All 0's is excluded.
12200 CONST_INT 32-bit mask is considered sign-extended so any
12201 transition must occur within the CONST_INT, not on the boundary. */
12202 if (! mask64_operand (x
, DImode
))
12203 output_operand_lossage ("invalid %%S value");
12205 uval
= INT_LOWPART (x
);
12207 if (uval
& 1) /* Clear Left */
12209 #if HOST_BITS_PER_WIDE_INT > 64
12210 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
12214 else /* Clear Right */
12217 #if HOST_BITS_PER_WIDE_INT > 64
12218 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
12224 gcc_assert (i
>= 0);
12225 fprintf (file
, "%d", i
);
12229 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
12230 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
12232 /* Bit 3 is OV bit. */
12233 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
12235 /* If we want bit 31, write a shift count of zero, not 32. */
12236 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
12240 /* Print the symbolic name of a branch target register. */
12241 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LR_REGNO
12242 && REGNO (x
) != CTR_REGNO
))
12243 output_operand_lossage ("invalid %%T value");
12244 else if (REGNO (x
) == LR_REGNO
)
12245 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
12247 fputs ("ctr", file
);
12251 /* High-order 16 bits of constant for use in unsigned operand. */
12253 output_operand_lossage ("invalid %%u value");
12255 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
12256 (INT_LOWPART (x
) >> 16) & 0xffff);
12260 /* High-order 16 bits of constant for use in signed operand. */
12262 output_operand_lossage ("invalid %%v value");
12264 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
12265 (INT_LOWPART (x
) >> 16) & 0xffff);
12269 /* Print `u' if this has an auto-increment or auto-decrement. */
12270 if (GET_CODE (x
) == MEM
12271 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
12272 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
12273 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
))
12278 /* Print the trap code for this operand. */
12279 switch (GET_CODE (x
))
12282 fputs ("eq", file
); /* 4 */
12285 fputs ("ne", file
); /* 24 */
12288 fputs ("lt", file
); /* 16 */
12291 fputs ("le", file
); /* 20 */
12294 fputs ("gt", file
); /* 8 */
12297 fputs ("ge", file
); /* 12 */
12300 fputs ("llt", file
); /* 2 */
12303 fputs ("lle", file
); /* 6 */
12306 fputs ("lgt", file
); /* 1 */
12309 fputs ("lge", file
); /* 5 */
12312 gcc_unreachable ();
12317 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
12320 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
12321 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
12323 print_operand (file
, x
, 0);
12327 /* MB value for a PowerPC64 rldic operand. */
12328 val
= (GET_CODE (x
) == CONST_INT
12329 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
12334 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
12335 if ((val
<<= 1) < 0)
12338 #if HOST_BITS_PER_WIDE_INT == 32
12339 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
12340 i
+= 32; /* zero-extend high-part was all 0's */
12341 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
12343 val
= CONST_DOUBLE_LOW (x
);
12349 for ( ; i
< 64; i
++)
12350 if ((val
<<= 1) < 0)
12355 fprintf (file
, "%d", i
+ 1);
12359 if (GET_CODE (x
) == MEM
12360 && (legitimate_indexed_address_p (XEXP (x
, 0), 0)
12361 || (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
12362 && legitimate_indexed_address_p (XEXP (XEXP (x
, 0), 1), 0))))
12367 /* Like 'L', for third word of TImode */
12368 if (GET_CODE (x
) == REG
)
12369 fputs (reg_names
[REGNO (x
) + 2], file
);
12370 else if (GET_CODE (x
) == MEM
)
12372 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
12373 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12374 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
12375 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12376 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
12378 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
12379 if (small_data_operand (x
, GET_MODE (x
)))
12380 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12381 reg_names
[SMALL_DATA_REG
]);
12386 /* X is a SYMBOL_REF. Write out the name preceded by a
12387 period and without any trailing data in brackets. Used for function
12388 names. If we are configured for System V (or the embedded ABI) on
12389 the PowerPC, do not emit the period, since those systems do not use
12390 TOCs and the like. */
12391 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
12393 /* Mark the decl as referenced so that cgraph will output the
12395 if (SYMBOL_REF_DECL (x
))
12396 mark_decl_referenced (SYMBOL_REF_DECL (x
));
12398 /* For macho, check to see if we need a stub. */
12401 const char *name
= XSTR (x
, 0);
12403 if (MACHOPIC_INDIRECT
12404 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
12405 name
= machopic_indirection_name (x
, /*stub_p=*/true);
12407 assemble_name (file
, name
);
12409 else if (!DOT_SYMBOLS
)
12410 assemble_name (file
, XSTR (x
, 0));
12412 rs6000_output_function_entry (file
, XSTR (x
, 0));
12416 /* Like 'L', for last word of TImode. */
12417 if (GET_CODE (x
) == REG
)
12418 fputs (reg_names
[REGNO (x
) + 3], file
);
12419 else if (GET_CODE (x
) == MEM
)
12421 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
12422 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12423 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
12424 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12425 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
12427 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
12428 if (small_data_operand (x
, GET_MODE (x
)))
12429 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12430 reg_names
[SMALL_DATA_REG
]);
12434 /* Print AltiVec or SPE memory operand. */
12439 gcc_assert (GET_CODE (x
) == MEM
);
12443 /* Ugly hack because %y is overloaded. */
12444 if ((TARGET_SPE
|| TARGET_E500_DOUBLE
)
12445 && (GET_MODE_SIZE (GET_MODE (x
)) == 8
12446 || GET_MODE (x
) == TFmode
12447 || GET_MODE (x
) == TImode
))
12449 /* Handle [reg]. */
12450 if (GET_CODE (tmp
) == REG
)
12452 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
12455 /* Handle [reg+UIMM]. */
12456 else if (GET_CODE (tmp
) == PLUS
&&
12457 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
12461 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
12463 x
= INTVAL (XEXP (tmp
, 1));
12464 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
12468 /* Fall through. Must be [reg+reg]. */
12471 && GET_CODE (tmp
) == AND
12472 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
12473 && INTVAL (XEXP (tmp
, 1)) == -16)
12474 tmp
= XEXP (tmp
, 0);
12475 if (GET_CODE (tmp
) == REG
)
12476 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
12479 if (!GET_CODE (tmp
) == PLUS
12480 || !REG_P (XEXP (tmp
, 0))
12481 || !REG_P (XEXP (tmp
, 1)))
12483 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
12487 if (REGNO (XEXP (tmp
, 0)) == 0)
12488 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
12489 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
12491 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
12492 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
12498 if (GET_CODE (x
) == REG
)
12499 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
12500 else if (GET_CODE (x
) == MEM
)
12502 /* We need to handle PRE_INC and PRE_DEC here, since we need to
12503 know the width from the mode. */
12504 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
12505 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
12506 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
12507 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12508 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
12509 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
12510 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12511 output_address (XEXP (XEXP (x
, 0), 1));
12513 output_address (XEXP (x
, 0));
12516 output_addr_const (file
, x
);
12520 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
12524 output_operand_lossage ("invalid %%xn code");
12528 /* Print the address of an operand. */
12531 print_operand_address (FILE *file
, rtx x
)
12533 if (GET_CODE (x
) == REG
)
12534 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
12535 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
12536 || GET_CODE (x
) == LABEL_REF
)
12538 output_addr_const (file
, x
);
12539 if (small_data_operand (x
, GET_MODE (x
)))
12540 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12541 reg_names
[SMALL_DATA_REG
]);
12543 gcc_assert (!TARGET_TOC
);
12545 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
12547 gcc_assert (REG_P (XEXP (x
, 0)));
12548 if (REGNO (XEXP (x
, 0)) == 0)
12549 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
12550 reg_names
[ REGNO (XEXP (x
, 0)) ]);
12552 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
12553 reg_names
[ REGNO (XEXP (x
, 1)) ]);
12555 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
12556 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
12557 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
12559 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
12560 && CONSTANT_P (XEXP (x
, 1)))
12562 output_addr_const (file
, XEXP (x
, 1));
12563 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
12567 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
12568 && CONSTANT_P (XEXP (x
, 1)))
12570 fprintf (file
, "lo16(");
12571 output_addr_const (file
, XEXP (x
, 1));
12572 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
12575 else if (legitimate_constant_pool_address_p (x
))
12577 if (TARGET_AIX
&& (!TARGET_ELF
|| !TARGET_MINIMAL_TOC
))
12579 rtx contains_minus
= XEXP (x
, 1);
12583 /* Find the (minus (sym) (toc)) buried in X, and temporarily
12584 turn it into (sym) for output_addr_const. */
12585 while (GET_CODE (XEXP (contains_minus
, 0)) != MINUS
)
12586 contains_minus
= XEXP (contains_minus
, 0);
12588 minus
= XEXP (contains_minus
, 0);
12589 symref
= XEXP (minus
, 0);
12590 gcc_assert (GET_CODE (XEXP (minus
, 1)) == SYMBOL_REF
);
12591 XEXP (contains_minus
, 0) = symref
;
12596 name
= XSTR (symref
, 0);
12597 newname
= XALLOCAVEC (char, strlen (name
) + sizeof ("@toc"));
12598 strcpy (newname
, name
);
12599 strcat (newname
, "@toc");
12600 XSTR (symref
, 0) = newname
;
12602 output_addr_const (file
, XEXP (x
, 1));
12604 XSTR (symref
, 0) = name
;
12605 XEXP (contains_minus
, 0) = minus
;
12608 output_addr_const (file
, XEXP (x
, 1));
12610 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
12613 gcc_unreachable ();
12616 /* Target hook for assembling integer objects. The PowerPC version has
12617 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
12618 is defined. It also needs to handle DI-mode objects on 64-bit
12622 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
12624 #ifdef RELOCATABLE_NEEDS_FIXUP
12625 /* Special handling for SI values. */
12626 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
12628 static int recurse
= 0;
12630 /* For -mrelocatable, we mark all addresses that need to be fixed up
12631 in the .fixup section. */
12632 if (TARGET_RELOCATABLE
12633 && in_section
!= toc_section
12634 && in_section
!= text_section
12635 && !unlikely_text_section_p (in_section
)
12637 && GET_CODE (x
) != CONST_INT
12638 && GET_CODE (x
) != CONST_DOUBLE
12644 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
12646 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
12647 fprintf (asm_out_file
, "\t.long\t(");
12648 output_addr_const (asm_out_file
, x
);
12649 fprintf (asm_out_file
, ")@fixup\n");
12650 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
12651 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
12652 fprintf (asm_out_file
, "\t.long\t");
12653 assemble_name (asm_out_file
, buf
);
12654 fprintf (asm_out_file
, "\n\t.previous\n");
12658 /* Remove initial .'s to turn a -mcall-aixdesc function
12659 address into the address of the descriptor, not the function
12661 else if (GET_CODE (x
) == SYMBOL_REF
12662 && XSTR (x
, 0)[0] == '.'
12663 && DEFAULT_ABI
== ABI_AIX
)
12665 const char *name
= XSTR (x
, 0);
12666 while (*name
== '.')
12669 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
12673 #endif /* RELOCATABLE_NEEDS_FIXUP */
12674 return default_assemble_integer (x
, size
, aligned_p
);
12677 #ifdef HAVE_GAS_HIDDEN
12678 /* Emit an assembler directive to set symbol visibility for DECL to
12679 VISIBILITY_TYPE. */
12682 rs6000_assemble_visibility (tree decl
, int vis
)
12684 /* Functions need to have their entry point symbol visibility set as
12685 well as their descriptor symbol visibility. */
12686 if (DEFAULT_ABI
== ABI_AIX
12688 && TREE_CODE (decl
) == FUNCTION_DECL
)
12690 static const char * const visibility_types
[] = {
12691 NULL
, "internal", "hidden", "protected"
12694 const char *name
, *type
;
12696 name
= ((* targetm
.strip_name_encoding
)
12697 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
12698 type
= visibility_types
[vis
];
12700 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
12701 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
12704 default_assemble_visibility (decl
, vis
);
12709 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
12711 /* Reversal of FP compares takes care -- an ordered compare
12712 becomes an unordered compare and vice versa. */
12713 if (mode
== CCFPmode
12714 && (!flag_finite_math_only
12715 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
12716 || code
== UNEQ
|| code
== LTGT
))
12717 return reverse_condition_maybe_unordered (code
);
12719 return reverse_condition (code
);
12722 /* Generate a compare for CODE. Return a brand-new rtx that
12723 represents the result of the compare. */
12726 rs6000_generate_compare (enum rtx_code code
)
12728 enum machine_mode comp_mode
;
12729 rtx compare_result
;
12731 if (rs6000_compare_fp_p
)
12732 comp_mode
= CCFPmode
;
12733 else if (code
== GTU
|| code
== LTU
12734 || code
== GEU
|| code
== LEU
)
12735 comp_mode
= CCUNSmode
;
12736 else if ((code
== EQ
|| code
== NE
)
12737 && GET_CODE (rs6000_compare_op0
) == SUBREG
12738 && GET_CODE (rs6000_compare_op1
) == SUBREG
12739 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0
)
12740 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1
))
12741 /* These are unsigned values, perhaps there will be a later
12742 ordering compare that can be shared with this one.
12743 Unfortunately we cannot detect the signedness of the operands
12744 for non-subregs. */
12745 comp_mode
= CCUNSmode
;
12747 comp_mode
= CCmode
;
12749 /* First, the compare. */
12750 compare_result
= gen_reg_rtx (comp_mode
);
12752 /* E500 FP compare instructions on the GPRs. Yuck! */
12753 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
)
12754 && rs6000_compare_fp_p
)
12756 rtx cmp
, or_result
, compare_result2
;
12757 enum machine_mode op_mode
= GET_MODE (rs6000_compare_op0
);
12759 if (op_mode
== VOIDmode
)
12760 op_mode
= GET_MODE (rs6000_compare_op1
);
12762 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
12763 This explains the following mess. */
12767 case EQ
: case UNEQ
: case NE
: case LTGT
:
12771 cmp
= flag_unsafe_math_optimizations
12772 ? gen_tstsfeq_gpr (compare_result
, rs6000_compare_op0
,
12773 rs6000_compare_op1
)
12774 : gen_cmpsfeq_gpr (compare_result
, rs6000_compare_op0
,
12775 rs6000_compare_op1
);
12779 cmp
= flag_unsafe_math_optimizations
12780 ? gen_tstdfeq_gpr (compare_result
, rs6000_compare_op0
,
12781 rs6000_compare_op1
)
12782 : gen_cmpdfeq_gpr (compare_result
, rs6000_compare_op0
,
12783 rs6000_compare_op1
);
12787 cmp
= flag_unsafe_math_optimizations
12788 ? gen_tsttfeq_gpr (compare_result
, rs6000_compare_op0
,
12789 rs6000_compare_op1
)
12790 : gen_cmptfeq_gpr (compare_result
, rs6000_compare_op0
,
12791 rs6000_compare_op1
);
12795 gcc_unreachable ();
12799 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
12803 cmp
= flag_unsafe_math_optimizations
12804 ? gen_tstsfgt_gpr (compare_result
, rs6000_compare_op0
,
12805 rs6000_compare_op1
)
12806 : gen_cmpsfgt_gpr (compare_result
, rs6000_compare_op0
,
12807 rs6000_compare_op1
);
12811 cmp
= flag_unsafe_math_optimizations
12812 ? gen_tstdfgt_gpr (compare_result
, rs6000_compare_op0
,
12813 rs6000_compare_op1
)
12814 : gen_cmpdfgt_gpr (compare_result
, rs6000_compare_op0
,
12815 rs6000_compare_op1
);
12819 cmp
= flag_unsafe_math_optimizations
12820 ? gen_tsttfgt_gpr (compare_result
, rs6000_compare_op0
,
12821 rs6000_compare_op1
)
12822 : gen_cmptfgt_gpr (compare_result
, rs6000_compare_op0
,
12823 rs6000_compare_op1
);
12827 gcc_unreachable ();
12831 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
12835 cmp
= flag_unsafe_math_optimizations
12836 ? gen_tstsflt_gpr (compare_result
, rs6000_compare_op0
,
12837 rs6000_compare_op1
)
12838 : gen_cmpsflt_gpr (compare_result
, rs6000_compare_op0
,
12839 rs6000_compare_op1
);
12843 cmp
= flag_unsafe_math_optimizations
12844 ? gen_tstdflt_gpr (compare_result
, rs6000_compare_op0
,
12845 rs6000_compare_op1
)
12846 : gen_cmpdflt_gpr (compare_result
, rs6000_compare_op0
,
12847 rs6000_compare_op1
);
12851 cmp
= flag_unsafe_math_optimizations
12852 ? gen_tsttflt_gpr (compare_result
, rs6000_compare_op0
,
12853 rs6000_compare_op1
)
12854 : gen_cmptflt_gpr (compare_result
, rs6000_compare_op0
,
12855 rs6000_compare_op1
);
12859 gcc_unreachable ();
12863 gcc_unreachable ();
12866 /* Synthesize LE and GE from LT/GT || EQ. */
12867 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
12873 case LE
: code
= LT
; break;
12874 case GE
: code
= GT
; break;
12875 case LEU
: code
= LT
; break;
12876 case GEU
: code
= GT
; break;
12877 default: gcc_unreachable ();
12880 compare_result2
= gen_reg_rtx (CCFPmode
);
12886 cmp
= flag_unsafe_math_optimizations
12887 ? gen_tstsfeq_gpr (compare_result2
, rs6000_compare_op0
,
12888 rs6000_compare_op1
)
12889 : gen_cmpsfeq_gpr (compare_result2
, rs6000_compare_op0
,
12890 rs6000_compare_op1
);
12894 cmp
= flag_unsafe_math_optimizations
12895 ? gen_tstdfeq_gpr (compare_result2
, rs6000_compare_op0
,
12896 rs6000_compare_op1
)
12897 : gen_cmpdfeq_gpr (compare_result2
, rs6000_compare_op0
,
12898 rs6000_compare_op1
);
12902 cmp
= flag_unsafe_math_optimizations
12903 ? gen_tsttfeq_gpr (compare_result2
, rs6000_compare_op0
,
12904 rs6000_compare_op1
)
12905 : gen_cmptfeq_gpr (compare_result2
, rs6000_compare_op0
,
12906 rs6000_compare_op1
);
12910 gcc_unreachable ();
12914 /* OR them together. */
12915 or_result
= gen_reg_rtx (CCFPmode
);
12916 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
12918 compare_result
= or_result
;
12923 if (code
== NE
|| code
== LTGT
)
12933 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
12934 CLOBBERs to match cmptf_internal2 pattern. */
12935 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
12936 && GET_MODE (rs6000_compare_op0
) == TFmode
12937 && !TARGET_IEEEQUAD
12938 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
12939 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
12941 gen_rtx_SET (VOIDmode
,
12943 gen_rtx_COMPARE (comp_mode
,
12944 rs6000_compare_op0
,
12945 rs6000_compare_op1
)),
12946 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12947 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12948 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12949 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12950 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12951 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12952 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12953 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)))));
12954 else if (GET_CODE (rs6000_compare_op1
) == UNSPEC
12955 && XINT (rs6000_compare_op1
, 1) == UNSPEC_SP_TEST
)
12957 rtx op1
= XVECEXP (rs6000_compare_op1
, 0, 0);
12958 comp_mode
= CCEQmode
;
12959 compare_result
= gen_reg_rtx (CCEQmode
);
12961 emit_insn (gen_stack_protect_testdi (compare_result
,
12962 rs6000_compare_op0
, op1
));
12964 emit_insn (gen_stack_protect_testsi (compare_result
,
12965 rs6000_compare_op0
, op1
));
12968 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
12969 gen_rtx_COMPARE (comp_mode
,
12970 rs6000_compare_op0
,
12971 rs6000_compare_op1
)));
12974 /* Some kinds of FP comparisons need an OR operation;
12975 under flag_finite_math_only we don't bother. */
12976 if (rs6000_compare_fp_p
12977 && !flag_finite_math_only
12978 && !(TARGET_HARD_FLOAT
&& !TARGET_FPRS
)
12979 && (code
== LE
|| code
== GE
12980 || code
== UNEQ
|| code
== LTGT
12981 || code
== UNGT
|| code
== UNLT
))
12983 enum rtx_code or1
, or2
;
12984 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
12985 rtx or_result
= gen_reg_rtx (CCEQmode
);
12989 case LE
: or1
= LT
; or2
= EQ
; break;
12990 case GE
: or1
= GT
; or2
= EQ
; break;
12991 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
12992 case LTGT
: or1
= LT
; or2
= GT
; break;
12993 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
12994 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
12995 default: gcc_unreachable ();
12997 validate_condition_mode (or1
, comp_mode
);
12998 validate_condition_mode (or2
, comp_mode
);
12999 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
13000 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
13001 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
13002 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
13004 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
13006 compare_result
= or_result
;
13010 validate_condition_mode (code
, GET_MODE (compare_result
));
13012 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
13016 /* Emit the RTL for an sCOND pattern. */
13019 rs6000_emit_sCOND (enum rtx_code code
, rtx result
)
13022 enum machine_mode op_mode
;
13023 enum rtx_code cond_code
;
13025 condition_rtx
= rs6000_generate_compare (code
);
13026 cond_code
= GET_CODE (condition_rtx
);
13028 if (rs6000_compare_fp_p
13029 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
13033 PUT_MODE (condition_rtx
, SImode
);
13034 t
= XEXP (condition_rtx
, 0);
13036 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
13038 if (cond_code
== NE
)
13039 emit_insn (gen_e500_flip_gt_bit (t
, t
));
13041 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
13045 if (cond_code
== NE
13046 || cond_code
== GE
|| cond_code
== LE
13047 || cond_code
== GEU
|| cond_code
== LEU
13048 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
13050 rtx not_result
= gen_reg_rtx (CCEQmode
);
13051 rtx not_op
, rev_cond_rtx
;
13052 enum machine_mode cc_mode
;
13054 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
13056 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
13057 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
13058 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
13059 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
13060 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
13063 op_mode
= GET_MODE (rs6000_compare_op0
);
13064 if (op_mode
== VOIDmode
)
13065 op_mode
= GET_MODE (rs6000_compare_op1
);
13067 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| rs6000_compare_fp_p
))
13069 PUT_MODE (condition_rtx
, DImode
);
13070 convert_move (result
, condition_rtx
, 0);
13074 PUT_MODE (condition_rtx
, SImode
);
13075 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
13079 /* Emit a branch of kind CODE to location LOC. */
13082 rs6000_emit_cbranch (enum rtx_code code
, rtx loc
)
13084 rtx condition_rtx
, loc_ref
;
13086 condition_rtx
= rs6000_generate_compare (code
);
13087 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, loc
);
13088 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
13089 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
13090 loc_ref
, pc_rtx
)));
13093 /* Return the string to output a conditional branch to LABEL, which is
13094 the operand number of the label, or -1 if the branch is really a
13095 conditional return.
13097 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
13098 condition code register and its mode specifies what kind of
13099 comparison we made.
13101 REVERSED is nonzero if we should reverse the sense of the comparison.
13103 INSN is the insn. */
13106 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
13108 static char string
[64];
13109 enum rtx_code code
= GET_CODE (op
);
13110 rtx cc_reg
= XEXP (op
, 0);
13111 enum machine_mode mode
= GET_MODE (cc_reg
);
13112 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
13113 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
13114 int really_reversed
= reversed
^ need_longbranch
;
13120 validate_condition_mode (code
, mode
);
13122 /* Work out which way this really branches. We could use
13123 reverse_condition_maybe_unordered here always but this
13124 makes the resulting assembler clearer. */
13125 if (really_reversed
)
13127 /* Reversal of FP compares takes care -- an ordered compare
13128 becomes an unordered compare and vice versa. */
13129 if (mode
== CCFPmode
)
13130 code
= reverse_condition_maybe_unordered (code
);
13132 code
= reverse_condition (code
);
13135 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
13137 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
13142 /* Opposite of GT. */
13151 gcc_unreachable ();
13157 /* Not all of these are actually distinct opcodes, but
13158 we distinguish them for clarity of the resulting assembler. */
13159 case NE
: case LTGT
:
13160 ccode
= "ne"; break;
13161 case EQ
: case UNEQ
:
13162 ccode
= "eq"; break;
13164 ccode
= "ge"; break;
13165 case GT
: case GTU
: case UNGT
:
13166 ccode
= "gt"; break;
13168 ccode
= "le"; break;
13169 case LT
: case LTU
: case UNLT
:
13170 ccode
= "lt"; break;
13171 case UNORDERED
: ccode
= "un"; break;
13172 case ORDERED
: ccode
= "nu"; break;
13173 case UNGE
: ccode
= "nl"; break;
13174 case UNLE
: ccode
= "ng"; break;
13176 gcc_unreachable ();
13179 /* Maybe we have a guess as to how likely the branch is.
13180 The old mnemonics don't have a way to specify this information. */
13182 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
13183 if (note
!= NULL_RTX
)
13185 /* PROB is the difference from 50%. */
13186 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
13188 /* Only hint for highly probable/improbable branches on newer
13189 cpus as static prediction overrides processor dynamic
13190 prediction. For older cpus we may as well always hint, but
13191 assume not taken for branches that are very close to 50% as a
13192 mispredicted taken branch is more expensive than a
13193 mispredicted not-taken branch. */
13194 if (rs6000_always_hint
13195 || (abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48
13196 && br_prob_note_reliable_p (note
)))
13198 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
13199 && ((prob
> 0) ^ need_longbranch
))
13207 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
13209 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
13211 /* We need to escape any '%' characters in the reg_names string.
13212 Assume they'd only be the first character.... */
13213 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
13215 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
13219 /* If the branch distance was too far, we may have to use an
13220 unconditional branch to go the distance. */
13221 if (need_longbranch
)
13222 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
13224 s
+= sprintf (s
, ",%s", label
);
13230 /* Return the string to flip the GT bit on a CR. */
13232 output_e500_flip_gt_bit (rtx dst
, rtx src
)
13234 static char string
[64];
13237 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
13238 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
13241 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
13242 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
13244 sprintf (string
, "crnot %d,%d", a
, b
);
13248 /* Return insn index for the vector compare instruction for given CODE,
13249 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
13253 get_vec_cmp_insn (enum rtx_code code
,
13254 enum machine_mode dest_mode
,
13255 enum machine_mode op_mode
)
13257 if (!TARGET_ALTIVEC
)
13258 return INSN_NOT_AVAILABLE
;
13263 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
13264 return UNSPEC_VCMPEQUB
;
13265 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
13266 return UNSPEC_VCMPEQUH
;
13267 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
13268 return UNSPEC_VCMPEQUW
;
13269 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
13270 return UNSPEC_VCMPEQFP
;
13273 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
13274 return UNSPEC_VCMPGEFP
;
13276 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
13277 return UNSPEC_VCMPGTSB
;
13278 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
13279 return UNSPEC_VCMPGTSH
;
13280 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
13281 return UNSPEC_VCMPGTSW
;
13282 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
13283 return UNSPEC_VCMPGTFP
;
13286 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
13287 return UNSPEC_VCMPGTUB
;
13288 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
13289 return UNSPEC_VCMPGTUH
;
13290 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
13291 return UNSPEC_VCMPGTUW
;
13296 return INSN_NOT_AVAILABLE
;
13299 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
13300 DMODE is expected destination mode. This is a recursive function. */
13303 rs6000_emit_vector_compare (enum rtx_code rcode
,
13305 enum machine_mode dmode
)
13309 enum machine_mode dest_mode
;
13310 enum machine_mode op_mode
= GET_MODE (op1
);
13312 gcc_assert (TARGET_ALTIVEC
);
13313 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
13315 /* Floating point vector compare instructions uses destination V4SImode.
13316 Move destination to appropriate mode later. */
13317 if (dmode
== V4SFmode
)
13318 dest_mode
= V4SImode
;
13322 mask
= gen_reg_rtx (dest_mode
);
13323 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
13325 if (vec_cmp_insn
== INSN_NOT_AVAILABLE
)
13327 bool swap_operands
= false;
13328 bool try_again
= false;
13333 swap_operands
= true;
13338 swap_operands
= true;
13346 /* Invert condition and try again.
13347 e.g., A != B becomes ~(A==B). */
13349 enum rtx_code rev_code
;
13350 enum insn_code nor_code
;
13353 rev_code
= reverse_condition_maybe_unordered (rcode
);
13354 eq_rtx
= rs6000_emit_vector_compare (rev_code
, op0
, op1
,
13357 nor_code
= optab_handler (one_cmpl_optab
, (int)dest_mode
)->insn_code
;
13358 gcc_assert (nor_code
!= CODE_FOR_nothing
);
13359 emit_insn (GEN_FCN (nor_code
) (mask
, eq_rtx
));
13361 if (dmode
!= dest_mode
)
13363 rtx temp
= gen_reg_rtx (dest_mode
);
13364 convert_move (temp
, mask
, 0);
13374 /* Try GT/GTU/LT/LTU OR EQ */
13377 enum insn_code ior_code
;
13378 enum rtx_code new_code
;
13399 gcc_unreachable ();
13402 c_rtx
= rs6000_emit_vector_compare (new_code
,
13403 op0
, op1
, dest_mode
);
13404 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
,
13407 ior_code
= optab_handler (ior_optab
, (int)dest_mode
)->insn_code
;
13408 gcc_assert (ior_code
!= CODE_FOR_nothing
);
13409 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
13410 if (dmode
!= dest_mode
)
13412 rtx temp
= gen_reg_rtx (dest_mode
);
13413 convert_move (temp
, mask
, 0);
13420 gcc_unreachable ();
13425 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
13426 /* You only get two chances. */
13427 gcc_assert (vec_cmp_insn
!= INSN_NOT_AVAILABLE
);
13439 emit_insn (gen_rtx_SET (VOIDmode
, mask
,
13440 gen_rtx_UNSPEC (dest_mode
,
13441 gen_rtvec (2, op0
, op1
),
13443 if (dmode
!= dest_mode
)
13445 rtx temp
= gen_reg_rtx (dest_mode
);
13446 convert_move (temp
, mask
, 0);
13452 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
13453 valid insn doesn exist for given mode. */
13456 get_vsel_insn (enum machine_mode mode
)
13461 return UNSPEC_VSEL4SI
;
13464 return UNSPEC_VSEL4SF
;
13467 return UNSPEC_VSEL8HI
;
13470 return UNSPEC_VSEL16QI
;
13473 return INSN_NOT_AVAILABLE
;
13476 return INSN_NOT_AVAILABLE
;
13479 /* Emit vector select insn where DEST is destination using
13480 operands OP1, OP2 and MASK. */
13483 rs6000_emit_vector_select (rtx dest
, rtx op1
, rtx op2
, rtx mask
)
13486 enum machine_mode dest_mode
= GET_MODE (dest
);
13487 int vsel_insn_index
= get_vsel_insn (GET_MODE (dest
));
13489 temp
= gen_reg_rtx (dest_mode
);
13491 /* For each vector element, select op1 when mask is 1 otherwise
13493 t
= gen_rtx_SET (VOIDmode
, temp
,
13494 gen_rtx_UNSPEC (dest_mode
,
13495 gen_rtvec (3, op2
, op1
, mask
),
13498 emit_move_insn (dest
, temp
);
13502 /* Emit vector conditional expression.
13503 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
13504 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
13507 rs6000_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
13508 rtx cond
, rtx cc_op0
, rtx cc_op1
)
13510 enum machine_mode dest_mode
= GET_MODE (dest
);
13511 enum rtx_code rcode
= GET_CODE (cond
);
13514 if (!TARGET_ALTIVEC
)
13517 /* Get the vector mask for the given relational operations. */
13518 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
13520 rs6000_emit_vector_select (dest
, op1
, op2
, mask
);
13525 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
13526 operands of the last comparison is nonzero/true, FALSE_COND if it
13527 is zero/false. Return 0 if the hardware has no such operation. */
13530 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
13532 enum rtx_code code
= GET_CODE (op
);
13533 rtx op0
= rs6000_compare_op0
;
13534 rtx op1
= rs6000_compare_op1
;
13535 REAL_VALUE_TYPE c1
;
13536 enum machine_mode compare_mode
= GET_MODE (op0
);
13537 enum machine_mode result_mode
= GET_MODE (dest
);
13539 bool is_against_zero
;
13541 /* These modes should always match. */
13542 if (GET_MODE (op1
) != compare_mode
13543 /* In the isel case however, we can use a compare immediate, so
13544 op1 may be a small constant. */
13545 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
13547 if (GET_MODE (true_cond
) != result_mode
)
13549 if (GET_MODE (false_cond
) != result_mode
)
13552 /* First, work out if the hardware can do this at all, or
13553 if it's too slow.... */
13554 if (! rs6000_compare_fp_p
)
13557 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
13560 else if (TARGET_HARD_FLOAT
&& !TARGET_FPRS
13561 && SCALAR_FLOAT_MODE_P (compare_mode
))
13564 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
13566 /* A floating-point subtract might overflow, underflow, or produce
13567 an inexact result, thus changing the floating-point flags, so it
13568 can't be generated if we care about that. It's safe if one side
13569 of the construct is zero, since then no subtract will be
13571 if (SCALAR_FLOAT_MODE_P (compare_mode
)
13572 && flag_trapping_math
&& ! is_against_zero
)
13575 /* Eliminate half of the comparisons by switching operands, this
13576 makes the remaining code simpler. */
13577 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
13578 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
13580 code
= reverse_condition_maybe_unordered (code
);
13582 true_cond
= false_cond
;
13586 /* UNEQ and LTGT take four instructions for a comparison with zero,
13587 it'll probably be faster to use a branch here too. */
13588 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
13591 if (GET_CODE (op1
) == CONST_DOUBLE
)
13592 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
13594 /* We're going to try to implement comparisons by performing
13595 a subtract, then comparing against zero. Unfortunately,
13596 Inf - Inf is NaN which is not zero, and so if we don't
13597 know that the operand is finite and the comparison
13598 would treat EQ different to UNORDERED, we can't do it. */
13599 if (HONOR_INFINITIES (compare_mode
)
13600 && code
!= GT
&& code
!= UNGE
13601 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
13602 /* Constructs of the form (a OP b ? a : b) are safe. */
13603 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
13604 || (! rtx_equal_p (op0
, true_cond
)
13605 && ! rtx_equal_p (op1
, true_cond
))))
13608 /* At this point we know we can use fsel. */
13610 /* Reduce the comparison to a comparison against zero. */
13611 if (! is_against_zero
)
13613 temp
= gen_reg_rtx (compare_mode
);
13614 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13615 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
13617 op1
= CONST0_RTX (compare_mode
);
13620 /* If we don't care about NaNs we can reduce some of the comparisons
13621 down to faster ones. */
13622 if (! HONOR_NANS (compare_mode
))
13628 true_cond
= false_cond
;
13641 /* Now, reduce everything down to a GE. */
13648 temp
= gen_reg_rtx (compare_mode
);
13649 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
13654 temp
= gen_reg_rtx (compare_mode
);
13655 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
13660 temp
= gen_reg_rtx (compare_mode
);
13661 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13662 gen_rtx_NEG (compare_mode
,
13663 gen_rtx_ABS (compare_mode
, op0
))));
13668 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
13669 temp
= gen_reg_rtx (result_mode
);
13670 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13671 gen_rtx_IF_THEN_ELSE (result_mode
,
13672 gen_rtx_GE (VOIDmode
,
13674 true_cond
, false_cond
)));
13675 false_cond
= true_cond
;
13678 temp
= gen_reg_rtx (compare_mode
);
13679 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
13684 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
13685 temp
= gen_reg_rtx (result_mode
);
13686 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13687 gen_rtx_IF_THEN_ELSE (result_mode
,
13688 gen_rtx_GE (VOIDmode
,
13690 true_cond
, false_cond
)));
13691 true_cond
= false_cond
;
13694 temp
= gen_reg_rtx (compare_mode
);
13695 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
13700 gcc_unreachable ();
13703 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
13704 gen_rtx_IF_THEN_ELSE (result_mode
,
13705 gen_rtx_GE (VOIDmode
,
13707 true_cond
, false_cond
)));
13711 /* Same as above, but for ints (isel). */
13714 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
13716 rtx condition_rtx
, cr
;
13718 /* All isel implementations thus far are 32-bits. */
13719 if (GET_MODE (rs6000_compare_op0
) != SImode
)
13722 /* We still have to do the compare, because isel doesn't do a
13723 compare, it just looks at the CRx bits set by a previous compare
13725 condition_rtx
= rs6000_generate_compare (GET_CODE (op
));
13726 cr
= XEXP (condition_rtx
, 0);
13728 if (GET_MODE (cr
) == CCmode
)
13729 emit_insn (gen_isel_signed (dest
, condition_rtx
,
13730 true_cond
, false_cond
, cr
));
13732 emit_insn (gen_isel_unsigned (dest
, condition_rtx
,
13733 true_cond
, false_cond
, cr
));
13739 output_isel (rtx
*operands
)
13741 enum rtx_code code
;
13743 code
= GET_CODE (operands
[1]);
13744 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
13746 PUT_CODE (operands
[1], reverse_condition (code
));
13747 return "isel %0,%3,%2,%j1";
13750 return "isel %0,%2,%3,%j1";
13754 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
13756 enum machine_mode mode
= GET_MODE (op0
);
13760 if (code
== SMAX
|| code
== SMIN
)
13765 if (code
== SMAX
|| code
== UMAX
)
13766 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
13767 op0
, op1
, mode
, 0);
13769 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
13770 op1
, op0
, mode
, 0);
13771 gcc_assert (target
);
13772 if (target
!= dest
)
13773 emit_move_insn (dest
, target
);
13776 /* Emit instructions to perform a load-reserved/store-conditional operation.
13777 The operation performed is an atomic
13778 (set M (CODE:MODE M OP))
13779 If not NULL, BEFORE is atomically set to M before the operation, and
13780 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
13781 If SYNC_P then a memory barrier is emitted before the operation.
13782 Either OP or M may be wrapped in a NOT operation. */
13785 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
13786 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
13789 enum machine_mode used_mode
;
13790 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
13793 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
13794 rtx shift
= NULL_RTX
;
13797 emit_insn (gen_memory_barrier ());
13799 if (GET_CODE (m
) == NOT
)
13800 used_m
= XEXP (m
, 0);
13804 /* If this is smaller than SImode, we'll have to use SImode with
13806 if (mode
== QImode
|| mode
== HImode
)
13810 if (MEM_ALIGN (used_m
) >= 32)
13813 if (BYTES_BIG_ENDIAN
)
13814 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
13816 shift
= GEN_INT (ishift
);
13817 used_m
= change_address (used_m
, SImode
, 0);
13821 rtx addrSI
, aligned_addr
;
13822 int shift_mask
= mode
== QImode
? 0x18 : 0x10;
13824 addrSI
= gen_lowpart_common (SImode
,
13825 force_reg (Pmode
, XEXP (used_m
, 0)));
13826 addrSI
= force_reg (SImode
, addrSI
);
13827 shift
= gen_reg_rtx (SImode
);
13829 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
13830 GEN_INT (shift_mask
)));
13831 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
13833 aligned_addr
= expand_binop (Pmode
, and_optab
,
13835 GEN_INT (-4), NULL_RTX
,
13836 1, OPTAB_LIB_WIDEN
);
13837 used_m
= change_address (used_m
, SImode
, aligned_addr
);
13838 set_mem_align (used_m
, 32);
13840 /* It's safe to keep the old alias set of USED_M, because
13841 the operation is atomic and only affects the original
13843 if (GET_CODE (m
) == NOT
)
13844 m
= gen_rtx_NOT (SImode
, used_m
);
13848 if (GET_CODE (op
) == NOT
)
13850 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
13851 oldop
= gen_rtx_NOT (SImode
, oldop
);
13854 oldop
= lowpart_subreg (SImode
, op
, mode
);
13860 newop
= expand_binop (SImode
, and_optab
,
13861 oldop
, GEN_INT (imask
), NULL_RTX
,
13862 1, OPTAB_LIB_WIDEN
);
13863 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
13867 newop
= expand_binop (SImode
, ior_optab
,
13868 oldop
, GEN_INT (~imask
), NULL_RTX
,
13869 1, OPTAB_LIB_WIDEN
);
13870 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
13878 newop
= expand_binop (SImode
, and_optab
,
13879 oldop
, GEN_INT (imask
), NULL_RTX
,
13880 1, OPTAB_LIB_WIDEN
);
13881 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
13883 mask
= gen_reg_rtx (SImode
);
13884 emit_move_insn (mask
, GEN_INT (imask
));
13885 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
13888 newop
= gen_rtx_PLUS (SImode
, m
, newop
);
13890 newop
= gen_rtx_MINUS (SImode
, m
, newop
);
13891 newop
= gen_rtx_AND (SImode
, newop
, mask
);
13892 newop
= gen_rtx_IOR (SImode
, newop
,
13893 gen_rtx_AND (SImode
,
13894 gen_rtx_NOT (SImode
, mask
),
13900 gcc_unreachable ();
13903 if (GET_CODE (m
) == NOT
)
13907 mask
= gen_reg_rtx (SImode
);
13908 emit_move_insn (mask
, GEN_INT (imask
));
13909 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
13911 xorm
= gen_rtx_XOR (SImode
, used_m
, mask
);
13912 /* Depending on the value of 'op', the XOR or the operation might
13913 be able to be simplified away. */
13914 newop
= simplify_gen_binary (code
, SImode
, xorm
, newop
);
13917 used_mode
= SImode
;
13918 before
= gen_reg_rtx (used_mode
);
13919 after
= gen_reg_rtx (used_mode
);
13924 before
= before_param
;
13925 after
= after_param
;
13927 if (before
== NULL_RTX
)
13928 before
= gen_reg_rtx (used_mode
);
13929 if (after
== NULL_RTX
)
13930 after
= gen_reg_rtx (used_mode
);
13933 if ((code
== PLUS
|| code
== MINUS
|| GET_CODE (m
) == NOT
)
13934 && used_mode
!= mode
)
13935 the_op
= op
; /* Computed above. */
13936 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
13937 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
13939 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
13941 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
13942 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
13943 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
13944 gen_rtx_UNSPEC (used_mode
,
13945 gen_rtvec (1, the_op
),
13947 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
13949 if ((code
== PLUS
|| code
== MINUS
) && used_mode
!= mode
)
13950 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
13951 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
13953 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
13954 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
13956 /* Shift and mask the return values properly. */
13957 if (used_mode
!= mode
&& before_param
)
13959 emit_insn (gen_lshrsi3 (before
, before
, shift
));
13960 convert_move (before_param
, before
, 1);
13963 if (used_mode
!= mode
&& after_param
)
13965 emit_insn (gen_lshrsi3 (after
, after
, shift
));
13966 convert_move (after_param
, after
, 1);
13969 /* The previous sequence will end with a branch that's dependent on
13970 the conditional store, so placing an isync will ensure that no
13971 other instructions (especially, no load or store instructions)
13972 can start before the atomic operation completes. */
13974 emit_insn (gen_isync ());
13977 /* A subroutine of the atomic operation splitters. Jump to LABEL if
13978 COND is true. Mark the jump as unlikely to be taken. */
13981 emit_unlikely_jump (rtx cond
, rtx label
)
13983 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
13986 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
13987 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
13988 REG_NOTES (x
) = gen_rtx_EXPR_LIST (REG_BR_PROB
, very_unlikely
, NULL_RTX
);
13991 /* A subroutine of the atomic operation splitters. Emit a load-locked
13992 instruction in MODE. */
13995 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
13997 rtx (*fn
) (rtx
, rtx
) = NULL
;
13998 if (mode
== SImode
)
13999 fn
= gen_load_locked_si
;
14000 else if (mode
== DImode
)
14001 fn
= gen_load_locked_di
;
14002 emit_insn (fn (reg
, mem
));
14005 /* A subroutine of the atomic operation splitters. Emit a store-conditional
14006 instruction in MODE. */
14009 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
14011 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
14012 if (mode
== SImode
)
14013 fn
= gen_store_conditional_si
;
14014 else if (mode
== DImode
)
14015 fn
= gen_store_conditional_di
;
14017 /* Emit sync before stwcx. to address PPC405 Erratum. */
14018 if (PPC405_ERRATUM77
)
14019 emit_insn (gen_memory_barrier ());
14021 emit_insn (fn (res
, mem
, val
));
14024 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
14025 to perform. MEM is the memory on which to operate. VAL is the second
14026 operand of the binary operator. BEFORE and AFTER are optional locations to
14027 return the value of MEM either before of after the operation. SCRATCH is
14028 a scratch register. */
14031 rs6000_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
14032 rtx before
, rtx after
, rtx scratch
)
14034 enum machine_mode mode
= GET_MODE (mem
);
14035 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
14037 emit_insn (gen_memory_barrier ());
14039 label
= gen_label_rtx ();
14040 emit_label (label
);
14041 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
14043 if (before
== NULL_RTX
)
14045 emit_load_locked (mode
, before
, mem
);
14048 x
= gen_rtx_AND (mode
, gen_rtx_NOT (mode
, before
), val
);
14049 else if (code
== AND
)
14050 x
= gen_rtx_UNSPEC (mode
, gen_rtvec (2, before
, val
), UNSPEC_AND
);
14052 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
14054 if (after
!= NULL_RTX
)
14055 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
14056 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
14058 emit_store_conditional (mode
, cond
, mem
, scratch
);
14060 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14061 emit_unlikely_jump (x
, label
);
14063 emit_insn (gen_isync ());
14066 /* Expand an atomic compare and swap operation. MEM is the memory on which
14067 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
14068 value to be stored. SCRATCH is a scratch GPR. */
14071 rs6000_split_compare_and_swap (rtx retval
, rtx mem
, rtx oldval
, rtx newval
,
14074 enum machine_mode mode
= GET_MODE (mem
);
14075 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
14077 emit_insn (gen_memory_barrier ());
14079 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
14080 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
14081 emit_label (XEXP (label1
, 0));
14083 emit_load_locked (mode
, retval
, mem
);
14085 x
= gen_rtx_COMPARE (CCmode
, retval
, oldval
);
14086 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
14088 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14089 emit_unlikely_jump (x
, label2
);
14091 emit_move_insn (scratch
, newval
);
14092 emit_store_conditional (mode
, cond
, mem
, scratch
);
14094 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14095 emit_unlikely_jump (x
, label1
);
14097 emit_insn (gen_isync ());
14098 emit_label (XEXP (label2
, 0));
14101 /* Expand an atomic test and set operation. MEM is the memory on which
14102 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
14105 rs6000_split_lock_test_and_set (rtx retval
, rtx mem
, rtx val
, rtx scratch
)
14107 enum machine_mode mode
= GET_MODE (mem
);
14108 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
14110 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
14111 emit_label (XEXP (label
, 0));
14113 emit_load_locked (mode
, retval
, mem
);
14114 emit_move_insn (scratch
, val
);
14115 emit_store_conditional (mode
, cond
, mem
, scratch
);
14117 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14118 emit_unlikely_jump (x
, label
);
14120 emit_insn (gen_isync ());
14124 rs6000_expand_compare_and_swapqhi (rtx dst
, rtx mem
, rtx oldval
, rtx newval
)
14126 enum machine_mode mode
= GET_MODE (mem
);
14127 rtx addrSI
, align
, wdst
, shift
, mask
;
14128 HOST_WIDE_INT shift_mask
= mode
== QImode
? 0x18 : 0x10;
14129 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
14131 /* Shift amount for subword relative to aligned word. */
14132 addrSI
= force_reg (GET_MODE (XEXP (mem
, 0)), XEXP (mem
, 0));
14133 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
, addrSI
));
14134 shift
= gen_reg_rtx (SImode
);
14135 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
14136 GEN_INT (shift_mask
)));
14137 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
14139 /* Shift and mask old value into position within word. */
14140 oldval
= convert_modes (SImode
, mode
, oldval
, 1);
14141 oldval
= expand_binop (SImode
, and_optab
,
14142 oldval
, GEN_INT (imask
), NULL_RTX
,
14143 1, OPTAB_LIB_WIDEN
);
14144 emit_insn (gen_ashlsi3 (oldval
, oldval
, shift
));
14146 /* Shift and mask new value into position within word. */
14147 newval
= convert_modes (SImode
, mode
, newval
, 1);
14148 newval
= expand_binop (SImode
, and_optab
,
14149 newval
, GEN_INT (imask
), NULL_RTX
,
14150 1, OPTAB_LIB_WIDEN
);
14151 emit_insn (gen_ashlsi3 (newval
, newval
, shift
));
14153 /* Mask for insertion. */
14154 mask
= gen_reg_rtx (SImode
);
14155 emit_move_insn (mask
, GEN_INT (imask
));
14156 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
14158 /* Address of aligned word containing subword. */
14159 align
= expand_binop (Pmode
, and_optab
, XEXP (mem
, 0), GEN_INT (-4),
14160 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
14161 mem
= change_address (mem
, SImode
, align
);
14162 set_mem_align (mem
, 32);
14163 MEM_VOLATILE_P (mem
) = 1;
14165 wdst
= gen_reg_rtx (SImode
);
14166 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst
, mask
,
14167 oldval
, newval
, mem
));
14169 /* Shift the result back. */
14170 emit_insn (gen_lshrsi3 (wdst
, wdst
, shift
));
14172 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
14176 rs6000_split_compare_and_swapqhi (rtx dest
, rtx mask
,
14177 rtx oldval
, rtx newval
, rtx mem
,
14180 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
14182 emit_insn (gen_memory_barrier ());
14183 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
14184 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
14185 emit_label (XEXP (label1
, 0));
14187 emit_load_locked (SImode
, scratch
, mem
);
14189 /* Mask subword within loaded value for comparison with oldval.
14190 Use UNSPEC_AND to avoid clobber.*/
14191 emit_insn (gen_rtx_SET (SImode
, dest
,
14192 gen_rtx_UNSPEC (SImode
,
14193 gen_rtvec (2, scratch
, mask
),
14196 x
= gen_rtx_COMPARE (CCmode
, dest
, oldval
);
14197 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
14199 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14200 emit_unlikely_jump (x
, label2
);
14202 /* Clear subword within loaded value for insertion of new value. */
14203 emit_insn (gen_rtx_SET (SImode
, scratch
,
14204 gen_rtx_AND (SImode
,
14205 gen_rtx_NOT (SImode
, mask
), scratch
)));
14206 emit_insn (gen_iorsi3 (scratch
, scratch
, newval
));
14207 emit_store_conditional (SImode
, cond
, mem
, scratch
);
14209 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
14210 emit_unlikely_jump (x
, label1
);
14212 emit_insn (gen_isync ());
14213 emit_label (XEXP (label2
, 0));
14217 /* Emit instructions to move SRC to DST. Called by splitters for
14218 multi-register moves. It will emit at most one instruction for
14219 each register that is accessed; that is, it won't emit li/lis pairs
14220 (or equivalent for 64-bit code). One of SRC or DST must be a hard
14224 rs6000_split_multireg_move (rtx dst
, rtx src
)
14226 /* The register number of the first register being moved. */
14228 /* The mode that is to be moved. */
14229 enum machine_mode mode
;
14230 /* The mode that the move is being done in, and its size. */
14231 enum machine_mode reg_mode
;
14233 /* The number of registers that will be moved. */
14236 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
14237 mode
= GET_MODE (dst
);
14238 nregs
= hard_regno_nregs
[reg
][mode
];
14239 if (FP_REGNO_P (reg
))
14240 reg_mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
:
14241 ((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
) ? DFmode
: SFmode
);
14242 else if (ALTIVEC_REGNO_P (reg
))
14243 reg_mode
= V16QImode
;
14244 else if (TARGET_E500_DOUBLE
&& mode
== TFmode
)
14247 reg_mode
= word_mode
;
14248 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
14250 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
14252 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
14254 /* Move register range backwards, if we might have destructive
14257 for (i
= nregs
- 1; i
>= 0; i
--)
14258 emit_insn (gen_rtx_SET (VOIDmode
,
14259 simplify_gen_subreg (reg_mode
, dst
, mode
,
14260 i
* reg_mode_size
),
14261 simplify_gen_subreg (reg_mode
, src
, mode
,
14262 i
* reg_mode_size
)));
14268 bool used_update
= false;
14270 if (MEM_P (src
) && INT_REGNO_P (reg
))
14274 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
14275 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
14278 breg
= XEXP (XEXP (src
, 0), 0);
14279 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
14280 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
14281 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
14282 emit_insn (TARGET_32BIT
14283 ? gen_addsi3 (breg
, breg
, delta_rtx
)
14284 : gen_adddi3 (breg
, breg
, delta_rtx
));
14285 src
= replace_equiv_address (src
, breg
);
14287 else if (! rs6000_offsettable_memref_p (src
))
14290 basereg
= gen_rtx_REG (Pmode
, reg
);
14291 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
14292 src
= replace_equiv_address (src
, basereg
);
14295 breg
= XEXP (src
, 0);
14296 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
14297 breg
= XEXP (breg
, 0);
14299 /* If the base register we are using to address memory is
14300 also a destination reg, then change that register last. */
14302 && REGNO (breg
) >= REGNO (dst
)
14303 && REGNO (breg
) < REGNO (dst
) + nregs
)
14304 j
= REGNO (breg
) - REGNO (dst
);
14307 if (GET_CODE (dst
) == MEM
&& INT_REGNO_P (reg
))
14311 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
14312 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
14315 breg
= XEXP (XEXP (dst
, 0), 0);
14316 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
14317 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
14318 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
14320 /* We have to update the breg before doing the store.
14321 Use store with update, if available. */
14325 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
14326 emit_insn (TARGET_32BIT
14327 ? (TARGET_POWERPC64
14328 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
14329 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
14330 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
14331 used_update
= true;
14334 emit_insn (TARGET_32BIT
14335 ? gen_addsi3 (breg
, breg
, delta_rtx
)
14336 : gen_adddi3 (breg
, breg
, delta_rtx
));
14337 dst
= replace_equiv_address (dst
, breg
);
14340 gcc_assert (rs6000_offsettable_memref_p (dst
));
14343 for (i
= 0; i
< nregs
; i
++)
14345 /* Calculate index to next subword. */
14350 /* If compiler already emitted move of first word by
14351 store with update, no need to do anything. */
14352 if (j
== 0 && used_update
)
14355 emit_insn (gen_rtx_SET (VOIDmode
,
14356 simplify_gen_subreg (reg_mode
, dst
, mode
,
14357 j
* reg_mode_size
),
14358 simplify_gen_subreg (reg_mode
, src
, mode
,
14359 j
* reg_mode_size
)));
14365 /* This page contains routines that are used to determine what the
14366 function prologue and epilogue code will do and write them out. */
14368 /* Return the first fixed-point register that is required to be
14369 saved. 32 if none. */
14372 first_reg_to_save (void)
14376 /* Find lowest numbered live register. */
14377 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
14378 if (df_regs_ever_live_p (first_reg
)
14379 && (! call_used_regs
[first_reg
]
14380 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
14381 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
14382 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
14383 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
14388 && crtl
->uses_pic_offset_table
14389 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
14390 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
14396 /* Similar, for FP regs. */
14399 first_fp_reg_to_save (void)
14403 /* Find lowest numbered live register. */
14404 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
14405 if (df_regs_ever_live_p (first_reg
))
14411 /* Similar, for AltiVec regs. */
14414 first_altivec_reg_to_save (void)
14418 /* Stack frame remains as is unless we are in AltiVec ABI. */
14419 if (! TARGET_ALTIVEC_ABI
)
14420 return LAST_ALTIVEC_REGNO
+ 1;
14422 /* On Darwin, the unwind routines are compiled without
14423 TARGET_ALTIVEC, and use save_world to save/restore the
14424 altivec registers when necessary. */
14425 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
14426 && ! TARGET_ALTIVEC
)
14427 return FIRST_ALTIVEC_REGNO
+ 20;
14429 /* Find lowest numbered live register. */
14430 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14431 if (df_regs_ever_live_p (i
))
14437 /* Return a 32-bit mask of the AltiVec registers we need to set in
14438 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
14439 the 32-bit word is 0. */
14441 static unsigned int
14442 compute_vrsave_mask (void)
14444 unsigned int i
, mask
= 0;
14446 /* On Darwin, the unwind routines are compiled without
14447 TARGET_ALTIVEC, and use save_world to save/restore the
14448 call-saved altivec registers when necessary. */
14449 if (DEFAULT_ABI
== ABI_DARWIN
&& crtl
->calls_eh_return
14450 && ! TARGET_ALTIVEC
)
14453 /* First, find out if we use _any_ altivec registers. */
14454 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14455 if (df_regs_ever_live_p (i
))
14456 mask
|= ALTIVEC_REG_BIT (i
);
14461 /* Next, remove the argument registers from the set. These must
14462 be in the VRSAVE mask set by the caller, so we don't need to add
14463 them in again. More importantly, the mask we compute here is
14464 used to generate CLOBBERs in the set_vrsave insn, and we do not
14465 wish the argument registers to die. */
14466 for (i
= crtl
->args
.info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
14467 mask
&= ~ALTIVEC_REG_BIT (i
);
14469 /* Similarly, remove the return value from the set. */
14472 diddle_return_value (is_altivec_return_reg
, &yes
);
14474 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
14480 /* For a very restricted set of circumstances, we can cut down the
14481 size of prologues/epilogues by calling our own save/restore-the-world
14485 compute_save_world_info (rs6000_stack_t
*info_ptr
)
14487 info_ptr
->world_save_p
= 1;
14488 info_ptr
->world_save_p
14489 = (WORLD_SAVE_P (info_ptr
)
14490 && DEFAULT_ABI
== ABI_DARWIN
14491 && ! (cfun
->calls_setjmp
&& flag_exceptions
)
14492 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
14493 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
14494 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
14495 && info_ptr
->cr_save_p
);
14497 /* This will not work in conjunction with sibcalls. Make sure there
14498 are none. (This check is expensive, but seldom executed.) */
14499 if (WORLD_SAVE_P (info_ptr
))
14502 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
14503 if ( GET_CODE (insn
) == CALL_INSN
14504 && SIBLING_CALL_P (insn
))
14506 info_ptr
->world_save_p
= 0;
14511 if (WORLD_SAVE_P (info_ptr
))
14513 /* Even if we're not touching VRsave, make sure there's room on the
14514 stack for it, if it looks like we're calling SAVE_WORLD, which
14515 will attempt to save it. */
14516 info_ptr
->vrsave_size
= 4;
14518 /* If we are going to save the world, we need to save the link register too. */
14519 info_ptr
->lr_save_p
= 1;
14521 /* "Save" the VRsave register too if we're saving the world. */
14522 if (info_ptr
->vrsave_mask
== 0)
14523 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
14525 /* Because the Darwin register save/restore routines only handle
14526 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
14528 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
14529 && (info_ptr
->first_altivec_reg_save
14530 >= FIRST_SAVED_ALTIVEC_REGNO
));
14537 is_altivec_return_reg (rtx reg
, void *xyes
)
14539 bool *yes
= (bool *) xyes
;
14540 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
14545 /* Calculate the stack information for the current function. This is
14546 complicated by having two separate calling sequences, the AIX calling
14547 sequence and the V.4 calling sequence.
14549 AIX (and Darwin/Mac OS X) stack frames look like:
14551 SP----> +---------------------------------------+
14552 | back chain to caller | 0 0
14553 +---------------------------------------+
14554 | saved CR | 4 8 (8-11)
14555 +---------------------------------------+
14557 +---------------------------------------+
14558 | reserved for compilers | 12 24
14559 +---------------------------------------+
14560 | reserved for binders | 16 32
14561 +---------------------------------------+
14562 | saved TOC pointer | 20 40
14563 +---------------------------------------+
14564 | Parameter save area (P) | 24 48
14565 +---------------------------------------+
14566 | Alloca space (A) | 24+P etc.
14567 +---------------------------------------+
14568 | Local variable space (L) | 24+P+A
14569 +---------------------------------------+
14570 | Float/int conversion temporary (X) | 24+P+A+L
14571 +---------------------------------------+
14572 | Save area for AltiVec registers (W) | 24+P+A+L+X
14573 +---------------------------------------+
14574 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
14575 +---------------------------------------+
14576 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
14577 +---------------------------------------+
14578 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
14579 +---------------------------------------+
14580 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
14581 +---------------------------------------+
14582 old SP->| back chain to caller's caller |
14583 +---------------------------------------+
14585 The required alignment for AIX configurations is two words (i.e., 8
14589 V.4 stack frames look like:
14591 SP----> +---------------------------------------+
14592 | back chain to caller | 0
14593 +---------------------------------------+
14594 | caller's saved LR | 4
14595 +---------------------------------------+
14596 | Parameter save area (P) | 8
14597 +---------------------------------------+
14598 | Alloca space (A) | 8+P
14599 +---------------------------------------+
14600 | Varargs save area (V) | 8+P+A
14601 +---------------------------------------+
14602 | Local variable space (L) | 8+P+A+V
14603 +---------------------------------------+
14604 | Float/int conversion temporary (X) | 8+P+A+V+L
14605 +---------------------------------------+
14606 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
14607 +---------------------------------------+
14608 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
14609 +---------------------------------------+
14610 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
14611 +---------------------------------------+
14612 | SPE: area for 64-bit GP registers |
14613 +---------------------------------------+
14614 | SPE alignment padding |
14615 +---------------------------------------+
14616 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
14617 +---------------------------------------+
14618 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
14619 +---------------------------------------+
14620 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
14621 +---------------------------------------+
14622 old SP->| back chain to caller's caller |
14623 +---------------------------------------+
14625 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
14626 given. (But note below and in sysv4.h that we require only 8 and
14627 may round up the size of our stack frame anyways. The historical
14628 reason is early versions of powerpc-linux which didn't properly
14629 align the stack at program startup. A happy side-effect is that
14630 -mno-eabi libraries can be used with -meabi programs.)
14632 The EABI configuration defaults to the V.4 layout. However,
14633 the stack alignment requirements may differ. If -mno-eabi is not
14634 given, the required stack alignment is 8 bytes; if -mno-eabi is
14635 given, the required alignment is 16 bytes. (But see V.4 comment
14638 #ifndef ABI_STACK_BOUNDARY
14639 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
14642 static rs6000_stack_t
*
14643 rs6000_stack_info (void)
14645 static rs6000_stack_t info
;
14646 rs6000_stack_t
*info_ptr
= &info
;
14647 int reg_size
= TARGET_32BIT
? 4 : 8;
14651 HOST_WIDE_INT non_fixed_size
;
14653 memset (&info
, 0, sizeof (info
));
14657 /* Cache value so we don't rescan instruction chain over and over. */
14658 if (cfun
->machine
->insn_chain_scanned_p
== 0)
14659 cfun
->machine
->insn_chain_scanned_p
14660 = spe_func_has_64bit_regs_p () + 1;
14661 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
14664 /* Select which calling sequence. */
14665 info_ptr
->abi
= DEFAULT_ABI
;
14667 /* Calculate which registers need to be saved & save area size. */
14668 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
14669 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
14670 even if it currently looks like we won't. Reload may need it to
14671 get at a constant; if so, it will have already created a constant
14672 pool entry for it. */
14673 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
14674 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
14675 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
14676 && crtl
->uses_const_pool
14677 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
14678 first_gp
= RS6000_PIC_OFFSET_TABLE_REGNUM
;
14680 first_gp
= info_ptr
->first_gp_reg_save
;
14682 info_ptr
->gp_size
= reg_size
* (32 - first_gp
);
14684 /* For the SPE, we have an additional upper 32-bits on each GPR.
14685 Ideally we should save the entire 64-bits only when the upper
14686 half is used in SIMD instructions. Since we only record
14687 registers live (not the size they are used in), this proves
14688 difficult because we'd have to traverse the instruction chain at
14689 the right time, taking reload into account. This is a real pain,
14690 so we opt to save the GPRs in 64-bits always if but one register
14691 gets used in 64-bits. Otherwise, all the registers in the frame
14692 get saved in 32-bits.
14694 So... since when we save all GPRs (except the SP) in 64-bits, the
14695 traditional GP save area will be empty. */
14696 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
14697 info_ptr
->gp_size
= 0;
14699 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
14700 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
14702 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
14703 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
14704 - info_ptr
->first_altivec_reg_save
);
14706 /* Does this function call anything? */
14707 info_ptr
->calls_p
= (! current_function_is_leaf
14708 || cfun
->machine
->ra_needs_full_frame
);
14710 /* Determine if we need to save the link register. */
14711 if ((DEFAULT_ABI
== ABI_AIX
14713 && !TARGET_PROFILE_KERNEL
)
14714 #ifdef TARGET_RELOCATABLE
14715 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
14717 || (info_ptr
->first_fp_reg_save
!= 64
14718 && !FP_SAVE_INLINE (info_ptr
->first_fp_reg_save
))
14719 || (DEFAULT_ABI
== ABI_V4
&& cfun
->calls_alloca
)
14720 || info_ptr
->calls_p
14721 || rs6000_ra_ever_killed ())
14723 info_ptr
->lr_save_p
= 1;
14724 df_set_regs_ever_live (LR_REGNO
, true);
14727 /* Determine if we need to save the condition code registers. */
14728 if (df_regs_ever_live_p (CR2_REGNO
)
14729 || df_regs_ever_live_p (CR3_REGNO
)
14730 || df_regs_ever_live_p (CR4_REGNO
))
14732 info_ptr
->cr_save_p
= 1;
14733 if (DEFAULT_ABI
== ABI_V4
)
14734 info_ptr
->cr_size
= reg_size
;
14737 /* If the current function calls __builtin_eh_return, then we need
14738 to allocate stack space for registers that will hold data for
14739 the exception handler. */
14740 if (crtl
->calls_eh_return
)
14743 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
14746 /* SPE saves EH registers in 64-bits. */
14747 ehrd_size
= i
* (TARGET_SPE_ABI
14748 && info_ptr
->spe_64bit_regs_used
!= 0
14749 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
14754 /* Determine various sizes. */
14755 info_ptr
->reg_size
= reg_size
;
14756 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
14757 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
14758 info_ptr
->parm_size
= RS6000_ALIGN (crtl
->outgoing_args_size
,
14759 TARGET_ALTIVEC
? 16 : 8);
14760 if (FRAME_GROWS_DOWNWARD
)
14761 info_ptr
->vars_size
14762 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
14763 + info_ptr
->parm_size
,
14764 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
14765 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
14766 + info_ptr
->parm_size
);
14768 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
14769 info_ptr
->spe_gp_size
= 8 * (32 - first_gp
);
14771 info_ptr
->spe_gp_size
= 0;
14773 if (TARGET_ALTIVEC_ABI
)
14774 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
14776 info_ptr
->vrsave_mask
= 0;
14778 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
14779 info_ptr
->vrsave_size
= 4;
14781 info_ptr
->vrsave_size
= 0;
14783 compute_save_world_info (info_ptr
);
14785 /* Calculate the offsets. */
14786 switch (DEFAULT_ABI
)
14790 gcc_unreachable ();
14794 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
14795 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
14797 if (TARGET_ALTIVEC_ABI
)
14799 info_ptr
->vrsave_save_offset
14800 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
14802 /* Align stack so vector save area is on a quadword boundary.
14803 The padding goes above the vectors. */
14804 if (info_ptr
->altivec_size
!= 0)
14805 info_ptr
->altivec_padding_size
14806 = info_ptr
->vrsave_save_offset
& 0xF;
14808 info_ptr
->altivec_padding_size
= 0;
14810 info_ptr
->altivec_save_offset
14811 = info_ptr
->vrsave_save_offset
14812 - info_ptr
->altivec_padding_size
14813 - info_ptr
->altivec_size
;
14814 gcc_assert (info_ptr
->altivec_size
== 0
14815 || info_ptr
->altivec_save_offset
% 16 == 0);
14817 /* Adjust for AltiVec case. */
14818 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
14821 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
14822 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
14823 info_ptr
->lr_save_offset
= 2*reg_size
;
14827 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
14828 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
14829 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
14831 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
14833 /* Align stack so SPE GPR save area is aligned on a
14834 double-word boundary. */
14835 if (info_ptr
->spe_gp_size
!= 0 && info_ptr
->cr_save_offset
!= 0)
14836 info_ptr
->spe_padding_size
14837 = 8 - (-info_ptr
->cr_save_offset
% 8);
14839 info_ptr
->spe_padding_size
= 0;
14841 info_ptr
->spe_gp_save_offset
14842 = info_ptr
->cr_save_offset
14843 - info_ptr
->spe_padding_size
14844 - info_ptr
->spe_gp_size
;
14846 /* Adjust for SPE case. */
14847 info_ptr
->ehrd_offset
= info_ptr
->spe_gp_save_offset
;
14849 else if (TARGET_ALTIVEC_ABI
)
14851 info_ptr
->vrsave_save_offset
14852 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
14854 /* Align stack so vector save area is on a quadword boundary. */
14855 if (info_ptr
->altivec_size
!= 0)
14856 info_ptr
->altivec_padding_size
14857 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
14859 info_ptr
->altivec_padding_size
= 0;
14861 info_ptr
->altivec_save_offset
14862 = info_ptr
->vrsave_save_offset
14863 - info_ptr
->altivec_padding_size
14864 - info_ptr
->altivec_size
;
14866 /* Adjust for AltiVec case. */
14867 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
;
14870 info_ptr
->ehrd_offset
= info_ptr
->cr_save_offset
;
14871 info_ptr
->ehrd_offset
-= ehrd_size
;
14872 info_ptr
->lr_save_offset
= reg_size
;
14876 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
14877 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
14878 + info_ptr
->gp_size
14879 + info_ptr
->altivec_size
14880 + info_ptr
->altivec_padding_size
14881 + info_ptr
->spe_gp_size
14882 + info_ptr
->spe_padding_size
14884 + info_ptr
->cr_size
14885 + info_ptr
->vrsave_size
,
14888 non_fixed_size
= (info_ptr
->vars_size
14889 + info_ptr
->parm_size
14890 + info_ptr
->save_size
);
14892 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
14893 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
14895 /* Determine if we need to allocate any stack frame:
14897 For AIX we need to push the stack if a frame pointer is needed
14898 (because the stack might be dynamically adjusted), if we are
14899 debugging, if we make calls, or if the sum of fp_save, gp_save,
14900 and local variables are more than the space needed to save all
14901 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
14902 + 18*8 = 288 (GPR13 reserved).
14904 For V.4 we don't have the stack cushion that AIX uses, but assume
14905 that the debugger can handle stackless frames. */
14907 if (info_ptr
->calls_p
)
14908 info_ptr
->push_p
= 1;
14910 else if (DEFAULT_ABI
== ABI_V4
)
14911 info_ptr
->push_p
= non_fixed_size
!= 0;
14913 else if (frame_pointer_needed
)
14914 info_ptr
->push_p
= 1;
14916 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
14917 info_ptr
->push_p
= 1;
14920 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
14922 /* Zero offsets if we're not saving those registers. */
14923 if (info_ptr
->fp_size
== 0)
14924 info_ptr
->fp_save_offset
= 0;
14926 if (info_ptr
->gp_size
== 0)
14927 info_ptr
->gp_save_offset
= 0;
14929 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
14930 info_ptr
->altivec_save_offset
= 0;
14932 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
14933 info_ptr
->vrsave_save_offset
= 0;
14935 if (! TARGET_SPE_ABI
14936 || info_ptr
->spe_64bit_regs_used
== 0
14937 || info_ptr
->spe_gp_size
== 0)
14938 info_ptr
->spe_gp_save_offset
= 0;
14940 if (! info_ptr
->lr_save_p
)
14941 info_ptr
->lr_save_offset
= 0;
14943 if (! info_ptr
->cr_save_p
)
14944 info_ptr
->cr_save_offset
= 0;
14949 /* Return true if the current function uses any GPRs in 64-bit SIMD
14953 spe_func_has_64bit_regs_p (void)
14957 /* Functions that save and restore all the call-saved registers will
14958 need to save/restore the registers in 64-bits. */
14959 if (crtl
->calls_eh_return
14960 || cfun
->calls_setjmp
14961 || crtl
->has_nonlocal_goto
)
14964 insns
= get_insns ();
14966 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
14972 /* FIXME: This should be implemented with attributes...
14974 (set_attr "spe64" "true")....then,
14975 if (get_spe64(insn)) return true;
14977 It's the only reliable way to do the stuff below. */
14979 i
= PATTERN (insn
);
14980 if (GET_CODE (i
) == SET
)
14982 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
14984 if (SPE_VECTOR_MODE (mode
))
14986 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
))
14996 debug_stack_info (rs6000_stack_t
*info
)
14998 const char *abi_string
;
15001 info
= rs6000_stack_info ();
15003 fprintf (stderr
, "\nStack information for function %s:\n",
15004 ((current_function_decl
&& DECL_NAME (current_function_decl
))
15005 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
15010 default: abi_string
= "Unknown"; break;
15011 case ABI_NONE
: abi_string
= "NONE"; break;
15012 case ABI_AIX
: abi_string
= "AIX"; break;
15013 case ABI_DARWIN
: abi_string
= "Darwin"; break;
15014 case ABI_V4
: abi_string
= "V.4"; break;
15017 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
15019 if (TARGET_ALTIVEC_ABI
)
15020 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
15022 if (TARGET_SPE_ABI
)
15023 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
15025 if (info
->first_gp_reg_save
!= 32)
15026 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
15028 if (info
->first_fp_reg_save
!= 64)
15029 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
15031 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
15032 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
15033 info
->first_altivec_reg_save
);
15035 if (info
->lr_save_p
)
15036 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
15038 if (info
->cr_save_p
)
15039 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
15041 if (info
->vrsave_mask
)
15042 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
15045 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
15048 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
15050 if (info
->gp_save_offset
)
15051 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
15053 if (info
->fp_save_offset
)
15054 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
15056 if (info
->altivec_save_offset
)
15057 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
15058 info
->altivec_save_offset
);
15060 if (info
->spe_gp_save_offset
)
15061 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
15062 info
->spe_gp_save_offset
);
15064 if (info
->vrsave_save_offset
)
15065 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
15066 info
->vrsave_save_offset
);
15068 if (info
->lr_save_offset
)
15069 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
15071 if (info
->cr_save_offset
)
15072 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
15074 if (info
->varargs_save_offset
)
15075 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
15077 if (info
->total_size
)
15078 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
15081 if (info
->vars_size
)
15082 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
15085 if (info
->parm_size
)
15086 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
15088 if (info
->fixed_size
)
15089 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
15092 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
15094 if (info
->spe_gp_size
)
15095 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
15098 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
15100 if (info
->altivec_size
)
15101 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
15103 if (info
->vrsave_size
)
15104 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
15106 if (info
->altivec_padding_size
)
15107 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
15108 info
->altivec_padding_size
);
15110 if (info
->spe_padding_size
)
15111 fprintf (stderr
, "\tspe_padding_size = %5d\n",
15112 info
->spe_padding_size
);
15115 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
15117 if (info
->save_size
)
15118 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
15120 if (info
->reg_size
!= 4)
15121 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
15123 fprintf (stderr
, "\n");
15127 rs6000_return_addr (int count
, rtx frame
)
15129 /* Currently we don't optimize very well between prolog and body
15130 code and for PIC code the code can be actually quite bad, so
15131 don't try to be too clever here. */
15132 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
15134 cfun
->machine
->ra_needs_full_frame
= 1;
15141 plus_constant (copy_to_reg
15142 (gen_rtx_MEM (Pmode
,
15143 memory_address (Pmode
, frame
))),
15144 RETURN_ADDRESS_OFFSET
)));
15147 cfun
->machine
->ra_need_lr
= 1;
15148 return get_hard_reg_initial_val (Pmode
, LR_REGNO
);
15151 /* Say whether a function is a candidate for sibcall handling or not.
15152 We do not allow indirect calls to be optimized into sibling calls.
15153 Also, we can't do it if there are any vector parameters; there's
15154 nowhere to put the VRsave code so it works; note that functions with
15155 vector parameters are required to have a prototype, so the argument
15156 type info must be available here. (The tail recursion case can work
15157 with vector parameters, but there's no way to distinguish here.) */
15159 rs6000_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
15164 if (TARGET_ALTIVEC_VRSAVE
)
15166 for (type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
15167 type
; type
= TREE_CHAIN (type
))
15169 if (TREE_CODE (TREE_VALUE (type
)) == VECTOR_TYPE
)
15173 if (DEFAULT_ABI
== ABI_DARWIN
15174 || ((*targetm
.binds_local_p
) (decl
)
15175 && (DEFAULT_ABI
!= ABI_AIX
|| !DECL_EXTERNAL (decl
))))
15177 tree attr_list
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
15179 if (!lookup_attribute ("longcall", attr_list
)
15180 || lookup_attribute ("shortcall", attr_list
))
15187 /* NULL if INSN insn is valid within a low-overhead loop.
15188 Otherwise return why doloop cannot be applied.
15189 PowerPC uses the COUNT register for branch on table instructions. */
15191 static const char *
15192 rs6000_invalid_within_doloop (const_rtx insn
)
15195 return "Function call in the loop.";
15198 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
15199 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
15200 return "Computed branch in the loop.";
15206 rs6000_ra_ever_killed (void)
15212 if (crtl
->is_thunk
)
15215 /* regs_ever_live has LR marked as used if any sibcalls are present,
15216 but this should not force saving and restoring in the
15217 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
15218 clobbers LR, so that is inappropriate. */
15220 /* Also, the prologue can generate a store into LR that
15221 doesn't really count, like this:
15224 bcl to set PIC register
15228 When we're called from the epilogue, we need to avoid counting
15229 this as a store. */
15231 push_topmost_sequence ();
15232 top
= get_insns ();
15233 pop_topmost_sequence ();
15234 reg
= gen_rtx_REG (Pmode
, LR_REGNO
);
15236 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
15242 if (!SIBLING_CALL_P (insn
))
15245 else if (find_regno_note (insn
, REG_INC
, LR_REGNO
))
15247 else if (set_of (reg
, insn
) != NULL_RTX
15248 && !prologue_epilogue_contains (insn
))
15255 /* Emit instructions needed to load the TOC register.
15256 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
15257 a constant pool; or for SVR4 -fpic. */
15260 rs6000_emit_load_toc_table (int fromprolog
)
15263 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
15265 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
15268 rtx lab
, tmp1
, tmp2
, got
;
15270 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
15271 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15273 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
15275 got
= rs6000_got_sym ();
15276 tmp1
= tmp2
= dest
;
15279 tmp1
= gen_reg_rtx (Pmode
);
15280 tmp2
= gen_reg_rtx (Pmode
);
15282 emit_insn (gen_load_toc_v4_PIC_1 (lab
));
15283 emit_move_insn (tmp1
,
15284 gen_rtx_REG (Pmode
, LR_REGNO
));
15285 emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
15286 emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
15288 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
15290 emit_insn (gen_load_toc_v4_pic_si ());
15291 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
15293 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
15296 rtx temp0
= (fromprolog
15297 ? gen_rtx_REG (Pmode
, 0)
15298 : gen_reg_rtx (Pmode
));
15304 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
15305 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15307 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
15308 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15310 emit_insn (gen_load_toc_v4_PIC_1 (symF
));
15311 emit_move_insn (dest
,
15312 gen_rtx_REG (Pmode
, LR_REGNO
));
15313 emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
, symL
, symF
));
15319 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
15320 emit_insn (gen_load_toc_v4_PIC_1b (tocsym
));
15321 emit_move_insn (dest
,
15322 gen_rtx_REG (Pmode
, LR_REGNO
));
15323 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
15325 emit_insn (gen_addsi3 (dest
, temp0
, dest
));
15327 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
15329 /* This is for AIX code running in non-PIC ELF32. */
15332 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
15333 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15335 emit_insn (gen_elf_high (dest
, realsym
));
15336 emit_insn (gen_elf_low (dest
, dest
, realsym
));
15340 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
15343 emit_insn (gen_load_toc_aix_si (dest
));
15345 emit_insn (gen_load_toc_aix_di (dest
));
15349 /* Emit instructions to restore the link register after determining where
15350 its value has been stored. */
15353 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
15355 rs6000_stack_t
*info
= rs6000_stack_info ();
15358 operands
[0] = source
;
15359 operands
[1] = scratch
;
15361 if (info
->lr_save_p
)
15363 rtx frame_rtx
= stack_pointer_rtx
;
15364 HOST_WIDE_INT sp_offset
= 0;
15367 if (frame_pointer_needed
15368 || cfun
->calls_alloca
15369 || info
->total_size
> 32767)
15371 tmp
= gen_frame_mem (Pmode
, frame_rtx
);
15372 emit_move_insn (operands
[1], tmp
);
15373 frame_rtx
= operands
[1];
15375 else if (info
->push_p
)
15376 sp_offset
= info
->total_size
;
15378 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
15379 tmp
= gen_frame_mem (Pmode
, tmp
);
15380 emit_move_insn (tmp
, operands
[0]);
15383 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
), operands
[0]);
15386 static GTY(()) alias_set_type set
= -1;
15389 get_TOC_alias_set (void)
15392 set
= new_alias_set ();
15396 /* This returns nonzero if the current function uses the TOC. This is
15397 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
15398 is generated by the ABI_V4 load_toc_* patterns. */
15405 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
15408 rtx pat
= PATTERN (insn
);
15411 if (GET_CODE (pat
) == PARALLEL
)
15412 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
15414 rtx sub
= XVECEXP (pat
, 0, i
);
15415 if (GET_CODE (sub
) == USE
)
15417 sub
= XEXP (sub
, 0);
15418 if (GET_CODE (sub
) == UNSPEC
15419 && XINT (sub
, 1) == UNSPEC_TOC
)
15429 create_TOC_reference (rtx symbol
)
15431 if (!can_create_pseudo_p ())
15432 df_set_regs_ever_live (TOC_REGISTER
, true);
15433 return gen_rtx_PLUS (Pmode
,
15434 gen_rtx_REG (Pmode
, TOC_REGISTER
),
15435 gen_rtx_CONST (Pmode
,
15436 gen_rtx_MINUS (Pmode
, symbol
,
15437 gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
))));
15440 /* If _Unwind_* has been called from within the same module,
15441 toc register is not guaranteed to be saved to 40(1) on function
15442 entry. Save it there in that case. */
15445 rs6000_aix_emit_builtin_unwind_init (void)
15448 rtx stack_top
= gen_reg_rtx (Pmode
);
15449 rtx opcode_addr
= gen_reg_rtx (Pmode
);
15450 rtx opcode
= gen_reg_rtx (SImode
);
15451 rtx tocompare
= gen_reg_rtx (SImode
);
15452 rtx no_toc_save_needed
= gen_label_rtx ();
15454 mem
= gen_frame_mem (Pmode
, hard_frame_pointer_rtx
);
15455 emit_move_insn (stack_top
, mem
);
15457 mem
= gen_frame_mem (Pmode
,
15458 gen_rtx_PLUS (Pmode
, stack_top
,
15459 GEN_INT (2 * GET_MODE_SIZE (Pmode
))));
15460 emit_move_insn (opcode_addr
, mem
);
15461 emit_move_insn (opcode
, gen_rtx_MEM (SImode
, opcode_addr
));
15462 emit_move_insn (tocompare
, gen_int_mode (TARGET_32BIT
? 0x80410014
15463 : 0xE8410028, SImode
));
15465 do_compare_rtx_and_jump (opcode
, tocompare
, EQ
, 1,
15466 SImode
, NULL_RTX
, NULL_RTX
,
15467 no_toc_save_needed
);
15469 mem
= gen_frame_mem (Pmode
,
15470 gen_rtx_PLUS (Pmode
, stack_top
,
15471 GEN_INT (5 * GET_MODE_SIZE (Pmode
))));
15472 emit_move_insn (mem
, gen_rtx_REG (Pmode
, 2));
15473 emit_label (no_toc_save_needed
);
15476 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
15477 and the change to the stack pointer. */
15480 rs6000_emit_stack_tie (void)
15482 rtx mem
= gen_frame_mem (BLKmode
,
15483 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
15485 emit_insn (gen_stack_tie (mem
));
15488 /* Emit the correct code for allocating stack space, as insns.
15489 If COPY_R12, make sure a copy of the old frame is left in r12.
15490 If COPY_R11, make sure a copy of the old frame is left in r11,
15491 in preference to r12 if COPY_R12.
15492 The generated code may use hard register 0 as a temporary. */
15495 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, int copy_r12
, int copy_r11
)
15498 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
15499 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
15500 rtx todec
= gen_int_mode (-size
, Pmode
);
15502 if (INTVAL (todec
) != -size
)
15504 warning (0, "stack frame too large");
15505 emit_insn (gen_trap ());
15509 if (crtl
->limit_stack
)
15511 if (REG_P (stack_limit_rtx
)
15512 && REGNO (stack_limit_rtx
) > 1
15513 && REGNO (stack_limit_rtx
) <= 31)
15515 emit_insn (TARGET_32BIT
15516 ? gen_addsi3 (tmp_reg
,
15519 : gen_adddi3 (tmp_reg
,
15523 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
15526 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
15528 && DEFAULT_ABI
== ABI_V4
)
15530 rtx toload
= gen_rtx_CONST (VOIDmode
,
15531 gen_rtx_PLUS (Pmode
,
15535 emit_insn (gen_elf_high (tmp_reg
, toload
));
15536 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
15537 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
15541 warning (0, "stack limit expression is not supported");
15544 if (copy_r12
|| copy_r11
|| ! TARGET_UPDATE
)
15545 emit_move_insn (copy_r11
15546 ? gen_rtx_REG (Pmode
, 11)
15547 : gen_rtx_REG (Pmode
, 12),
15556 /* Need a note here so that try_split doesn't get confused. */
15557 if (get_last_insn () == NULL_RTX
)
15558 emit_note (NOTE_INSN_DELETED
);
15559 insn
= emit_move_insn (tmp_reg
, todec
);
15560 try_split (PATTERN (insn
), insn
, 0);
15564 insn
= emit_insn (TARGET_32BIT
15565 ? gen_movsi_update (stack_reg
, stack_reg
,
15567 : gen_movdi_di_update (stack_reg
, stack_reg
,
15568 todec
, stack_reg
));
15569 /* Since we didn't use gen_frame_mem to generate the MEM, grab
15570 it now and set the alias set/attributes. The above gen_*_update
15571 calls will generate a PARALLEL with the MEM set being the first
15573 par
= PATTERN (insn
);
15574 gcc_assert (GET_CODE (par
) == PARALLEL
);
15575 set
= XVECEXP (par
, 0, 0);
15576 gcc_assert (GET_CODE (set
) == SET
);
15577 mem
= SET_DEST (set
);
15578 gcc_assert (MEM_P (mem
));
15579 MEM_NOTRAP_P (mem
) = 1;
15580 set_mem_alias_set (mem
, get_frame_alias_set ());
15584 insn
= emit_insn (TARGET_32BIT
15585 ? gen_addsi3 (stack_reg
, stack_reg
, todec
)
15586 : gen_adddi3 (stack_reg
, stack_reg
, todec
));
15587 emit_move_insn (gen_frame_mem (Pmode
, stack_reg
),
15589 ? gen_rtx_REG (Pmode
, 11)
15590 : gen_rtx_REG (Pmode
, 12));
15593 RTX_FRAME_RELATED_P (insn
) = 1;
15595 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
15596 gen_rtx_SET (VOIDmode
, stack_reg
,
15597 gen_rtx_PLUS (Pmode
, stack_reg
,
15602 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
15603 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
15604 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
15605 deduce these equivalences by itself so it wasn't necessary to hold
15606 its hand so much. */
15609 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
15610 rtx reg2
, rtx rreg
)
15614 /* copy_rtx will not make unique copies of registers, so we need to
15615 ensure we don't have unwanted sharing here. */
15617 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
15620 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
15622 real
= copy_rtx (PATTERN (insn
));
15624 if (reg2
!= NULL_RTX
)
15625 real
= replace_rtx (real
, reg2
, rreg
);
15627 real
= replace_rtx (real
, reg
,
15628 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
15629 STACK_POINTER_REGNUM
),
15632 /* We expect that 'real' is either a SET or a PARALLEL containing
15633 SETs (and possibly other stuff). In a PARALLEL, all the SETs
15634 are important so they all have to be marked RTX_FRAME_RELATED_P. */
15636 if (GET_CODE (real
) == SET
)
15640 temp
= simplify_rtx (SET_SRC (set
));
15642 SET_SRC (set
) = temp
;
15643 temp
= simplify_rtx (SET_DEST (set
));
15645 SET_DEST (set
) = temp
;
15646 if (GET_CODE (SET_DEST (set
)) == MEM
)
15648 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
15650 XEXP (SET_DEST (set
), 0) = temp
;
15657 gcc_assert (GET_CODE (real
) == PARALLEL
);
15658 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
15659 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
15661 rtx set
= XVECEXP (real
, 0, i
);
15663 temp
= simplify_rtx (SET_SRC (set
));
15665 SET_SRC (set
) = temp
;
15666 temp
= simplify_rtx (SET_DEST (set
));
15668 SET_DEST (set
) = temp
;
15669 if (GET_CODE (SET_DEST (set
)) == MEM
)
15671 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
15673 XEXP (SET_DEST (set
), 0) = temp
;
15675 RTX_FRAME_RELATED_P (set
) = 1;
15679 RTX_FRAME_RELATED_P (insn
) = 1;
15680 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
15685 /* Returns an insn that has a vrsave set operation with the
15686 appropriate CLOBBERs. */
15689 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
15692 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
15693 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
15696 = gen_rtx_SET (VOIDmode
,
15698 gen_rtx_UNSPEC_VOLATILE (SImode
,
15699 gen_rtvec (2, reg
, vrsave
),
15700 UNSPECV_SET_VRSAVE
));
15704 /* We need to clobber the registers in the mask so the scheduler
15705 does not move sets to VRSAVE before sets of AltiVec registers.
15707 However, if the function receives nonlocal gotos, reload will set
15708 all call saved registers live. We will end up with:
15710 (set (reg 999) (mem))
15711 (parallel [ (set (reg vrsave) (unspec blah))
15712 (clobber (reg 999))])
15714 The clobber will cause the store into reg 999 to be dead, and
15715 flow will attempt to delete an epilogue insn. In this case, we
15716 need an unspec use/set of the register. */
15718 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
15719 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
15721 if (!epiloguep
|| call_used_regs
[i
])
15722 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
15723 gen_rtx_REG (V4SImode
, i
));
15726 rtx reg
= gen_rtx_REG (V4SImode
, i
);
15729 = gen_rtx_SET (VOIDmode
,
15731 gen_rtx_UNSPEC (V4SImode
,
15732 gen_rtvec (1, reg
), 27));
15736 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
15738 for (i
= 0; i
< nclobs
; ++i
)
15739 XVECEXP (insn
, 0, i
) = clobs
[i
];
15744 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
15745 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
15748 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
15749 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
15751 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
15752 rtx replacea
, replaceb
;
15754 int_rtx
= GEN_INT (offset
);
15756 /* Some cases that need register indexed addressing. */
15757 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
15758 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
15760 && SPE_VECTOR_MODE (mode
)
15761 && !SPE_CONST_OFFSET_OK (offset
)))
15763 /* Whomever calls us must make sure r11 is available in the
15764 flow path of instructions in the prologue. */
15765 offset_rtx
= gen_rtx_REG (Pmode
, 11);
15766 emit_move_insn (offset_rtx
, int_rtx
);
15768 replacea
= offset_rtx
;
15769 replaceb
= int_rtx
;
15773 offset_rtx
= int_rtx
;
15774 replacea
= NULL_RTX
;
15775 replaceb
= NULL_RTX
;
15778 reg
= gen_rtx_REG (mode
, regno
);
15779 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
15780 mem
= gen_frame_mem (mode
, addr
);
15782 insn
= emit_move_insn (mem
, reg
);
15784 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
15787 /* Emit an offset memory reference suitable for a frame store, while
15788 converting to a valid addressing mode. */
15791 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
15793 rtx int_rtx
, offset_rtx
;
15795 int_rtx
= GEN_INT (offset
);
15797 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
15798 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
15800 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
15801 emit_move_insn (offset_rtx
, int_rtx
);
15804 offset_rtx
= int_rtx
;
15806 return gen_frame_mem (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
15809 /* Look for user-defined global regs. We should not save and restore these,
15810 and cannot use stmw/lmw if there are any in its range. */
15813 no_global_regs_above (int first
, bool gpr
)
15816 for (i
= first
; i
< gpr
? 32 : 64 ; i
++)
15817 if (global_regs
[i
])
15822 #ifndef TARGET_FIX_AND_CONTINUE
15823 #define TARGET_FIX_AND_CONTINUE 0
15826 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
15827 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
15828 #define LAST_SAVRES_REGISTER 31
15829 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
15831 static GTY(()) rtx savres_routine_syms
[N_SAVRES_REGISTERS
][8];
15833 /* Return the symbol for an out-of-line register save/restore routine.
15834 We are saving/restoring GPRs if GPR is true. */
15837 rs6000_savres_routine_sym (rs6000_stack_t
*info
, bool savep
, bool gpr
, bool exitp
)
15839 int regno
= gpr
? info
->first_gp_reg_save
: (info
->first_fp_reg_save
- 32);
15841 int select
= ((savep
? 1 : 0) << 2
15843 /* On the SPE, we never have any FPRs, but we do have
15844 32/64-bit versions of the routines. */
15845 ? (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
? 1 : 0)
15849 /* Don't generate bogus routine names. */
15850 gcc_assert (FIRST_SAVRES_REGISTER
<= regno
&& regno
<= LAST_SAVRES_REGISTER
);
15852 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
];
15857 const char *action
;
15858 const char *regkind
;
15859 const char *exit_suffix
;
15861 action
= savep
? "save" : "rest";
15863 /* SPE has slightly different names for its routines depending on
15864 whether we are saving 32-bit or 64-bit registers. */
15865 if (TARGET_SPE_ABI
)
15867 /* No floating point saves on the SPE. */
15870 regkind
= info
->spe_64bit_regs_used
? "64gpr" : "32gpr";
15873 regkind
= gpr
? "gpr" : "fpr";
15875 exit_suffix
= exitp
? "_x" : "";
15877 sprintf (name
, "_%s%s_%d%s", action
, regkind
, regno
, exit_suffix
);
15879 sym
= savres_routine_syms
[regno
-FIRST_SAVRES_REGISTER
][select
]
15880 = gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (name
));
15886 /* Emit a sequence of insns, including a stack tie if needed, for
15887 resetting the stack pointer. If SAVRES is true, then don't reset the
15888 stack pointer, but move the base of the frame into r11 for use by
15889 out-of-line register restore routines. */
15892 rs6000_emit_stack_reset (rs6000_stack_t
*info
,
15893 rtx sp_reg_rtx
, rtx frame_reg_rtx
,
15894 int sp_offset
, bool savres
)
15896 /* This blockage is needed so that sched doesn't decide to move
15897 the sp change before the register restores. */
15898 if (frame_reg_rtx
!= sp_reg_rtx
15900 && info
->spe_64bit_regs_used
!= 0
15901 && info
->first_gp_reg_save
!= 32))
15902 rs6000_emit_stack_tie ();
15904 if (frame_reg_rtx
!= sp_reg_rtx
)
15906 rs6000_emit_stack_tie ();
15907 if (sp_offset
!= 0)
15908 emit_insn (gen_addsi3 (sp_reg_rtx
, frame_reg_rtx
,
15909 GEN_INT (sp_offset
)));
15911 emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
15913 else if (sp_offset
!= 0)
15915 /* If we are restoring registers out-of-line, we will be using the
15916 "exit" variants of the restore routines, which will reset the
15917 stack for us. But we do need to point r11 into the right place
15918 for those routines. */
15919 rtx dest_reg
= (savres
15920 ? gen_rtx_REG (Pmode
, 11)
15923 emit_insn (TARGET_32BIT
15924 ? gen_addsi3 (dest_reg
, sp_reg_rtx
,
15925 GEN_INT (sp_offset
))
15926 : gen_adddi3 (dest_reg
, sp_reg_rtx
,
15927 GEN_INT (sp_offset
)));
15931 /* Construct a parallel rtx describing the effect of a call to an
15932 out-of-line register save/restore routine. */
15935 rs6000_make_savres_rtx (rs6000_stack_t
*info
,
15936 rtx frame_reg_rtx
, int save_area_offset
,
15937 enum machine_mode reg_mode
,
15938 bool savep
, bool gpr
, bool exitp
)
15941 int offset
, start_reg
, end_reg
, n_regs
;
15942 int reg_size
= GET_MODE_SIZE (reg_mode
);
15948 ? info
->first_gp_reg_save
15949 : info
->first_fp_reg_save
);
15950 end_reg
= gpr
? 32 : 64;
15951 n_regs
= end_reg
- start_reg
;
15952 p
= rtvec_alloc ((exitp
? 4 : 3) + n_regs
);
15954 /* If we're saving registers, then we should never say we're exiting. */
15955 gcc_assert ((savep
&& !exitp
) || !savep
);
15958 RTVEC_ELT (p
, offset
++) = gen_rtx_RETURN (VOIDmode
);
15960 RTVEC_ELT (p
, offset
++)
15961 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 65));
15963 sym
= rs6000_savres_routine_sym (info
, savep
, gpr
, exitp
);
15964 RTVEC_ELT (p
, offset
++) = gen_rtx_USE (VOIDmode
, sym
);
15965 RTVEC_ELT (p
, offset
++) = gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 11));
15967 for (i
= 0; i
< end_reg
- start_reg
; i
++)
15969 rtx addr
, reg
, mem
;
15970 reg
= gen_rtx_REG (reg_mode
, start_reg
+ i
);
15971 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15972 GEN_INT (save_area_offset
+ reg_size
*i
));
15973 mem
= gen_frame_mem (reg_mode
, addr
);
15975 RTVEC_ELT (p
, i
+ offset
) = gen_rtx_SET (VOIDmode
,
15977 savep
? reg
: mem
);
15980 return gen_rtx_PARALLEL (VOIDmode
, p
);
15983 /* Determine whether the gp REG is really used. */
15986 rs6000_reg_live_or_pic_offset_p (int reg
)
15988 return ((df_regs_ever_live_p (reg
)
15989 && (!call_used_regs
[reg
]
15990 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
15991 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
15992 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
15993 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
15994 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))));
15998 SAVRES_MULTIPLE
= 0x1,
15999 SAVRES_INLINE_FPRS
= 0x2,
16000 SAVRES_INLINE_GPRS
= 0x4
16003 /* Determine the strategy for savings/restoring registers. */
16006 rs6000_savres_strategy (rs6000_stack_t
*info
, bool savep
,
16007 int using_static_chain_p
, int sibcall
)
16009 bool using_multiple_p
;
16011 bool savres_fprs_inline
;
16012 bool savres_gprs_inline
;
16013 bool noclobber_global_gprs
16014 = no_global_regs_above (info
->first_gp_reg_save
, /*gpr=*/true);
16016 using_multiple_p
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
16017 && (!TARGET_SPE_ABI
16018 || info
->spe_64bit_regs_used
== 0)
16019 && info
->first_gp_reg_save
< 31
16020 && noclobber_global_gprs
);
16021 /* Don't bother to try to save things out-of-line if r11 is occupied
16022 by the static chain. It would require too much fiddling and the
16023 static chain is rarely used anyway. */
16024 common
= (using_static_chain_p
16026 || crtl
->calls_eh_return
16027 || !info
->lr_save_p
16028 || cfun
->machine
->ra_need_lr
16029 || info
->total_size
> 32767);
16030 savres_fprs_inline
= (common
16031 || info
->first_fp_reg_save
== 64
16032 || !no_global_regs_above (info
->first_fp_reg_save
,
16034 || FP_SAVE_INLINE (info
->first_fp_reg_save
));
16035 savres_gprs_inline
= (common
16036 /* Saving CR interferes with the exit routines
16037 used on the SPE, so just punt here. */
16040 && info
->spe_64bit_regs_used
!= 0
16041 && info
->cr_save_p
!= 0)
16042 || info
->first_gp_reg_save
== 32
16043 || !noclobber_global_gprs
16044 || GP_SAVE_INLINE (info
->first_gp_reg_save
));
16047 /* If we are going to use store multiple, then don't even bother
16048 with the out-of-line routines, since the store-multiple instruction
16049 will always be smaller. */
16050 savres_gprs_inline
= savres_gprs_inline
|| using_multiple_p
;
16053 /* The situation is more complicated with load multiple. We'd
16054 prefer to use the out-of-line routines for restores, since the
16055 "exit" out-of-line routines can handle the restore of LR and
16056 the frame teardown. But we can only use the out-of-line
16057 routines if we know that we've used store multiple or
16058 out-of-line routines in the prologue, i.e. if we've saved all
16059 the registers from first_gp_reg_save. Otherwise, we risk
16060 loading garbage from the stack. Furthermore, we can only use
16061 the "exit" out-of-line gpr restore if we haven't saved any
16063 bool saved_all
= !savres_gprs_inline
|| using_multiple_p
;
16065 if (saved_all
&& info
->first_fp_reg_save
!= 64)
16066 /* We can't use the exit routine; use load multiple if it's
16068 savres_gprs_inline
= savres_gprs_inline
|| using_multiple_p
;
16071 return (using_multiple_p
16072 | (savres_fprs_inline
<< 1)
16073 | (savres_gprs_inline
<< 2));
16076 /* Emit function prologue as insns. */
16079 rs6000_emit_prologue (void)
16081 rs6000_stack_t
*info
= rs6000_stack_info ();
16082 enum machine_mode reg_mode
= Pmode
;
16083 int reg_size
= TARGET_32BIT
? 4 : 8;
16084 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
16085 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
16086 rtx frame_reg_rtx
= sp_reg_rtx
;
16087 rtx cr_save_rtx
= NULL_RTX
;
16090 int saving_FPRs_inline
;
16091 int saving_GPRs_inline
;
16092 int using_store_multiple
;
16093 int using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
16094 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
16095 && !call_used_regs
[STATIC_CHAIN_REGNUM
]);
16096 HOST_WIDE_INT sp_offset
= 0;
16098 if (TARGET_FIX_AND_CONTINUE
)
16100 /* gdb on darwin arranges to forward a function from the old
16101 address by modifying the first 5 instructions of the function
16102 to branch to the overriding function. This is necessary to
16103 permit function pointers that point to the old function to
16104 actually forward to the new function. */
16105 emit_insn (gen_nop ());
16106 emit_insn (gen_nop ());
16107 emit_insn (gen_nop ());
16108 emit_insn (gen_nop ());
16109 emit_insn (gen_nop ());
16112 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
16114 reg_mode
= V2SImode
;
16118 strategy
= rs6000_savres_strategy (info
, /*savep=*/true,
16119 /*static_chain_p=*/using_static_chain_p
,
16121 using_store_multiple
= strategy
& SAVRES_MULTIPLE
;
16122 saving_FPRs_inline
= strategy
& SAVRES_INLINE_FPRS
;
16123 saving_GPRs_inline
= strategy
& SAVRES_INLINE_GPRS
;
16125 /* For V.4, update stack before we do any saving and set back pointer. */
16126 if (! WORLD_SAVE_P (info
)
16128 && (DEFAULT_ABI
== ABI_V4
16129 || crtl
->calls_eh_return
))
16131 bool need_r11
= (TARGET_SPE
16132 ? (!saving_GPRs_inline
16133 && info
->spe_64bit_regs_used
== 0)
16134 : (!saving_FPRs_inline
|| !saving_GPRs_inline
));
16135 if (info
->total_size
< 32767)
16136 sp_offset
= info
->total_size
;
16138 frame_reg_rtx
= (need_r11
16139 ? gen_rtx_REG (Pmode
, 11)
16141 rs6000_emit_allocate_stack (info
->total_size
,
16142 (frame_reg_rtx
!= sp_reg_rtx
16143 && (info
->cr_save_p
16145 || info
->first_fp_reg_save
< 64
16146 || info
->first_gp_reg_save
< 32
16149 if (frame_reg_rtx
!= sp_reg_rtx
)
16150 rs6000_emit_stack_tie ();
16153 /* Handle world saves specially here. */
16154 if (WORLD_SAVE_P (info
))
16161 /* save_world expects lr in r0. */
16162 reg0
= gen_rtx_REG (Pmode
, 0);
16163 if (info
->lr_save_p
)
16165 insn
= emit_move_insn (reg0
,
16166 gen_rtx_REG (Pmode
, LR_REGNO
));
16167 RTX_FRAME_RELATED_P (insn
) = 1;
16170 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
16171 assumptions about the offsets of various bits of the stack
16173 gcc_assert (info
->gp_save_offset
== -220
16174 && info
->fp_save_offset
== -144
16175 && info
->lr_save_offset
== 8
16176 && info
->cr_save_offset
== 4
16179 && (!crtl
->calls_eh_return
16180 || info
->ehrd_offset
== -432)
16181 && info
->vrsave_save_offset
== -224
16182 && info
->altivec_save_offset
== -416);
16184 treg
= gen_rtx_REG (SImode
, 11);
16185 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
16187 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
16188 in R11. It also clobbers R12, so beware! */
16190 /* Preserve CR2 for save_world prologues */
16192 sz
+= 32 - info
->first_gp_reg_save
;
16193 sz
+= 64 - info
->first_fp_reg_save
;
16194 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
16195 p
= rtvec_alloc (sz
);
16197 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
16198 gen_rtx_REG (SImode
,
16200 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
16201 gen_rtx_SYMBOL_REF (Pmode
,
16203 /* We do floats first so that the instruction pattern matches
16205 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
16207 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
16208 ? DFmode
: SFmode
),
16209 info
->first_fp_reg_save
+ i
);
16210 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16211 GEN_INT (info
->fp_save_offset
16212 + sp_offset
+ 8 * i
));
16213 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
16214 ? DFmode
: SFmode
), addr
);
16216 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
16218 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
16220 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
16221 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16222 GEN_INT (info
->altivec_save_offset
16223 + sp_offset
+ 16 * i
));
16224 rtx mem
= gen_frame_mem (V4SImode
, addr
);
16226 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
16228 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16230 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16231 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16232 GEN_INT (info
->gp_save_offset
16233 + sp_offset
+ reg_size
* i
));
16234 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16236 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
16240 /* CR register traditionally saved as CR2. */
16241 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
16242 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16243 GEN_INT (info
->cr_save_offset
16245 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16247 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
16249 /* Explain about use of R0. */
16250 if (info
->lr_save_p
)
16252 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16253 GEN_INT (info
->lr_save_offset
16255 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16257 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg0
);
16259 /* Explain what happens to the stack pointer. */
16261 rtx newval
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
, treg
);
16262 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, sp_reg_rtx
, newval
);
16265 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16266 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16267 treg
, GEN_INT (-info
->total_size
));
16268 sp_offset
= info
->total_size
;
16271 /* If we use the link register, get it into r0. */
16272 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
16274 rtx addr
, reg
, mem
;
16276 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
16277 gen_rtx_REG (Pmode
, LR_REGNO
));
16278 RTX_FRAME_RELATED_P (insn
) = 1;
16280 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16281 GEN_INT (info
->lr_save_offset
+ sp_offset
));
16282 reg
= gen_rtx_REG (Pmode
, 0);
16283 mem
= gen_rtx_MEM (Pmode
, addr
);
16284 /* This should not be of rs6000_sr_alias_set, because of
16285 __builtin_return_address. */
16287 insn
= emit_move_insn (mem
, reg
);
16288 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16289 NULL_RTX
, NULL_RTX
);
16292 /* If we need to save CR, put it into r12. */
16293 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
16297 cr_save_rtx
= gen_rtx_REG (SImode
, 12);
16298 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
16299 RTX_FRAME_RELATED_P (insn
) = 1;
16300 /* Now, there's no way that dwarf2out_frame_debug_expr is going
16301 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
16302 But that's OK. All we have to do is specify that _one_ condition
16303 code register is saved in this stack slot. The thrower's epilogue
16304 will then restore all the call-saved registers.
16305 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
16306 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
16307 gen_rtx_REG (SImode
, CR2_REGNO
));
16308 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
16313 /* Do any required saving of fpr's. If only one or two to save, do
16314 it ourselves. Otherwise, call function. */
16315 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
16318 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
16319 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
16320 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
16321 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
,
16322 (TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
16324 info
->first_fp_reg_save
+ i
,
16325 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
16328 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
16332 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
16333 info
->fp_save_offset
+ sp_offset
,
16335 /*savep=*/true, /*gpr=*/false,
16337 insn
= emit_insn (par
);
16338 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16339 NULL_RTX
, NULL_RTX
);
16342 /* Save GPRs. This is done as a PARALLEL if we are using
16343 the store-multiple instructions. */
16344 if (!WORLD_SAVE_P (info
)
16346 && info
->spe_64bit_regs_used
!= 0
16347 && info
->first_gp_reg_save
!= 32)
16350 rtx spe_save_area_ptr
;
16352 /* Determine whether we can address all of the registers that need
16353 to be saved with an offset from the stack pointer that fits in
16354 the small const field for SPE memory instructions. */
16355 int spe_regs_addressable_via_sp
16356 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
16357 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
16358 && saving_GPRs_inline
);
16361 if (spe_regs_addressable_via_sp
)
16363 spe_save_area_ptr
= frame_reg_rtx
;
16364 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
16368 /* Make r11 point to the start of the SPE save area. We need
16369 to be careful here if r11 is holding the static chain. If
16370 it is, then temporarily save it in r0. We would use r0 as
16371 our base register here, but using r0 as a base register in
16372 loads and stores means something different from what we
16374 int ool_adjust
= (saving_GPRs_inline
16376 : (info
->first_gp_reg_save
16377 - (FIRST_SAVRES_REGISTER
+1))*8);
16378 HOST_WIDE_INT offset
= (info
->spe_gp_save_offset
16379 + sp_offset
- ool_adjust
);
16381 if (using_static_chain_p
)
16383 rtx r0
= gen_rtx_REG (Pmode
, 0);
16384 gcc_assert (info
->first_gp_reg_save
> 11);
16386 emit_move_insn (r0
, gen_rtx_REG (Pmode
, 11));
16389 spe_save_area_ptr
= gen_rtx_REG (Pmode
, 11);
16390 insn
= emit_insn (gen_addsi3 (spe_save_area_ptr
,
16392 GEN_INT (offset
)));
16393 /* We need to make sure the move to r11 gets noted for
16394 properly outputting unwind information. */
16395 if (!saving_GPRs_inline
)
16396 rs6000_frame_related (insn
, frame_reg_rtx
, offset
,
16397 NULL_RTX
, NULL_RTX
);
16401 if (saving_GPRs_inline
)
16403 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16404 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
16406 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16407 rtx offset
, addr
, mem
;
16409 /* We're doing all this to ensure that the offset fits into
16410 the immediate offset of 'evstdd'. */
16411 gcc_assert (SPE_CONST_OFFSET_OK (reg_size
* i
+ spe_offset
));
16413 offset
= GEN_INT (reg_size
* i
+ spe_offset
);
16414 addr
= gen_rtx_PLUS (Pmode
, spe_save_area_ptr
, offset
);
16415 mem
= gen_rtx_MEM (V2SImode
, addr
);
16417 insn
= emit_move_insn (mem
, reg
);
16419 rs6000_frame_related (insn
, spe_save_area_ptr
,
16420 info
->spe_gp_save_offset
16421 + sp_offset
+ reg_size
* i
,
16422 offset
, const0_rtx
);
16429 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
16431 /*savep=*/true, /*gpr=*/true,
16433 insn
= emit_insn (par
);
16434 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16435 NULL_RTX
, NULL_RTX
);
16439 /* Move the static chain pointer back. */
16440 if (using_static_chain_p
&& !spe_regs_addressable_via_sp
)
16441 emit_move_insn (gen_rtx_REG (Pmode
, 11), gen_rtx_REG (Pmode
, 0));
16443 else if (!WORLD_SAVE_P (info
) && !saving_GPRs_inline
)
16447 /* Need to adjust r11 if we saved any FPRs. */
16448 if (info
->first_fp_reg_save
!= 64)
16450 rtx r11
= gen_rtx_REG (reg_mode
, 11);
16451 rtx offset
= GEN_INT (info
->total_size
16452 + (-8 * (64-info
->first_fp_reg_save
)));
16453 rtx ptr_reg
= (sp_reg_rtx
== frame_reg_rtx
16454 ? sp_reg_rtx
: r11
);
16456 emit_insn (TARGET_32BIT
16457 ? gen_addsi3 (r11
, ptr_reg
, offset
)
16458 : gen_adddi3 (r11
, ptr_reg
, offset
));
16461 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
16462 info
->gp_save_offset
+ sp_offset
,
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
);
16470 else if (!WORLD_SAVE_P (info
) && using_store_multiple
)
16474 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
16475 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16477 rtx addr
, reg
, mem
;
16478 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16479 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16480 GEN_INT (info
->gp_save_offset
16483 mem
= gen_frame_mem (reg_mode
, addr
);
16485 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
16487 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16488 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16489 NULL_RTX
, NULL_RTX
);
16491 else if (!WORLD_SAVE_P (info
))
16494 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16495 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
16497 rtx addr
, reg
, mem
;
16498 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16500 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16501 GEN_INT (info
->gp_save_offset
16504 mem
= gen_frame_mem (reg_mode
, addr
);
16506 insn
= emit_move_insn (mem
, reg
);
16507 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16508 NULL_RTX
, NULL_RTX
);
16512 /* ??? There's no need to emit actual instructions here, but it's the
16513 easiest way to get the frame unwind information emitted. */
16514 if (crtl
->calls_eh_return
)
16516 unsigned int i
, regno
;
16518 /* In AIX ABI we need to pretend we save r2 here. */
16521 rtx addr
, reg
, mem
;
16523 reg
= gen_rtx_REG (reg_mode
, 2);
16524 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16525 GEN_INT (sp_offset
+ 5 * reg_size
));
16526 mem
= gen_frame_mem (reg_mode
, addr
);
16528 insn
= emit_move_insn (mem
, reg
);
16529 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16530 NULL_RTX
, NULL_RTX
);
16531 PATTERN (insn
) = gen_blockage ();
16536 regno
= EH_RETURN_DATA_REGNO (i
);
16537 if (regno
== INVALID_REGNUM
)
16540 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
16541 info
->ehrd_offset
+ sp_offset
16542 + reg_size
* (int) i
,
16547 /* Save CR if we use any that must be preserved. */
16548 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
16550 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16551 GEN_INT (info
->cr_save_offset
+ sp_offset
));
16552 rtx mem
= gen_frame_mem (SImode
, addr
);
16553 /* See the large comment above about why CR2_REGNO is used. */
16554 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
16556 /* If r12 was used to hold the original sp, copy cr into r0 now
16558 if (REGNO (frame_reg_rtx
) == 12)
16562 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
16563 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
16564 RTX_FRAME_RELATED_P (insn
) = 1;
16565 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
16566 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
16571 insn
= emit_move_insn (mem
, cr_save_rtx
);
16573 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16574 NULL_RTX
, NULL_RTX
);
16577 /* Update stack and set back pointer unless this is V.4,
16578 for which it was done previously. */
16579 if (!WORLD_SAVE_P (info
) && info
->push_p
16580 && !(DEFAULT_ABI
== ABI_V4
|| crtl
->calls_eh_return
))
16582 if (info
->total_size
< 32767)
16583 sp_offset
= info
->total_size
;
16585 frame_reg_rtx
= frame_ptr_rtx
;
16586 rs6000_emit_allocate_stack (info
->total_size
,
16587 (frame_reg_rtx
!= sp_reg_rtx
16588 && ((info
->altivec_size
!= 0)
16589 || (info
->vrsave_mask
!= 0)
16592 if (frame_reg_rtx
!= sp_reg_rtx
)
16593 rs6000_emit_stack_tie ();
16596 /* Set frame pointer, if needed. */
16597 if (frame_pointer_needed
)
16599 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
16601 RTX_FRAME_RELATED_P (insn
) = 1;
16604 /* Save AltiVec registers if needed. Save here because the red zone does
16605 not include AltiVec registers. */
16606 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
16610 /* There should be a non inline version of this, for when we
16611 are saving lots of vector registers. */
16612 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
16613 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
16615 rtx areg
, savereg
, mem
;
16618 offset
= info
->altivec_save_offset
+ sp_offset
16619 + 16 * (i
- info
->first_altivec_reg_save
);
16621 savereg
= gen_rtx_REG (V4SImode
, i
);
16623 areg
= gen_rtx_REG (Pmode
, 0);
16624 emit_move_insn (areg
, GEN_INT (offset
));
16626 /* AltiVec addressing mode is [reg+reg]. */
16627 mem
= gen_frame_mem (V4SImode
,
16628 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
16630 insn
= emit_move_insn (mem
, savereg
);
16632 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16633 areg
, GEN_INT (offset
));
16637 /* VRSAVE is a bit vector representing which AltiVec registers
16638 are used. The OS uses this to determine which vector
16639 registers to save on a context switch. We need to save
16640 VRSAVE on the stack frame, add whatever AltiVec registers we
16641 used in this function, and do the corresponding magic in the
16644 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
16645 && info
->vrsave_mask
!= 0)
16647 rtx reg
, mem
, vrsave
;
16650 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
16651 as frame_reg_rtx and r11 as the static chain pointer for
16652 nested functions. */
16653 reg
= gen_rtx_REG (SImode
, 0);
16654 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
16656 emit_insn (gen_get_vrsave_internal (reg
));
16658 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
16660 if (!WORLD_SAVE_P (info
))
16663 offset
= info
->vrsave_save_offset
+ sp_offset
;
16664 mem
= gen_frame_mem (SImode
,
16665 gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16666 GEN_INT (offset
)));
16667 insn
= emit_move_insn (mem
, reg
);
16670 /* Include the registers in the mask. */
16671 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
16673 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
16676 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
16677 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
16678 || (DEFAULT_ABI
== ABI_V4
16679 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
16680 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
)))
16682 /* If emit_load_toc_table will use the link register, we need to save
16683 it. We use R12 for this purpose because emit_load_toc_table
16684 can use register 0. This allows us to use a plain 'blr' to return
16685 from the procedure more often. */
16686 int save_LR_around_toc_setup
= (TARGET_ELF
16687 && DEFAULT_ABI
!= ABI_AIX
16689 && ! info
->lr_save_p
16690 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
16691 if (save_LR_around_toc_setup
)
16693 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
16695 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
16696 RTX_FRAME_RELATED_P (insn
) = 1;
16698 rs6000_emit_load_toc_table (TRUE
);
16700 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
16701 RTX_FRAME_RELATED_P (insn
) = 1;
16704 rs6000_emit_load_toc_table (TRUE
);
16708 if (DEFAULT_ABI
== ABI_DARWIN
16709 && flag_pic
&& crtl
->uses_pic_offset_table
)
16711 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
16712 rtx src
= machopic_function_base_sym ();
16714 /* Save and restore LR locally around this call (in R0). */
16715 if (!info
->lr_save_p
)
16716 emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
);
16718 emit_insn (gen_load_macho_picbase (src
));
16720 emit_move_insn (gen_rtx_REG (Pmode
,
16721 RS6000_PIC_OFFSET_TABLE_REGNUM
),
16724 if (!info
->lr_save_p
)
16725 emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0));
16730 /* Write function prologue. */
16733 rs6000_output_function_prologue (FILE *file
,
16734 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
16736 rs6000_stack_t
*info
= rs6000_stack_info ();
16738 if (TARGET_DEBUG_STACK
)
16739 debug_stack_info (info
);
16741 /* Write .extern for any function we will call to save and restore
16743 if (info
->first_fp_reg_save
< 64
16744 && !FP_SAVE_INLINE (info
->first_fp_reg_save
))
16745 fprintf (file
, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
16746 SAVE_FP_PREFIX
, info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
,
16747 RESTORE_FP_PREFIX
, info
->first_fp_reg_save
- 32, RESTORE_FP_SUFFIX
);
16749 /* Write .extern for AIX common mode routines, if needed. */
16750 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
16752 fputs ("\t.extern __mulh\n", file
);
16753 fputs ("\t.extern __mull\n", file
);
16754 fputs ("\t.extern __divss\n", file
);
16755 fputs ("\t.extern __divus\n", file
);
16756 fputs ("\t.extern __quoss\n", file
);
16757 fputs ("\t.extern __quous\n", file
);
16758 common_mode_defined
= 1;
16761 if (! HAVE_prologue
)
16765 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
16766 the "toplevel" insn chain. */
16767 emit_note (NOTE_INSN_DELETED
);
16768 rs6000_emit_prologue ();
16769 emit_note (NOTE_INSN_DELETED
);
16771 /* Expand INSN_ADDRESSES so final() doesn't crash. */
16775 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
16777 INSN_ADDRESSES_NEW (insn
, addr
);
16782 if (TARGET_DEBUG_STACK
)
16783 debug_rtx_list (get_insns (), 100);
16784 final (get_insns (), file
, FALSE
);
16788 rs6000_pic_labelno
++;
16791 /* Non-zero if vmx regs are restored before the frame pop, zero if
16792 we restore after the pop when possible. */
16793 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
16795 /* Reload CR from REG. */
16798 rs6000_restore_saved_cr (rtx reg
, int using_mfcr_multiple
)
16803 if (using_mfcr_multiple
)
16805 for (i
= 0; i
< 8; i
++)
16806 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
16808 gcc_assert (count
);
16811 if (using_mfcr_multiple
&& count
> 1)
16816 p
= rtvec_alloc (count
);
16819 for (i
= 0; i
< 8; i
++)
16820 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
16822 rtvec r
= rtvec_alloc (2);
16823 RTVEC_ELT (r
, 0) = reg
;
16824 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
16825 RTVEC_ELT (p
, ndx
) =
16826 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
16827 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
16830 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16831 gcc_assert (ndx
== count
);
16834 for (i
= 0; i
< 8; i
++)
16835 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
16837 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
16843 /* Emit function epilogue as insns.
16845 At present, dwarf2out_frame_debug_expr doesn't understand
16846 register restores, so we don't bother setting RTX_FRAME_RELATED_P
16847 anywhere in the epilogue. Most of the insns below would in any case
16848 need special notes to explain where r11 is in relation to the stack. */
16851 rs6000_emit_epilogue (int sibcall
)
16853 rs6000_stack_t
*info
;
16854 int restoring_GPRs_inline
;
16855 int restoring_FPRs_inline
;
16856 int using_load_multiple
;
16857 int using_mtcr_multiple
;
16858 int use_backchain_to_restore_sp
;
16862 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
16863 rtx frame_reg_rtx
= sp_reg_rtx
;
16864 enum machine_mode reg_mode
= Pmode
;
16865 int reg_size
= TARGET_32BIT
? 4 : 8;
16868 info
= rs6000_stack_info ();
16870 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
16872 reg_mode
= V2SImode
;
16876 strategy
= rs6000_savres_strategy (info
, /*savep=*/false,
16877 /*static_chain_p=*/0, sibcall
);
16878 using_load_multiple
= strategy
& SAVRES_MULTIPLE
;
16879 restoring_FPRs_inline
= strategy
& SAVRES_INLINE_FPRS
;
16880 restoring_GPRs_inline
= strategy
& SAVRES_INLINE_GPRS
;
16881 using_mtcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
16882 || rs6000_cpu
== PROCESSOR_PPC603
16883 || rs6000_cpu
== PROCESSOR_PPC750
16885 /* Restore via the backchain when we have a large frame, since this
16886 is more efficient than an addis, addi pair. The second condition
16887 here will not trigger at the moment; We don't actually need a
16888 frame pointer for alloca, but the generic parts of the compiler
16889 give us one anyway. */
16890 use_backchain_to_restore_sp
= (info
->total_size
> 32767
16891 || info
->total_size
16892 + (info
->lr_save_p
? info
->lr_save_offset
: 0)
16894 || (cfun
->calls_alloca
16895 && !frame_pointer_needed
));
16896 restore_lr
= (info
->lr_save_p
16897 && restoring_GPRs_inline
16898 && restoring_FPRs_inline
);
16900 if (WORLD_SAVE_P (info
))
16904 const char *alloc_rname
;
16907 /* eh_rest_world_r10 will return to the location saved in the LR
16908 stack slot (which is not likely to be our caller.)
16909 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
16910 rest_world is similar, except any R10 parameter is ignored.
16911 The exception-handling stuff that was here in 2.95 is no
16912 longer necessary. */
16916 + 32 - info
->first_gp_reg_save
16917 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
16918 + 63 + 1 - info
->first_fp_reg_save
);
16920 strcpy (rname
, ((crtl
->calls_eh_return
) ?
16921 "*eh_rest_world_r10" : "*rest_world"));
16922 alloc_rname
= ggc_strdup (rname
);
16925 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
16926 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
16927 gen_rtx_REG (Pmode
,
16930 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
16931 /* The instruction pattern requires a clobber here;
16932 it is shared with the restVEC helper. */
16934 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
16937 /* CR register traditionally saved as CR2. */
16938 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
16939 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16940 GEN_INT (info
->cr_save_offset
));
16941 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16943 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16946 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16948 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16949 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16950 GEN_INT (info
->gp_save_offset
16952 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16954 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16956 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
16958 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
16959 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16960 GEN_INT (info
->altivec_save_offset
16962 rtx mem
= gen_frame_mem (V4SImode
, addr
);
16964 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16966 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
16968 rtx reg
= gen_rtx_REG (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
16969 ? DFmode
: SFmode
),
16970 info
->first_fp_reg_save
+ i
);
16971 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16972 GEN_INT (info
->fp_save_offset
16974 rtx mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
16975 ? DFmode
: SFmode
), addr
);
16977 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16980 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
16982 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
16984 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
16986 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
16988 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
16989 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16994 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
16996 sp_offset
= info
->total_size
;
16998 /* Restore AltiVec registers if we must do so before adjusting the
17000 if (TARGET_ALTIVEC_ABI
17001 && info
->altivec_size
!= 0
17002 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
17003 || (DEFAULT_ABI
!= ABI_V4
17004 && info
->altivec_save_offset
< (TARGET_32BIT
? -220 : -288))))
17008 if (use_backchain_to_restore_sp
)
17010 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
17011 emit_move_insn (frame_reg_rtx
,
17012 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
17015 else if (frame_pointer_needed
)
17016 frame_reg_rtx
= hard_frame_pointer_rtx
;
17018 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
17019 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
17021 rtx addr
, areg
, mem
;
17023 areg
= gen_rtx_REG (Pmode
, 0);
17025 (areg
, GEN_INT (info
->altivec_save_offset
17027 + 16 * (i
- info
->first_altivec_reg_save
)));
17029 /* AltiVec addressing mode is [reg+reg]. */
17030 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
17031 mem
= gen_frame_mem (V4SImode
, addr
);
17033 emit_move_insn (gen_rtx_REG (V4SImode
, i
), mem
);
17037 /* Restore VRSAVE if we must do so before adjusting the stack. */
17039 && TARGET_ALTIVEC_VRSAVE
17040 && info
->vrsave_mask
!= 0
17041 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
17042 || (DEFAULT_ABI
!= ABI_V4
17043 && info
->vrsave_save_offset
< (TARGET_32BIT
? -220 : -288))))
17045 rtx addr
, mem
, reg
;
17047 if (frame_reg_rtx
== sp_reg_rtx
)
17049 if (use_backchain_to_restore_sp
)
17051 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
17052 emit_move_insn (frame_reg_rtx
,
17053 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
17056 else if (frame_pointer_needed
)
17057 frame_reg_rtx
= hard_frame_pointer_rtx
;
17060 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17061 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
17062 mem
= gen_frame_mem (SImode
, addr
);
17063 reg
= gen_rtx_REG (SImode
, 12);
17064 emit_move_insn (reg
, mem
);
17066 emit_insn (generate_set_vrsave (reg
, info
, 1));
17069 /* If we have a large stack frame, restore the old stack pointer
17070 using the backchain. */
17071 if (use_backchain_to_restore_sp
)
17073 if (frame_reg_rtx
== sp_reg_rtx
)
17075 /* Under V.4, don't reset the stack pointer until after we're done
17076 loading the saved registers. */
17077 if (DEFAULT_ABI
== ABI_V4
)
17078 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
17080 emit_move_insn (frame_reg_rtx
,
17081 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
17084 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
17085 && DEFAULT_ABI
== ABI_V4
)
17086 /* frame_reg_rtx has been set up by the altivec restore. */
17090 emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
17091 frame_reg_rtx
= sp_reg_rtx
;
17094 /* If we have a frame pointer, we can restore the old stack pointer
17096 else if (frame_pointer_needed
)
17098 frame_reg_rtx
= sp_reg_rtx
;
17099 if (DEFAULT_ABI
== ABI_V4
)
17100 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
17102 emit_insn (TARGET_32BIT
17103 ? gen_addsi3 (frame_reg_rtx
, hard_frame_pointer_rtx
,
17104 GEN_INT (info
->total_size
))
17105 : gen_adddi3 (frame_reg_rtx
, hard_frame_pointer_rtx
,
17106 GEN_INT (info
->total_size
)));
17109 else if (info
->push_p
17110 && DEFAULT_ABI
!= ABI_V4
17111 && !crtl
->calls_eh_return
)
17113 emit_insn (TARGET_32BIT
17114 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
17115 GEN_INT (info
->total_size
))
17116 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
17117 GEN_INT (info
->total_size
)));
17121 /* Restore AltiVec registers if we have not done so already. */
17122 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
17123 && TARGET_ALTIVEC_ABI
17124 && info
->altivec_size
!= 0
17125 && (DEFAULT_ABI
== ABI_V4
17126 || info
->altivec_save_offset
>= (TARGET_32BIT
? -220 : -288)))
17130 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
17131 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
17133 rtx addr
, areg
, mem
;
17135 areg
= gen_rtx_REG (Pmode
, 0);
17137 (areg
, GEN_INT (info
->altivec_save_offset
17139 + 16 * (i
- info
->first_altivec_reg_save
)));
17141 /* AltiVec addressing mode is [reg+reg]. */
17142 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
17143 mem
= gen_frame_mem (V4SImode
, addr
);
17145 emit_move_insn (gen_rtx_REG (V4SImode
, i
), mem
);
17149 /* Restore VRSAVE if we have not done so already. */
17150 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
17152 && TARGET_ALTIVEC_VRSAVE
17153 && info
->vrsave_mask
!= 0
17154 && (DEFAULT_ABI
== ABI_V4
17155 || info
->vrsave_save_offset
>= (TARGET_32BIT
? -220 : -288)))
17157 rtx addr
, mem
, reg
;
17159 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17160 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
17161 mem
= gen_frame_mem (SImode
, addr
);
17162 reg
= gen_rtx_REG (SImode
, 12);
17163 emit_move_insn (reg
, mem
);
17165 emit_insn (generate_set_vrsave (reg
, info
, 1));
17168 /* Get the old lr if we saved it. If we are restoring registers
17169 out-of-line, then the out-of-line routines can do this for us. */
17172 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
17173 info
->lr_save_offset
+ sp_offset
);
17175 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
17178 /* Get the old cr if we saved it. */
17179 if (info
->cr_save_p
)
17181 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17182 GEN_INT (info
->cr_save_offset
+ sp_offset
));
17183 rtx mem
= gen_frame_mem (SImode
, addr
);
17185 emit_move_insn (gen_rtx_REG (SImode
, 12), mem
);
17188 /* Set LR here to try to overlap restores below. */
17190 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
17191 gen_rtx_REG (Pmode
, 0));
17193 /* Load exception handler data registers, if needed. */
17194 if (crtl
->calls_eh_return
)
17196 unsigned int i
, regno
;
17200 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17201 GEN_INT (sp_offset
+ 5 * reg_size
));
17202 rtx mem
= gen_frame_mem (reg_mode
, addr
);
17204 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
17211 regno
= EH_RETURN_DATA_REGNO (i
);
17212 if (regno
== INVALID_REGNUM
)
17215 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
17216 info
->ehrd_offset
+ sp_offset
17217 + reg_size
* (int) i
);
17219 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
17223 /* Restore GPRs. This is done as a PARALLEL if we are using
17224 the load-multiple instructions. */
17226 && info
->spe_64bit_regs_used
!= 0
17227 && info
->first_gp_reg_save
!= 32)
17229 /* Determine whether we can address all of the registers that need
17230 to be saved with an offset from the stack pointer that fits in
17231 the small const field for SPE memory instructions. */
17232 int spe_regs_addressable_via_sp
17233 = (SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
17234 + (32 - info
->first_gp_reg_save
- 1) * reg_size
)
17235 && restoring_GPRs_inline
);
17238 if (spe_regs_addressable_via_sp
)
17239 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
17242 rtx old_frame_reg_rtx
= frame_reg_rtx
;
17243 /* Make r11 point to the start of the SPE save area. We worried about
17244 not clobbering it when we were saving registers in the prologue.
17245 There's no need to worry here because the static chain is passed
17246 anew to every function. */
17247 int ool_adjust
= (restoring_GPRs_inline
17249 : (info
->first_gp_reg_save
17250 - (FIRST_SAVRES_REGISTER
+1))*8);
17252 if (frame_reg_rtx
== sp_reg_rtx
)
17253 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
17254 emit_insn (gen_addsi3 (frame_reg_rtx
, old_frame_reg_rtx
,
17255 GEN_INT (info
->spe_gp_save_offset
17258 /* Keep the invariant that frame_reg_rtx + sp_offset points
17259 at the top of the stack frame. */
17260 sp_offset
= -info
->spe_gp_save_offset
;
17265 if (restoring_GPRs_inline
)
17267 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
17268 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
17270 rtx offset
, addr
, mem
;
17272 /* We're doing all this to ensure that the immediate offset
17273 fits into the immediate field of 'evldd'. */
17274 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset
+ reg_size
* i
));
17276 offset
= GEN_INT (spe_offset
+ reg_size
* i
);
17277 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, offset
);
17278 mem
= gen_rtx_MEM (V2SImode
, addr
);
17280 emit_move_insn (gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
),
17288 par
= rs6000_make_savres_rtx (info
, gen_rtx_REG (Pmode
, 11),
17290 /*savep=*/false, /*gpr=*/true,
17292 emit_jump_insn (par
);
17294 /* We don't want anybody else emitting things after we jumped
17299 else if (!restoring_GPRs_inline
)
17301 /* We are jumping to an out-of-line function. */
17302 bool can_use_exit
= info
->first_fp_reg_save
== 64;
17305 /* Emit stack reset code if we need it. */
17307 rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
17308 sp_offset
, can_use_exit
);
17310 emit_insn (gen_addsi3 (gen_rtx_REG (Pmode
, 11),
17312 GEN_INT (sp_offset
- info
->fp_size
)));
17314 par
= rs6000_make_savres_rtx (info
, frame_reg_rtx
,
17315 info
->gp_save_offset
, reg_mode
,
17316 /*savep=*/false, /*gpr=*/true,
17317 /*exitp=*/can_use_exit
);
17321 if (info
->cr_save_p
)
17322 rs6000_restore_saved_cr (gen_rtx_REG (SImode
, 12),
17323 using_mtcr_multiple
);
17325 emit_jump_insn (par
);
17327 /* We don't want anybody else emitting things after we jumped
17334 else if (using_load_multiple
)
17337 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
17338 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
17340 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17341 GEN_INT (info
->gp_save_offset
17344 rtx mem
= gen_frame_mem (reg_mode
, addr
);
17347 gen_rtx_SET (VOIDmode
,
17348 gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
),
17351 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
17355 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
17356 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
17358 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17359 GEN_INT (info
->gp_save_offset
17362 rtx mem
= gen_frame_mem (reg_mode
, addr
);
17364 emit_move_insn (gen_rtx_REG (reg_mode
,
17365 info
->first_gp_reg_save
+ i
), mem
);
17369 /* Restore fpr's if we need to do it without calling a function. */
17370 if (restoring_FPRs_inline
)
17371 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
17372 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
17373 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
17376 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
17377 GEN_INT (info
->fp_save_offset
17380 mem
= gen_frame_mem (((TARGET_HARD_FLOAT
&& TARGET_DOUBLE_FLOAT
)
17381 ? DFmode
: SFmode
), addr
);
17383 emit_move_insn (gen_rtx_REG (((TARGET_HARD_FLOAT
17384 && TARGET_DOUBLE_FLOAT
)
17385 ? DFmode
: SFmode
),
17386 info
->first_fp_reg_save
+ i
),
17390 /* If we saved cr, restore it here. Just those that were used. */
17391 if (info
->cr_save_p
)
17392 rs6000_restore_saved_cr (gen_rtx_REG (SImode
, 12), using_mtcr_multiple
);
17394 /* If this is V.4, unwind the stack pointer after all of the loads
17396 rs6000_emit_stack_reset (info
, sp_reg_rtx
, frame_reg_rtx
,
17397 sp_offset
, !restoring_FPRs_inline
);
17399 if (crtl
->calls_eh_return
)
17401 rtx sa
= EH_RETURN_STACKADJ_RTX
;
17402 emit_insn (TARGET_32BIT
17403 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
, sa
)
17404 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
, sa
));
17410 if (! restoring_FPRs_inline
)
17411 p
= rtvec_alloc (4 + 64 - info
->first_fp_reg_save
);
17413 p
= rtvec_alloc (2);
17415 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
17416 RTVEC_ELT (p
, 1) = (restoring_FPRs_inline
17417 ? gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 65))
17418 : gen_rtx_CLOBBER (VOIDmode
,
17419 gen_rtx_REG (Pmode
, 65)));
17421 /* If we have to restore more than two FP registers, branch to the
17422 restore function. It will return to our caller. */
17423 if (! restoring_FPRs_inline
)
17428 sym
= rs6000_savres_routine_sym (info
,
17432 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
, sym
);
17433 RTVEC_ELT (p
, 3) = gen_rtx_USE (VOIDmode
,
17434 gen_rtx_REG (Pmode
, 11));
17435 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
17438 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
17439 GEN_INT (info
->fp_save_offset
+ 8*i
));
17440 mem
= gen_frame_mem (DFmode
, addr
);
17442 RTVEC_ELT (p
, i
+4) =
17443 gen_rtx_SET (VOIDmode
,
17444 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
17449 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
17453 /* Write function epilogue. */
17456 rs6000_output_function_epilogue (FILE *file
,
17457 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
17459 if (! HAVE_epilogue
)
17461 rtx insn
= get_last_insn ();
17462 /* If the last insn was a BARRIER, we don't have to write anything except
17463 the trace table. */
17464 if (GET_CODE (insn
) == NOTE
)
17465 insn
= prev_nonnote_insn (insn
);
17466 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
17468 /* This is slightly ugly, but at least we don't have two
17469 copies of the epilogue-emitting code. */
17472 /* A NOTE_INSN_DELETED is supposed to be at the start
17473 and end of the "toplevel" insn chain. */
17474 emit_note (NOTE_INSN_DELETED
);
17475 rs6000_emit_epilogue (FALSE
);
17476 emit_note (NOTE_INSN_DELETED
);
17478 /* Expand INSN_ADDRESSES so final() doesn't crash. */
17482 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
17484 INSN_ADDRESSES_NEW (insn
, addr
);
17489 if (TARGET_DEBUG_STACK
)
17490 debug_rtx_list (get_insns (), 100);
17491 final (get_insns (), file
, FALSE
);
17497 macho_branch_islands ();
17498 /* Mach-O doesn't support labels at the end of objects, so if
17499 it looks like we might want one, insert a NOP. */
17501 rtx insn
= get_last_insn ();
17504 && NOTE_KIND (insn
) != NOTE_INSN_DELETED_LABEL
)
17505 insn
= PREV_INSN (insn
);
17509 && NOTE_KIND (insn
) == NOTE_INSN_DELETED_LABEL
)))
17510 fputs ("\tnop\n", file
);
17514 /* Output a traceback table here. See /usr/include/sys/debug.h for info
17517 We don't output a traceback table if -finhibit-size-directive was
17518 used. The documentation for -finhibit-size-directive reads
17519 ``don't output a @code{.size} assembler directive, or anything
17520 else that would cause trouble if the function is split in the
17521 middle, and the two halves are placed at locations far apart in
17522 memory.'' The traceback table has this property, since it
17523 includes the offset from the start of the function to the
17524 traceback table itself.
17526 System V.4 Powerpc's (and the embedded ABI derived from it) use a
17527 different traceback table. */
17528 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
17529 && rs6000_traceback
!= traceback_none
&& !crtl
->is_thunk
)
17531 const char *fname
= NULL
;
17532 const char *language_string
= lang_hooks
.name
;
17533 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
17535 int optional_tbtab
;
17536 rs6000_stack_t
*info
= rs6000_stack_info ();
17538 if (rs6000_traceback
== traceback_full
)
17539 optional_tbtab
= 1;
17540 else if (rs6000_traceback
== traceback_part
)
17541 optional_tbtab
= 0;
17543 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
17545 if (optional_tbtab
)
17547 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
17548 while (*fname
== '.') /* V.4 encodes . in the name */
17551 /* Need label immediately before tbtab, so we can compute
17552 its offset from the function start. */
17553 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
17554 ASM_OUTPUT_LABEL (file
, fname
);
17557 /* The .tbtab pseudo-op can only be used for the first eight
17558 expressions, since it can't handle the possibly variable
17559 length fields that follow. However, if you omit the optional
17560 fields, the assembler outputs zeros for all optional fields
17561 anyways, giving each variable length field is minimum length
17562 (as defined in sys/debug.h). Thus we can not use the .tbtab
17563 pseudo-op at all. */
17565 /* An all-zero word flags the start of the tbtab, for debuggers
17566 that have to find it by searching forward from the entry
17567 point or from the current pc. */
17568 fputs ("\t.long 0\n", file
);
17570 /* Tbtab format type. Use format type 0. */
17571 fputs ("\t.byte 0,", file
);
17573 /* Language type. Unfortunately, there does not seem to be any
17574 official way to discover the language being compiled, so we
17575 use language_string.
17576 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
17577 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
17578 a number, so for now use 9. */
17579 if (! strcmp (language_string
, "GNU C"))
17581 else if (! strcmp (language_string
, "GNU F77")
17582 || ! strcmp (language_string
, "GNU Fortran"))
17584 else if (! strcmp (language_string
, "GNU Pascal"))
17586 else if (! strcmp (language_string
, "GNU Ada"))
17588 else if (! strcmp (language_string
, "GNU C++")
17589 || ! strcmp (language_string
, "GNU Objective-C++"))
17591 else if (! strcmp (language_string
, "GNU Java"))
17593 else if (! strcmp (language_string
, "GNU Objective-C"))
17596 gcc_unreachable ();
17597 fprintf (file
, "%d,", i
);
17599 /* 8 single bit fields: global linkage (not set for C extern linkage,
17600 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
17601 from start of procedure stored in tbtab, internal function, function
17602 has controlled storage, function has no toc, function uses fp,
17603 function logs/aborts fp operations. */
17604 /* Assume that fp operations are used if any fp reg must be saved. */
17605 fprintf (file
, "%d,",
17606 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
17608 /* 6 bitfields: function is interrupt handler, name present in
17609 proc table, function calls alloca, on condition directives
17610 (controls stack walks, 3 bits), saves condition reg, saves
17612 /* The `function calls alloca' bit seems to be set whenever reg 31 is
17613 set up as a frame pointer, even when there is no alloca call. */
17614 fprintf (file
, "%d,",
17615 ((optional_tbtab
<< 6)
17616 | ((optional_tbtab
& frame_pointer_needed
) << 5)
17617 | (info
->cr_save_p
<< 1)
17618 | (info
->lr_save_p
)));
17620 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
17622 fprintf (file
, "%d,",
17623 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
17625 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
17626 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
17628 if (optional_tbtab
)
17630 /* Compute the parameter info from the function decl argument
17633 int next_parm_info_bit
= 31;
17635 for (decl
= DECL_ARGUMENTS (current_function_decl
);
17636 decl
; decl
= TREE_CHAIN (decl
))
17638 rtx parameter
= DECL_INCOMING_RTL (decl
);
17639 enum machine_mode mode
= GET_MODE (parameter
);
17641 if (GET_CODE (parameter
) == REG
)
17643 if (SCALAR_FLOAT_MODE_P (mode
))
17664 gcc_unreachable ();
17667 /* If only one bit will fit, don't or in this entry. */
17668 if (next_parm_info_bit
> 0)
17669 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
17670 next_parm_info_bit
-= 2;
17674 fixed_parms
+= ((GET_MODE_SIZE (mode
)
17675 + (UNITS_PER_WORD
- 1))
17677 next_parm_info_bit
-= 1;
17683 /* Number of fixed point parameters. */
17684 /* This is actually the number of words of fixed point parameters; thus
17685 an 8 byte struct counts as 2; and thus the maximum value is 8. */
17686 fprintf (file
, "%d,", fixed_parms
);
17688 /* 2 bitfields: number of floating point parameters (7 bits), parameters
17690 /* This is actually the number of fp registers that hold parameters;
17691 and thus the maximum value is 13. */
17692 /* Set parameters on stack bit if parameters are not in their original
17693 registers, regardless of whether they are on the stack? Xlc
17694 seems to set the bit when not optimizing. */
17695 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
17697 if (! optional_tbtab
)
17700 /* Optional fields follow. Some are variable length. */
17702 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
17703 11 double float. */
17704 /* There is an entry for each parameter in a register, in the order that
17705 they occur in the parameter list. Any intervening arguments on the
17706 stack are ignored. If the list overflows a long (max possible length
17707 34 bits) then completely leave off all elements that don't fit. */
17708 /* Only emit this long if there was at least one parameter. */
17709 if (fixed_parms
|| float_parms
)
17710 fprintf (file
, "\t.long %d\n", parm_info
);
17712 /* Offset from start of code to tb table. */
17713 fputs ("\t.long ", file
);
17714 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
17716 RS6000_OUTPUT_BASENAME (file
, fname
);
17718 assemble_name (file
, fname
);
17720 rs6000_output_function_entry (file
, fname
);
17723 /* Interrupt handler mask. */
17724 /* Omit this long, since we never set the interrupt handler bit
17727 /* Number of CTL (controlled storage) anchors. */
17728 /* Omit this long, since the has_ctl bit is never set above. */
17730 /* Displacement into stack of each CTL anchor. */
17731 /* Omit this list of longs, because there are no CTL anchors. */
17733 /* Length of function name. */
17736 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
17738 /* Function name. */
17739 assemble_string (fname
, strlen (fname
));
17741 /* Register for alloca automatic storage; this is always reg 31.
17742 Only emit this if the alloca bit was set above. */
17743 if (frame_pointer_needed
)
17744 fputs ("\t.byte 31\n", file
);
17746 fputs ("\t.align 2\n", file
);
17750 /* A C compound statement that outputs the assembler code for a thunk
17751 function, used to implement C++ virtual function calls with
17752 multiple inheritance. The thunk acts as a wrapper around a virtual
17753 function, adjusting the implicit object parameter before handing
17754 control off to the real function.
17756 First, emit code to add the integer DELTA to the location that
17757 contains the incoming first argument. Assume that this argument
17758 contains a pointer, and is the one used to pass the `this' pointer
17759 in C++. This is the incoming argument *before* the function
17760 prologue, e.g. `%o0' on a sparc. The addition must preserve the
17761 values of all other incoming arguments.
17763 After the addition, emit code to jump to FUNCTION, which is a
17764 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
17765 not touch the return address. Hence returning from FUNCTION will
17766 return to whoever called the current `thunk'.
17768 The effect must be as if FUNCTION had been called directly with the
17769 adjusted first argument. This macro is responsible for emitting
17770 all of the code for a thunk function; output_function_prologue()
17771 and output_function_epilogue() are not invoked.
17773 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
17774 been extracted from it.) It might possibly be useful on some
17775 targets, but probably not.
17777 If you do not define this macro, the target-independent code in the
17778 C++ frontend will generate a less efficient heavyweight thunk that
17779 calls FUNCTION instead of jumping to it. The generic approach does
17780 not support varargs. */
17783 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
17784 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
17787 rtx this_rtx
, insn
, funexp
;
17789 reload_completed
= 1;
17790 epilogue_completed
= 1;
17792 /* Mark the end of the (empty) prologue. */
17793 emit_note (NOTE_INSN_PROLOGUE_END
);
17795 /* Find the "this" pointer. If the function returns a structure,
17796 the structure return pointer is in r3. */
17797 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
17798 this_rtx
= gen_rtx_REG (Pmode
, 4);
17800 this_rtx
= gen_rtx_REG (Pmode
, 3);
17802 /* Apply the constant offset, if required. */
17805 rtx delta_rtx
= GEN_INT (delta
);
17806 emit_insn (TARGET_32BIT
17807 ? gen_addsi3 (this_rtx
, this_rtx
, delta_rtx
)
17808 : gen_adddi3 (this_rtx
, this_rtx
, delta_rtx
));
17811 /* Apply the offset from the vtable, if required. */
17814 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
17815 rtx tmp
= gen_rtx_REG (Pmode
, 12);
17817 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this_rtx
));
17818 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
17820 emit_insn (TARGET_32BIT
17821 ? gen_addsi3 (tmp
, tmp
, vcall_offset_rtx
)
17822 : gen_adddi3 (tmp
, tmp
, vcall_offset_rtx
));
17823 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
17827 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
17829 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
17831 emit_insn (TARGET_32BIT
17832 ? gen_addsi3 (this_rtx
, this_rtx
, tmp
)
17833 : gen_adddi3 (this_rtx
, this_rtx
, tmp
));
17836 /* Generate a tail call to the target function. */
17837 if (!TREE_USED (function
))
17839 assemble_external (function
);
17840 TREE_USED (function
) = 1;
17842 funexp
= XEXP (DECL_RTL (function
), 0);
17843 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
17846 if (MACHOPIC_INDIRECT
)
17847 funexp
= machopic_indirect_call_target (funexp
);
17850 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
17851 generate sibcall RTL explicitly. */
17852 insn
= emit_call_insn (
17853 gen_rtx_PARALLEL (VOIDmode
,
17855 gen_rtx_CALL (VOIDmode
,
17856 funexp
, const0_rtx
),
17857 gen_rtx_USE (VOIDmode
, const0_rtx
),
17858 gen_rtx_USE (VOIDmode
,
17859 gen_rtx_REG (SImode
,
17861 gen_rtx_RETURN (VOIDmode
))));
17862 SIBLING_CALL_P (insn
) = 1;
17865 /* Run just enough of rest_of_compilation to get the insns emitted.
17866 There's not really enough bulk here to make other passes such as
17867 instruction scheduling worth while. Note that use_thunk calls
17868 assemble_start_function and assemble_end_function. */
17869 insn
= get_insns ();
17870 insn_locators_alloc ();
17871 shorten_branches (insn
);
17872 final_start_function (insn
, file
, 1);
17873 final (insn
, file
, 1);
17874 final_end_function ();
17875 free_after_compilation (cfun
);
17877 reload_completed
= 0;
17878 epilogue_completed
= 0;
17881 /* A quick summary of the various types of 'constant-pool tables'
17884 Target Flags Name One table per
17885 AIX (none) AIX TOC object file
17886 AIX -mfull-toc AIX TOC object file
17887 AIX -mminimal-toc AIX minimal TOC translation unit
17888 SVR4/EABI (none) SVR4 SDATA object file
17889 SVR4/EABI -fpic SVR4 pic object file
17890 SVR4/EABI -fPIC SVR4 PIC translation unit
17891 SVR4/EABI -mrelocatable EABI TOC function
17892 SVR4/EABI -maix AIX TOC object file
17893 SVR4/EABI -maix -mminimal-toc
17894 AIX minimal TOC translation unit
17896 Name Reg. Set by entries contains:
17897 made by addrs? fp? sum?
17899 AIX TOC 2 crt0 as Y option option
17900 AIX minimal TOC 30 prolog gcc Y Y option
17901 SVR4 SDATA 13 crt0 gcc N Y N
17902 SVR4 pic 30 prolog ld Y not yet N
17903 SVR4 PIC 30 prolog gcc Y option option
17904 EABI TOC 30 prolog gcc Y option option
17908 /* Hash functions for the hash table. */
17911 rs6000_hash_constant (rtx k
)
17913 enum rtx_code code
= GET_CODE (k
);
17914 enum machine_mode mode
= GET_MODE (k
);
17915 unsigned result
= (code
<< 3) ^ mode
;
17916 const char *format
;
17919 format
= GET_RTX_FORMAT (code
);
17920 flen
= strlen (format
);
17926 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
17929 if (mode
!= VOIDmode
)
17930 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
17942 for (; fidx
< flen
; fidx
++)
17943 switch (format
[fidx
])
17948 const char *str
= XSTR (k
, fidx
);
17949 len
= strlen (str
);
17950 result
= result
* 613 + len
;
17951 for (i
= 0; i
< len
; i
++)
17952 result
= result
* 613 + (unsigned) str
[i
];
17957 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
17961 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
17964 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
17965 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
17969 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
17970 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
17977 gcc_unreachable ();
17984 toc_hash_function (const void *hash_entry
)
17986 const struct toc_hash_struct
*thc
=
17987 (const struct toc_hash_struct
*) hash_entry
;
17988 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
17991 /* Compare H1 and H2 for equivalence. */
17994 toc_hash_eq (const void *h1
, const void *h2
)
17996 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
17997 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
17999 if (((const struct toc_hash_struct
*) h1
)->key_mode
18000 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
18003 return rtx_equal_p (r1
, r2
);
18006 /* These are the names given by the C++ front-end to vtables, and
18007 vtable-like objects. Ideally, this logic should not be here;
18008 instead, there should be some programmatic way of inquiring as
18009 to whether or not an object is a vtable. */
18011 #define VTABLE_NAME_P(NAME) \
18012 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
18013 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
18014 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
18015 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
18016 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
18019 rs6000_output_symbol_ref (FILE *file
, rtx x
)
18021 /* Currently C++ toc references to vtables can be emitted before it
18022 is decided whether the vtable is public or private. If this is
18023 the case, then the linker will eventually complain that there is
18024 a reference to an unknown section. Thus, for vtables only,
18025 we emit the TOC reference to reference the symbol and not the
18027 const char *name
= XSTR (x
, 0);
18029 if (VTABLE_NAME_P (name
))
18031 RS6000_OUTPUT_BASENAME (file
, name
);
18034 assemble_name (file
, name
);
18037 /* Output a TOC entry. We derive the entry name from what is being
18041 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
18044 const char *name
= buf
;
18045 const char *real_name
;
18047 HOST_WIDE_INT offset
= 0;
18049 gcc_assert (!TARGET_NO_TOC
);
18051 /* When the linker won't eliminate them, don't output duplicate
18052 TOC entries (this happens on AIX if there is any kind of TOC,
18053 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
18055 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
18057 struct toc_hash_struct
*h
;
18060 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
18061 time because GGC is not initialized at that point. */
18062 if (toc_hash_table
== NULL
)
18063 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
18064 toc_hash_eq
, NULL
);
18066 h
= GGC_NEW (struct toc_hash_struct
);
18068 h
->key_mode
= mode
;
18069 h
->labelno
= labelno
;
18071 found
= htab_find_slot (toc_hash_table
, h
, 1);
18072 if (*found
== NULL
)
18074 else /* This is indeed a duplicate.
18075 Set this label equal to that label. */
18077 fputs ("\t.set ", file
);
18078 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
18079 fprintf (file
, "%d,", labelno
);
18080 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
18081 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
18087 /* If we're going to put a double constant in the TOC, make sure it's
18088 aligned properly when strict alignment is on. */
18089 if (GET_CODE (x
) == CONST_DOUBLE
18090 && STRICT_ALIGNMENT
18091 && GET_MODE_BITSIZE (mode
) >= 64
18092 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
18093 ASM_OUTPUT_ALIGN (file
, 3);
18096 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
18098 /* Handle FP constants specially. Note that if we have a minimal
18099 TOC, things we put here aren't actually in the TOC, so we can allow
18101 if (GET_CODE (x
) == CONST_DOUBLE
&&
18102 (GET_MODE (x
) == TFmode
|| GET_MODE (x
) == TDmode
))
18104 REAL_VALUE_TYPE rv
;
18107 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
18108 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
18109 REAL_VALUE_TO_TARGET_DECIMAL128 (rv
, k
);
18111 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
18115 if (TARGET_MINIMAL_TOC
)
18116 fputs (DOUBLE_INT_ASM_OP
, file
);
18118 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
18119 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
18120 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
18121 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
18122 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
18123 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
18128 if (TARGET_MINIMAL_TOC
)
18129 fputs ("\t.long ", file
);
18131 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
18132 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
18133 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
18134 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
18135 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
18136 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
18140 else if (GET_CODE (x
) == CONST_DOUBLE
&&
18141 (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DDmode
))
18143 REAL_VALUE_TYPE rv
;
18146 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
18148 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
18149 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, k
);
18151 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
18155 if (TARGET_MINIMAL_TOC
)
18156 fputs (DOUBLE_INT_ASM_OP
, file
);
18158 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
18159 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
18160 fprintf (file
, "0x%lx%08lx\n",
18161 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
18166 if (TARGET_MINIMAL_TOC
)
18167 fputs ("\t.long ", file
);
18169 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
18170 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
18171 fprintf (file
, "0x%lx,0x%lx\n",
18172 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
18176 else if (GET_CODE (x
) == CONST_DOUBLE
&&
18177 (GET_MODE (x
) == SFmode
|| GET_MODE (x
) == SDmode
))
18179 REAL_VALUE_TYPE rv
;
18182 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
18183 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
18184 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
18186 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
18190 if (TARGET_MINIMAL_TOC
)
18191 fputs (DOUBLE_INT_ASM_OP
, file
);
18193 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
18194 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
18199 if (TARGET_MINIMAL_TOC
)
18200 fputs ("\t.long ", file
);
18202 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
18203 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
18207 else if (GET_MODE (x
) == VOIDmode
18208 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
18210 unsigned HOST_WIDE_INT low
;
18211 HOST_WIDE_INT high
;
18213 if (GET_CODE (x
) == CONST_DOUBLE
)
18215 low
= CONST_DOUBLE_LOW (x
);
18216 high
= CONST_DOUBLE_HIGH (x
);
18219 #if HOST_BITS_PER_WIDE_INT == 32
18222 high
= (low
& 0x80000000) ? ~0 : 0;
18226 low
= INTVAL (x
) & 0xffffffff;
18227 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
18231 /* TOC entries are always Pmode-sized, but since this
18232 is a bigendian machine then if we're putting smaller
18233 integer constants in the TOC we have to pad them.
18234 (This is still a win over putting the constants in
18235 a separate constant pool, because then we'd have
18236 to have both a TOC entry _and_ the actual constant.)
18238 For a 32-bit target, CONST_INT values are loaded and shifted
18239 entirely within `low' and can be stored in one TOC entry. */
18241 /* It would be easy to make this work, but it doesn't now. */
18242 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
18244 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
18246 #if HOST_BITS_PER_WIDE_INT == 32
18247 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
18248 POINTER_SIZE
, &low
, &high
, 0);
18251 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
18252 high
= (HOST_WIDE_INT
) low
>> 32;
18259 if (TARGET_MINIMAL_TOC
)
18260 fputs (DOUBLE_INT_ASM_OP
, file
);
18262 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
18263 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
18264 fprintf (file
, "0x%lx%08lx\n",
18265 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
18270 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
18272 if (TARGET_MINIMAL_TOC
)
18273 fputs ("\t.long ", file
);
18275 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
18276 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
18277 fprintf (file
, "0x%lx,0x%lx\n",
18278 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
18282 if (TARGET_MINIMAL_TOC
)
18283 fputs ("\t.long ", file
);
18285 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
18286 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
18292 if (GET_CODE (x
) == CONST
)
18294 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
);
18296 base
= XEXP (XEXP (x
, 0), 0);
18297 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
18300 switch (GET_CODE (base
))
18303 name
= XSTR (base
, 0);
18307 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
18308 CODE_LABEL_NUMBER (XEXP (base
, 0)));
18312 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
18316 gcc_unreachable ();
18319 real_name
= (*targetm
.strip_name_encoding
) (name
);
18320 if (TARGET_MINIMAL_TOC
)
18321 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
18324 fprintf (file
, "\t.tc %s", real_name
);
18327 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
18329 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
18331 fputs ("[TC],", file
);
18334 /* Currently C++ toc references to vtables can be emitted before it
18335 is decided whether the vtable is public or private. If this is
18336 the case, then the linker will eventually complain that there is
18337 a TOC reference to an unknown section. Thus, for vtables only,
18338 we emit the TOC reference to reference the symbol and not the
18340 if (VTABLE_NAME_P (name
))
18342 RS6000_OUTPUT_BASENAME (file
, name
);
18344 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
18345 else if (offset
> 0)
18346 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
18349 output_addr_const (file
, x
);
18353 /* Output an assembler pseudo-op to write an ASCII string of N characters
18354 starting at P to FILE.
18356 On the RS/6000, we have to do this using the .byte operation and
18357 write out special characters outside the quoted string.
18358 Also, the assembler is broken; very long strings are truncated,
18359 so we must artificially break them up early. */
18362 output_ascii (FILE *file
, const char *p
, int n
)
18365 int i
, count_string
;
18366 const char *for_string
= "\t.byte \"";
18367 const char *for_decimal
= "\t.byte ";
18368 const char *to_close
= NULL
;
18371 for (i
= 0; i
< n
; i
++)
18374 if (c
>= ' ' && c
< 0177)
18377 fputs (for_string
, file
);
18380 /* Write two quotes to get one. */
18388 for_decimal
= "\"\n\t.byte ";
18392 if (count_string
>= 512)
18394 fputs (to_close
, file
);
18396 for_string
= "\t.byte \"";
18397 for_decimal
= "\t.byte ";
18405 fputs (for_decimal
, file
);
18406 fprintf (file
, "%d", c
);
18408 for_string
= "\n\t.byte \"";
18409 for_decimal
= ", ";
18415 /* Now close the string if we have written one. Then end the line. */
18417 fputs (to_close
, file
);
18420 /* Generate a unique section name for FILENAME for a section type
18421 represented by SECTION_DESC. Output goes into BUF.
18423 SECTION_DESC can be any string, as long as it is different for each
18424 possible section type.
18426 We name the section in the same manner as xlc. The name begins with an
18427 underscore followed by the filename (after stripping any leading directory
18428 names) with the last period replaced by the string SECTION_DESC. If
18429 FILENAME does not contain a period, SECTION_DESC is appended to the end of
18433 rs6000_gen_section_name (char **buf
, const char *filename
,
18434 const char *section_desc
)
18436 const char *q
, *after_last_slash
, *last_period
= 0;
18440 after_last_slash
= filename
;
18441 for (q
= filename
; *q
; q
++)
18444 after_last_slash
= q
+ 1;
18445 else if (*q
== '.')
18449 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
18450 *buf
= (char *) xmalloc (len
);
18455 for (q
= after_last_slash
; *q
; q
++)
18457 if (q
== last_period
)
18459 strcpy (p
, section_desc
);
18460 p
+= strlen (section_desc
);
18464 else if (ISALNUM (*q
))
18468 if (last_period
== 0)
18469 strcpy (p
, section_desc
);
18474 /* Emit profile function. */
18477 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
18479 /* Non-standard profiling for kernels, which just saves LR then calls
18480 _mcount without worrying about arg saves. The idea is to change
18481 the function prologue as little as possible as it isn't easy to
18482 account for arg save/restore code added just for _mcount. */
18483 if (TARGET_PROFILE_KERNEL
)
18486 if (DEFAULT_ABI
== ABI_AIX
)
18488 #ifndef NO_PROFILE_COUNTERS
18489 # define NO_PROFILE_COUNTERS 0
18491 if (NO_PROFILE_COUNTERS
)
18492 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 0);
18496 const char *label_name
;
18499 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
18500 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
18501 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
18503 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 1,
18507 else if (DEFAULT_ABI
== ABI_DARWIN
)
18509 const char *mcount_name
= RS6000_MCOUNT
;
18510 int caller_addr_regno
= LR_REGNO
;
18512 /* Be conservative and always set this, at least for now. */
18513 crtl
->uses_pic_offset_table
= 1;
18516 /* For PIC code, set up a stub and collect the caller's address
18517 from r0, which is where the prologue puts it. */
18518 if (MACHOPIC_INDIRECT
18519 && crtl
->uses_pic_offset_table
)
18520 caller_addr_regno
= 0;
18522 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
18524 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
18528 /* Write function profiler code. */
18531 output_function_profiler (FILE *file
, int labelno
)
18535 switch (DEFAULT_ABI
)
18538 gcc_unreachable ();
18543 warning (0, "no profiling of 64-bit code for this ABI");
18546 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
18547 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
18548 if (NO_PROFILE_COUNTERS
)
18550 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
18551 reg_names
[0], reg_names
[1]);
18553 else if (TARGET_SECURE_PLT
&& flag_pic
)
18555 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
18556 reg_names
[0], reg_names
[1]);
18557 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
18558 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
18559 reg_names
[12], reg_names
[12]);
18560 assemble_name (file
, buf
);
18561 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
18562 assemble_name (file
, buf
);
18563 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
18565 else if (flag_pic
== 1)
18567 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
18568 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
18569 reg_names
[0], reg_names
[1]);
18570 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
18571 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
18572 assemble_name (file
, buf
);
18573 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
18575 else if (flag_pic
> 1)
18577 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
18578 reg_names
[0], reg_names
[1]);
18579 /* Now, we need to get the address of the label. */
18580 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
18581 assemble_name (file
, buf
);
18582 fputs ("-.\n1:", file
);
18583 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
18584 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
18585 reg_names
[0], reg_names
[11]);
18586 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
18587 reg_names
[0], reg_names
[0], reg_names
[11]);
18591 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
18592 assemble_name (file
, buf
);
18593 fputs ("@ha\n", file
);
18594 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
18595 reg_names
[0], reg_names
[1]);
18596 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
18597 assemble_name (file
, buf
);
18598 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
18601 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
18602 fprintf (file
, "\tbl %s%s\n",
18603 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
18608 if (!TARGET_PROFILE_KERNEL
)
18610 /* Don't do anything, done in output_profile_hook (). */
18614 gcc_assert (!TARGET_32BIT
);
18616 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
18617 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
18619 if (cfun
->static_chain_decl
!= NULL
)
18621 asm_fprintf (file
, "\tstd %s,24(%s)\n",
18622 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
18623 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
18624 asm_fprintf (file
, "\tld %s,24(%s)\n",
18625 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
18628 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
18636 /* The following variable value is the last issued insn. */
18638 static rtx last_scheduled_insn
;
18640 /* The following variable helps to balance issuing of load and
18641 store instructions */
18643 static int load_store_pendulum
;
18645 /* Power4 load update and store update instructions are cracked into a
18646 load or store and an integer insn which are executed in the same cycle.
18647 Branches have their own dispatch slot which does not count against the
18648 GCC issue rate, but it changes the program flow so there are no other
18649 instructions to issue in this cycle. */
18652 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED
,
18653 int verbose ATTRIBUTE_UNUSED
,
18654 rtx insn
, int more
)
18656 last_scheduled_insn
= insn
;
18657 if (GET_CODE (PATTERN (insn
)) == USE
18658 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18660 cached_can_issue_more
= more
;
18661 return cached_can_issue_more
;
18664 if (insn_terminates_group_p (insn
, current_group
))
18666 cached_can_issue_more
= 0;
18667 return cached_can_issue_more
;
18670 /* If no reservation, but reach here */
18671 if (recog_memoized (insn
) < 0)
18674 if (rs6000_sched_groups
)
18676 if (is_microcoded_insn (insn
))
18677 cached_can_issue_more
= 0;
18678 else if (is_cracked_insn (insn
))
18679 cached_can_issue_more
= more
> 2 ? more
- 2 : 0;
18681 cached_can_issue_more
= more
- 1;
18683 return cached_can_issue_more
;
18686 if (rs6000_cpu_attr
== CPU_CELL
&& is_nonpipeline_insn (insn
))
18689 cached_can_issue_more
= more
- 1;
18690 return cached_can_issue_more
;
18693 /* Adjust the cost of a scheduling dependency. Return the new cost of
18694 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
18697 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
18699 enum attr_type attr_type
;
18701 if (! recog_memoized (insn
))
18704 switch (REG_NOTE_KIND (link
))
18708 /* Data dependency; DEP_INSN writes a register that INSN reads
18709 some cycles later. */
18711 /* Separate a load from a narrower, dependent store. */
18712 if (rs6000_sched_groups
18713 && GET_CODE (PATTERN (insn
)) == SET
18714 && GET_CODE (PATTERN (dep_insn
)) == SET
18715 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
18716 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
18717 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
18718 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
18721 attr_type
= get_attr_type (insn
);
18726 /* Tell the first scheduling pass about the latency between
18727 a mtctr and bctr (and mtlr and br/blr). The first
18728 scheduling pass will not know about this latency since
18729 the mtctr instruction, which has the latency associated
18730 to it, will be generated by reload. */
18731 return TARGET_POWER
? 5 : 4;
18733 /* Leave some extra cycles between a compare and its
18734 dependent branch, to inhibit expensive mispredicts. */
18735 if ((rs6000_cpu_attr
== CPU_PPC603
18736 || rs6000_cpu_attr
== CPU_PPC604
18737 || rs6000_cpu_attr
== CPU_PPC604E
18738 || rs6000_cpu_attr
== CPU_PPC620
18739 || rs6000_cpu_attr
== CPU_PPC630
18740 || rs6000_cpu_attr
== CPU_PPC750
18741 || rs6000_cpu_attr
== CPU_PPC7400
18742 || rs6000_cpu_attr
== CPU_PPC7450
18743 || rs6000_cpu_attr
== CPU_POWER4
18744 || rs6000_cpu_attr
== CPU_POWER5
18745 || rs6000_cpu_attr
== CPU_CELL
)
18746 && recog_memoized (dep_insn
)
18747 && (INSN_CODE (dep_insn
) >= 0))
18749 switch (get_attr_type (dep_insn
))
18753 case TYPE_DELAYED_COMPARE
:
18754 case TYPE_IMUL_COMPARE
:
18755 case TYPE_LMUL_COMPARE
:
18756 case TYPE_FPCOMPARE
:
18757 case TYPE_CR_LOGICAL
:
18758 case TYPE_DELAYED_CR
:
18767 case TYPE_STORE_UX
:
18769 case TYPE_FPSTORE_U
:
18770 case TYPE_FPSTORE_UX
:
18771 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18772 && recog_memoized (dep_insn
)
18773 && (INSN_CODE (dep_insn
) >= 0))
18776 if (GET_CODE (PATTERN (insn
)) != SET
)
18777 /* If this happens, we have to extend this to schedule
18778 optimally. Return default for now. */
18781 /* Adjust the cost for the case where the value written
18782 by a fixed point operation is used as the address
18783 gen value on a store. */
18784 switch (get_attr_type (dep_insn
))
18791 if (! store_data_bypass_p (dep_insn
, insn
))
18795 case TYPE_LOAD_EXT
:
18796 case TYPE_LOAD_EXT_U
:
18797 case TYPE_LOAD_EXT_UX
:
18798 case TYPE_VAR_SHIFT_ROTATE
:
18799 case TYPE_VAR_DELAYED_COMPARE
:
18801 if (! store_data_bypass_p (dep_insn
, insn
))
18807 case TYPE_FAST_COMPARE
:
18810 case TYPE_INSERT_WORD
:
18811 case TYPE_INSERT_DWORD
:
18812 case TYPE_FPLOAD_U
:
18813 case TYPE_FPLOAD_UX
:
18815 case TYPE_STORE_UX
:
18816 case TYPE_FPSTORE_U
:
18817 case TYPE_FPSTORE_UX
:
18819 if (! store_data_bypass_p (dep_insn
, insn
))
18827 case TYPE_IMUL_COMPARE
:
18828 case TYPE_LMUL_COMPARE
:
18830 if (! store_data_bypass_p (dep_insn
, insn
))
18836 if (! store_data_bypass_p (dep_insn
, insn
))
18842 if (! store_data_bypass_p (dep_insn
, insn
))
18855 case TYPE_LOAD_EXT
:
18856 case TYPE_LOAD_EXT_U
:
18857 case TYPE_LOAD_EXT_UX
:
18858 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18859 && recog_memoized (dep_insn
)
18860 && (INSN_CODE (dep_insn
) >= 0))
18863 /* Adjust the cost for the case where the value written
18864 by a fixed point instruction is used within the address
18865 gen portion of a subsequent load(u)(x) */
18866 switch (get_attr_type (dep_insn
))
18873 if (set_to_load_agen (dep_insn
, insn
))
18877 case TYPE_LOAD_EXT
:
18878 case TYPE_LOAD_EXT_U
:
18879 case TYPE_LOAD_EXT_UX
:
18880 case TYPE_VAR_SHIFT_ROTATE
:
18881 case TYPE_VAR_DELAYED_COMPARE
:
18883 if (set_to_load_agen (dep_insn
, insn
))
18889 case TYPE_FAST_COMPARE
:
18892 case TYPE_INSERT_WORD
:
18893 case TYPE_INSERT_DWORD
:
18894 case TYPE_FPLOAD_U
:
18895 case TYPE_FPLOAD_UX
:
18897 case TYPE_STORE_UX
:
18898 case TYPE_FPSTORE_U
:
18899 case TYPE_FPSTORE_UX
:
18901 if (set_to_load_agen (dep_insn
, insn
))
18909 case TYPE_IMUL_COMPARE
:
18910 case TYPE_LMUL_COMPARE
:
18912 if (set_to_load_agen (dep_insn
, insn
))
18918 if (set_to_load_agen (dep_insn
, insn
))
18924 if (set_to_load_agen (dep_insn
, insn
))
18935 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18936 && recog_memoized (dep_insn
)
18937 && (INSN_CODE (dep_insn
) >= 0)
18938 && (get_attr_type (dep_insn
) == TYPE_MFFGPR
))
18945 /* Fall out to return default cost. */
18949 case REG_DEP_OUTPUT
:
18950 /* Output dependency; DEP_INSN writes a register that INSN writes some
18952 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18953 && recog_memoized (dep_insn
)
18954 && (INSN_CODE (dep_insn
) >= 0))
18956 attr_type
= get_attr_type (insn
);
18961 if (get_attr_type (dep_insn
) == TYPE_FP
)
18965 if (get_attr_type (dep_insn
) == TYPE_MFFGPR
)
18973 /* Anti dependency; DEP_INSN reads a register that INSN writes some
18978 gcc_unreachable ();
18984 /* The function returns a true if INSN is microcoded.
18985 Return false otherwise. */
18988 is_microcoded_insn (rtx insn
)
18990 if (!insn
|| !INSN_P (insn
)
18991 || GET_CODE (PATTERN (insn
)) == USE
18992 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18995 if (rs6000_cpu_attr
== CPU_CELL
)
18996 return get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
;
18998 if (rs6000_sched_groups
)
19000 enum attr_type type
= get_attr_type (insn
);
19001 if (type
== TYPE_LOAD_EXT_U
19002 || type
== TYPE_LOAD_EXT_UX
19003 || type
== TYPE_LOAD_UX
19004 || type
== TYPE_STORE_UX
19005 || type
== TYPE_MFCR
)
19012 /* The function returns true if INSN is cracked into 2 instructions
19013 by the processor (and therefore occupies 2 issue slots). */
19016 is_cracked_insn (rtx insn
)
19018 if (!insn
|| !INSN_P (insn
)
19019 || GET_CODE (PATTERN (insn
)) == USE
19020 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19023 if (rs6000_sched_groups
)
19025 enum attr_type type
= get_attr_type (insn
);
19026 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
19027 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
19028 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
19029 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
19030 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
19031 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
19032 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
19033 || type
== TYPE_INSERT_WORD
)
19040 /* The function returns true if INSN can be issued only from
19041 the branch slot. */
19044 is_branch_slot_insn (rtx insn
)
19046 if (!insn
|| !INSN_P (insn
)
19047 || GET_CODE (PATTERN (insn
)) == USE
19048 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19051 if (rs6000_sched_groups
)
19053 enum attr_type type
= get_attr_type (insn
);
19054 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
19062 /* The function returns true if out_inst sets a value that is
19063 used in the address generation computation of in_insn */
19065 set_to_load_agen (rtx out_insn
, rtx in_insn
)
19067 rtx out_set
, in_set
;
19069 /* For performance reasons, only handle the simple case where
19070 both loads are a single_set. */
19071 out_set
= single_set (out_insn
);
19074 in_set
= single_set (in_insn
);
19076 return reg_mentioned_p (SET_DEST (out_set
), SET_SRC (in_set
));
19082 /* The function returns true if the target storage location of
19083 out_insn is adjacent to the target storage location of in_insn */
19084 /* Return 1 if memory locations are adjacent. */
19087 adjacent_mem_locations (rtx insn1
, rtx insn2
)
19090 rtx a
= get_store_dest (PATTERN (insn1
));
19091 rtx b
= get_store_dest (PATTERN (insn2
));
19093 if ((GET_CODE (XEXP (a
, 0)) == REG
19094 || (GET_CODE (XEXP (a
, 0)) == PLUS
19095 && GET_CODE (XEXP (XEXP (a
, 0), 1)) == CONST_INT
))
19096 && (GET_CODE (XEXP (b
, 0)) == REG
19097 || (GET_CODE (XEXP (b
, 0)) == PLUS
19098 && GET_CODE (XEXP (XEXP (b
, 0), 1)) == CONST_INT
)))
19100 HOST_WIDE_INT val0
= 0, val1
= 0, val_diff
;
19103 if (GET_CODE (XEXP (a
, 0)) == PLUS
)
19105 reg0
= XEXP (XEXP (a
, 0), 0);
19106 val0
= INTVAL (XEXP (XEXP (a
, 0), 1));
19109 reg0
= XEXP (a
, 0);
19111 if (GET_CODE (XEXP (b
, 0)) == PLUS
)
19113 reg1
= XEXP (XEXP (b
, 0), 0);
19114 val1
= INTVAL (XEXP (XEXP (b
, 0), 1));
19117 reg1
= XEXP (b
, 0);
19119 val_diff
= val1
- val0
;
19121 return ((REGNO (reg0
) == REGNO (reg1
))
19122 && ((MEM_SIZE (a
) && val_diff
== INTVAL (MEM_SIZE (a
)))
19123 || (MEM_SIZE (b
) && val_diff
== -INTVAL (MEM_SIZE (b
)))));
19129 /* A C statement (sans semicolon) to update the integer scheduling
19130 priority INSN_PRIORITY (INSN). Increase the priority to execute the
19131 INSN earlier, reduce the priority to execute INSN later. Do not
19132 define this macro if you do not need to adjust the scheduling
19133 priorities of insns. */
19136 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
19138 /* On machines (like the 750) which have asymmetric integer units,
19139 where one integer unit can do multiply and divides and the other
19140 can't, reduce the priority of multiply/divide so it is scheduled
19141 before other integer operations. */
19144 if (! INSN_P (insn
))
19147 if (GET_CODE (PATTERN (insn
)) == USE
)
19150 switch (rs6000_cpu_attr
) {
19152 switch (get_attr_type (insn
))
19159 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
19160 priority
, priority
);
19161 if (priority
>= 0 && priority
< 0x01000000)
19168 if (insn_must_be_first_in_group (insn
)
19169 && reload_completed
19170 && current_sched_info
->sched_max_insns_priority
19171 && rs6000_sched_restricted_insns_priority
)
19174 /* Prioritize insns that can be dispatched only in the first
19176 if (rs6000_sched_restricted_insns_priority
== 1)
19177 /* Attach highest priority to insn. This means that in
19178 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
19179 precede 'priority' (critical path) considerations. */
19180 return current_sched_info
->sched_max_insns_priority
;
19181 else if (rs6000_sched_restricted_insns_priority
== 2)
19182 /* Increase priority of insn by a minimal amount. This means that in
19183 haifa-sched.c:ready_sort(), only 'priority' (critical path)
19184 considerations precede dispatch-slot restriction considerations. */
19185 return (priority
+ 1);
19188 if (rs6000_cpu
== PROCESSOR_POWER6
19189 && ((load_store_pendulum
== -2 && is_load_insn (insn
))
19190 || (load_store_pendulum
== 2 && is_store_insn (insn
))))
19191 /* Attach highest priority to insn if the scheduler has just issued two
19192 stores and this instruction is a load, or two loads and this instruction
19193 is a store. Power6 wants loads and stores scheduled alternately
19195 return current_sched_info
->sched_max_insns_priority
;
19200 /* Return true if the instruction is nonpipelined on the Cell. */
19202 is_nonpipeline_insn (rtx insn
)
19204 enum attr_type type
;
19205 if (!insn
|| !INSN_P (insn
)
19206 || GET_CODE (PATTERN (insn
)) == USE
19207 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19210 type
= get_attr_type (insn
);
19211 if (type
== TYPE_IMUL
19212 || type
== TYPE_IMUL2
19213 || type
== TYPE_IMUL3
19214 || type
== TYPE_LMUL
19215 || type
== TYPE_IDIV
19216 || type
== TYPE_LDIV
19217 || type
== TYPE_SDIV
19218 || type
== TYPE_DDIV
19219 || type
== TYPE_SSQRT
19220 || type
== TYPE_DSQRT
19221 || type
== TYPE_MFCR
19222 || type
== TYPE_MFCRF
19223 || type
== TYPE_MFJMPR
)
19231 /* Return how many instructions the machine can issue per cycle. */
19234 rs6000_issue_rate (void)
19236 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
19237 if (!reload_completed
)
19240 switch (rs6000_cpu_attr
) {
19241 case CPU_RIOS1
: /* ? */
19243 case CPU_PPC601
: /* ? */
19252 case CPU_PPCE300C2
:
19253 case CPU_PPCE300C3
:
19254 case CPU_PPCE500MC
:
19271 /* Return how many instructions to look ahead for better insn
19275 rs6000_use_sched_lookahead (void)
19277 if (rs6000_cpu_attr
== CPU_PPC8540
)
19279 if (rs6000_cpu_attr
== CPU_CELL
)
19280 return (reload_completed
? 8 : 0);
19284 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
19286 rs6000_use_sched_lookahead_guard (rtx insn
)
19288 if (rs6000_cpu_attr
!= CPU_CELL
)
19291 if (insn
== NULL_RTX
|| !INSN_P (insn
))
19294 if (!reload_completed
19295 || is_nonpipeline_insn (insn
)
19296 || is_microcoded_insn (insn
))
19302 /* Determine is PAT refers to memory. */
19305 is_mem_ref (rtx pat
)
19311 /* stack_tie does not produce any real memory traffic. */
19312 if (GET_CODE (pat
) == UNSPEC
19313 && XINT (pat
, 1) == UNSPEC_TIE
)
19316 if (GET_CODE (pat
) == MEM
)
19319 /* Recursively process the pattern. */
19320 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
19322 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
19325 ret
|= is_mem_ref (XEXP (pat
, i
));
19326 else if (fmt
[i
] == 'E')
19327 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
19328 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
19334 /* Determine if PAT is a PATTERN of a load insn. */
19337 is_load_insn1 (rtx pat
)
19339 if (!pat
|| pat
== NULL_RTX
)
19342 if (GET_CODE (pat
) == SET
)
19343 return is_mem_ref (SET_SRC (pat
));
19345 if (GET_CODE (pat
) == PARALLEL
)
19349 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
19350 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
19357 /* Determine if INSN loads from memory. */
19360 is_load_insn (rtx insn
)
19362 if (!insn
|| !INSN_P (insn
))
19365 if (GET_CODE (insn
) == CALL_INSN
)
19368 return is_load_insn1 (PATTERN (insn
));
19371 /* Determine if PAT is a PATTERN of a store insn. */
19374 is_store_insn1 (rtx pat
)
19376 if (!pat
|| pat
== NULL_RTX
)
19379 if (GET_CODE (pat
) == SET
)
19380 return is_mem_ref (SET_DEST (pat
));
19382 if (GET_CODE (pat
) == PARALLEL
)
19386 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
19387 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
19394 /* Determine if INSN stores to memory. */
19397 is_store_insn (rtx insn
)
19399 if (!insn
|| !INSN_P (insn
))
19402 return is_store_insn1 (PATTERN (insn
));
19405 /* Return the dest of a store insn. */
19408 get_store_dest (rtx pat
)
19410 gcc_assert (is_store_insn1 (pat
));
19412 if (GET_CODE (pat
) == SET
)
19413 return SET_DEST (pat
);
19414 else if (GET_CODE (pat
) == PARALLEL
)
19418 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
19420 rtx inner_pat
= XVECEXP (pat
, 0, i
);
19421 if (GET_CODE (inner_pat
) == SET
19422 && is_mem_ref (SET_DEST (inner_pat
)))
19426 /* We shouldn't get here, because we should have either a simple
19427 store insn or a store with update which are covered above. */
19431 /* Returns whether the dependence between INSN and NEXT is considered
19432 costly by the given target. */
19435 rs6000_is_costly_dependence (dep_t dep
, int cost
, int distance
)
19440 /* If the flag is not enabled - no dependence is considered costly;
19441 allow all dependent insns in the same group.
19442 This is the most aggressive option. */
19443 if (rs6000_sched_costly_dep
== no_dep_costly
)
19446 /* If the flag is set to 1 - a dependence is always considered costly;
19447 do not allow dependent instructions in the same group.
19448 This is the most conservative option. */
19449 if (rs6000_sched_costly_dep
== all_deps_costly
)
19452 insn
= DEP_PRO (dep
);
19453 next
= DEP_CON (dep
);
19455 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
19456 && is_load_insn (next
)
19457 && is_store_insn (insn
))
19458 /* Prevent load after store in the same group. */
19461 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
19462 && is_load_insn (next
)
19463 && is_store_insn (insn
)
19464 && DEP_TYPE (dep
) == REG_DEP_TRUE
)
19465 /* Prevent load after store in the same group if it is a true
19469 /* The flag is set to X; dependences with latency >= X are considered costly,
19470 and will not be scheduled in the same group. */
19471 if (rs6000_sched_costly_dep
<= max_dep_latency
19472 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
19478 /* Return the next insn after INSN that is found before TAIL is reached,
19479 skipping any "non-active" insns - insns that will not actually occupy
19480 an issue slot. Return NULL_RTX if such an insn is not found. */
19483 get_next_active_insn (rtx insn
, rtx tail
)
19485 if (insn
== NULL_RTX
|| insn
== tail
)
19490 insn
= NEXT_INSN (insn
);
19491 if (insn
== NULL_RTX
|| insn
== tail
)
19496 || (NONJUMP_INSN_P (insn
)
19497 && GET_CODE (PATTERN (insn
)) != USE
19498 && GET_CODE (PATTERN (insn
)) != CLOBBER
19499 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
19505 /* We are about to begin issuing insns for this clock cycle. */
19508 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED
, int sched_verbose
,
19509 rtx
*ready ATTRIBUTE_UNUSED
,
19510 int *pn_ready ATTRIBUTE_UNUSED
,
19511 int clock_var ATTRIBUTE_UNUSED
)
19513 int n_ready
= *pn_ready
;
19516 fprintf (dump
, "// rs6000_sched_reorder :\n");
19518 /* Reorder the ready list, if the second to last ready insn
19519 is a nonepipeline insn. */
19520 if (rs6000_cpu_attr
== CPU_CELL
&& n_ready
> 1)
19522 if (is_nonpipeline_insn (ready
[n_ready
- 1])
19523 && (recog_memoized (ready
[n_ready
- 2]) > 0))
19524 /* Simply swap first two insns. */
19526 rtx tmp
= ready
[n_ready
- 1];
19527 ready
[n_ready
- 1] = ready
[n_ready
- 2];
19528 ready
[n_ready
- 2] = tmp
;
19532 if (rs6000_cpu
== PROCESSOR_POWER6
)
19533 load_store_pendulum
= 0;
19535 return rs6000_issue_rate ();
19538 /* Like rs6000_sched_reorder, but called after issuing each insn. */
19541 rs6000_sched_reorder2 (FILE *dump
, int sched_verbose
, rtx
*ready
,
19542 int *pn_ready
, int clock_var ATTRIBUTE_UNUSED
)
19545 fprintf (dump
, "// rs6000_sched_reorder2 :\n");
19547 /* For Power6, we need to handle some special cases to try and keep the
19548 store queue from overflowing and triggering expensive flushes.
19550 This code monitors how load and store instructions are being issued
19551 and skews the ready list one way or the other to increase the likelihood
19552 that a desired instruction is issued at the proper time.
19554 A couple of things are done. First, we maintain a "load_store_pendulum"
19555 to track the current state of load/store issue.
19557 - If the pendulum is at zero, then no loads or stores have been
19558 issued in the current cycle so we do nothing.
19560 - If the pendulum is 1, then a single load has been issued in this
19561 cycle and we attempt to locate another load in the ready list to
19564 - If the pendulum is -2, then two stores have already been
19565 issued in this cycle, so we increase the priority of the first load
19566 in the ready list to increase it's likelihood of being chosen first
19569 - If the pendulum is -1, then a single store has been issued in this
19570 cycle and we attempt to locate another store in the ready list to
19571 issue with it, preferring a store to an adjacent memory location to
19572 facilitate store pairing in the store queue.
19574 - If the pendulum is 2, then two loads have already been
19575 issued in this cycle, so we increase the priority of the first store
19576 in the ready list to increase it's likelihood of being chosen first
19579 - If the pendulum < -2 or > 2, then do nothing.
19581 Note: This code covers the most common scenarios. There exist non
19582 load/store instructions which make use of the LSU and which
19583 would need to be accounted for to strictly model the behavior
19584 of the machine. Those instructions are currently unaccounted
19585 for to help minimize compile time overhead of this code.
19587 if (rs6000_cpu
== PROCESSOR_POWER6
&& last_scheduled_insn
)
19593 if (is_store_insn (last_scheduled_insn
))
19594 /* Issuing a store, swing the load_store_pendulum to the left */
19595 load_store_pendulum
--;
19596 else if (is_load_insn (last_scheduled_insn
))
19597 /* Issuing a load, swing the load_store_pendulum to the right */
19598 load_store_pendulum
++;
19600 return cached_can_issue_more
;
19602 /* If the pendulum is balanced, or there is only one instruction on
19603 the ready list, then all is well, so return. */
19604 if ((load_store_pendulum
== 0) || (*pn_ready
<= 1))
19605 return cached_can_issue_more
;
19607 if (load_store_pendulum
== 1)
19609 /* A load has been issued in this cycle. Scan the ready list
19610 for another load to issue with it */
19615 if (is_load_insn (ready
[pos
]))
19617 /* Found a load. Move it to the head of the ready list,
19618 and adjust it's priority so that it is more likely to
19621 for (i
=pos
; i
<*pn_ready
-1; i
++)
19622 ready
[i
] = ready
[i
+ 1];
19623 ready
[*pn_ready
-1] = tmp
;
19625 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
19626 INSN_PRIORITY (tmp
)++;
19632 else if (load_store_pendulum
== -2)
19634 /* Two stores have been issued in this cycle. Increase the
19635 priority of the first load in the ready list to favor it for
19636 issuing in the next cycle. */
19641 if (is_load_insn (ready
[pos
])
19643 && INSN_PRIORITY_KNOWN (ready
[pos
]))
19645 INSN_PRIORITY (ready
[pos
])++;
19647 /* Adjust the pendulum to account for the fact that a load
19648 was found and increased in priority. This is to prevent
19649 increasing the priority of multiple loads */
19650 load_store_pendulum
--;
19657 else if (load_store_pendulum
== -1)
19659 /* A store has been issued in this cycle. Scan the ready list for
19660 another store to issue with it, preferring a store to an adjacent
19662 int first_store_pos
= -1;
19668 if (is_store_insn (ready
[pos
]))
19670 /* Maintain the index of the first store found on the
19672 if (first_store_pos
== -1)
19673 first_store_pos
= pos
;
19675 if (is_store_insn (last_scheduled_insn
)
19676 && adjacent_mem_locations (last_scheduled_insn
,ready
[pos
]))
19678 /* Found an adjacent store. Move it to the head of the
19679 ready list, and adjust it's priority so that it is
19680 more likely to stay there */
19682 for (i
=pos
; i
<*pn_ready
-1; i
++)
19683 ready
[i
] = ready
[i
+ 1];
19684 ready
[*pn_ready
-1] = tmp
;
19686 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
19687 INSN_PRIORITY (tmp
)++;
19689 first_store_pos
= -1;
19697 if (first_store_pos
>= 0)
19699 /* An adjacent store wasn't found, but a non-adjacent store was,
19700 so move the non-adjacent store to the front of the ready
19701 list, and adjust its priority so that it is more likely to
19703 tmp
= ready
[first_store_pos
];
19704 for (i
=first_store_pos
; i
<*pn_ready
-1; i
++)
19705 ready
[i
] = ready
[i
+ 1];
19706 ready
[*pn_ready
-1] = tmp
;
19707 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp
))
19708 INSN_PRIORITY (tmp
)++;
19711 else if (load_store_pendulum
== 2)
19713 /* Two loads have been issued in this cycle. Increase the priority
19714 of the first store in the ready list to favor it for issuing in
19720 if (is_store_insn (ready
[pos
])
19722 && INSN_PRIORITY_KNOWN (ready
[pos
]))
19724 INSN_PRIORITY (ready
[pos
])++;
19726 /* Adjust the pendulum to account for the fact that a store
19727 was found and increased in priority. This is to prevent
19728 increasing the priority of multiple stores */
19729 load_store_pendulum
++;
19738 return cached_can_issue_more
;
19741 /* Return whether the presence of INSN causes a dispatch group termination
19742 of group WHICH_GROUP.
19744 If WHICH_GROUP == current_group, this function will return true if INSN
19745 causes the termination of the current group (i.e, the dispatch group to
19746 which INSN belongs). This means that INSN will be the last insn in the
19747 group it belongs to.
19749 If WHICH_GROUP == previous_group, this function will return true if INSN
19750 causes the termination of the previous group (i.e, the dispatch group that
19751 precedes the group to which INSN belongs). This means that INSN will be
19752 the first insn in the group it belongs to). */
19755 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
19762 first
= insn_must_be_first_in_group (insn
);
19763 last
= insn_must_be_last_in_group (insn
);
19768 if (which_group
== current_group
)
19770 else if (which_group
== previous_group
)
19778 insn_must_be_first_in_group (rtx insn
)
19780 enum attr_type type
;
19783 || insn
== NULL_RTX
19784 || GET_CODE (insn
) == NOTE
19785 || GET_CODE (PATTERN (insn
)) == USE
19786 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19789 switch (rs6000_cpu
)
19791 case PROCESSOR_POWER5
:
19792 if (is_cracked_insn (insn
))
19794 case PROCESSOR_POWER4
:
19795 if (is_microcoded_insn (insn
))
19798 if (!rs6000_sched_groups
)
19801 type
= get_attr_type (insn
);
19808 case TYPE_DELAYED_CR
:
19809 case TYPE_CR_LOGICAL
:
19823 case PROCESSOR_POWER6
:
19824 type
= get_attr_type (insn
);
19828 case TYPE_INSERT_DWORD
:
19832 case TYPE_VAR_SHIFT_ROTATE
:
19839 case TYPE_INSERT_WORD
:
19840 case TYPE_DELAYED_COMPARE
:
19841 case TYPE_IMUL_COMPARE
:
19842 case TYPE_LMUL_COMPARE
:
19843 case TYPE_FPCOMPARE
:
19854 case TYPE_LOAD_EXT_UX
:
19856 case TYPE_STORE_UX
:
19857 case TYPE_FPLOAD_U
:
19858 case TYPE_FPLOAD_UX
:
19859 case TYPE_FPSTORE_U
:
19860 case TYPE_FPSTORE_UX
:
19874 insn_must_be_last_in_group (rtx insn
)
19876 enum attr_type type
;
19879 || insn
== NULL_RTX
19880 || GET_CODE (insn
) == NOTE
19881 || GET_CODE (PATTERN (insn
)) == USE
19882 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19885 switch (rs6000_cpu
) {
19886 case PROCESSOR_POWER4
:
19887 case PROCESSOR_POWER5
:
19888 if (is_microcoded_insn (insn
))
19891 if (is_branch_slot_insn (insn
))
19895 case PROCESSOR_POWER6
:
19896 type
= get_attr_type (insn
);
19903 case TYPE_VAR_SHIFT_ROTATE
:
19910 case TYPE_DELAYED_COMPARE
:
19911 case TYPE_IMUL_COMPARE
:
19912 case TYPE_LMUL_COMPARE
:
19913 case TYPE_FPCOMPARE
:
19934 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
19935 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
19938 is_costly_group (rtx
*group_insns
, rtx next_insn
)
19941 int issue_rate
= rs6000_issue_rate ();
19943 for (i
= 0; i
< issue_rate
; i
++)
19945 sd_iterator_def sd_it
;
19947 rtx insn
= group_insns
[i
];
19952 FOR_EACH_DEP (insn
, SD_LIST_FORW
, sd_it
, dep
)
19954 rtx next
= DEP_CON (dep
);
19956 if (next
== next_insn
19957 && rs6000_is_costly_dependence (dep
, dep_cost (dep
), 0))
19965 /* Utility of the function redefine_groups.
19966 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
19967 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
19968 to keep it "far" (in a separate group) from GROUP_INSNS, following
19969 one of the following schemes, depending on the value of the flag
19970 -minsert_sched_nops = X:
19971 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
19972 in order to force NEXT_INSN into a separate group.
19973 (2) X < sched_finish_regroup_exact: insert exactly X nops.
19974 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
19975 insertion (has a group just ended, how many vacant issue slots remain in the
19976 last group, and how many dispatch groups were encountered so far). */
19979 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
19980 rtx next_insn
, bool *group_end
, int can_issue_more
,
19985 int issue_rate
= rs6000_issue_rate ();
19986 bool end
= *group_end
;
19989 if (next_insn
== NULL_RTX
)
19990 return can_issue_more
;
19992 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
19993 return can_issue_more
;
19995 force
= is_costly_group (group_insns
, next_insn
);
19997 return can_issue_more
;
19999 if (sched_verbose
> 6)
20000 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
20001 *group_count
,can_issue_more
);
20003 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
20006 can_issue_more
= 0;
20008 /* Since only a branch can be issued in the last issue_slot, it is
20009 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
20010 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
20011 in this case the last nop will start a new group and the branch
20012 will be forced to the new group. */
20013 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
20016 while (can_issue_more
> 0)
20019 emit_insn_before (nop
, next_insn
);
20027 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
20029 int n_nops
= rs6000_sched_insert_nops
;
20031 /* Nops can't be issued from the branch slot, so the effective
20032 issue_rate for nops is 'issue_rate - 1'. */
20033 if (can_issue_more
== 0)
20034 can_issue_more
= issue_rate
;
20036 if (can_issue_more
== 0)
20038 can_issue_more
= issue_rate
- 1;
20041 for (i
= 0; i
< issue_rate
; i
++)
20043 group_insns
[i
] = 0;
20050 emit_insn_before (nop
, next_insn
);
20051 if (can_issue_more
== issue_rate
- 1) /* new group begins */
20054 if (can_issue_more
== 0)
20056 can_issue_more
= issue_rate
- 1;
20059 for (i
= 0; i
< issue_rate
; i
++)
20061 group_insns
[i
] = 0;
20067 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
20070 /* Is next_insn going to start a new group? */
20073 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
20074 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
20075 || (can_issue_more
< issue_rate
&&
20076 insn_terminates_group_p (next_insn
, previous_group
)));
20077 if (*group_end
&& end
)
20080 if (sched_verbose
> 6)
20081 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
20082 *group_count
, can_issue_more
);
20083 return can_issue_more
;
20086 return can_issue_more
;
20089 /* This function tries to synch the dispatch groups that the compiler "sees"
20090 with the dispatch groups that the processor dispatcher is expected to
20091 form in practice. It tries to achieve this synchronization by forcing the
20092 estimated processor grouping on the compiler (as opposed to the function
20093 'pad_goups' which tries to force the scheduler's grouping on the processor).
20095 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
20096 examines the (estimated) dispatch groups that will be formed by the processor
20097 dispatcher. It marks these group boundaries to reflect the estimated
20098 processor grouping, overriding the grouping that the scheduler had marked.
20099 Depending on the value of the flag '-minsert-sched-nops' this function can
20100 force certain insns into separate groups or force a certain distance between
20101 them by inserting nops, for example, if there exists a "costly dependence"
20104 The function estimates the group boundaries that the processor will form as
20105 follows: It keeps track of how many vacant issue slots are available after
20106 each insn. A subsequent insn will start a new group if one of the following
20108 - no more vacant issue slots remain in the current dispatch group.
20109 - only the last issue slot, which is the branch slot, is vacant, but the next
20110 insn is not a branch.
20111 - only the last 2 or less issue slots, including the branch slot, are vacant,
20112 which means that a cracked insn (which occupies two issue slots) can't be
20113 issued in this group.
20114 - less than 'issue_rate' slots are vacant, and the next insn always needs to
20115 start a new group. */
20118 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
20120 rtx insn
, next_insn
;
20122 int can_issue_more
;
20125 int group_count
= 0;
20129 issue_rate
= rs6000_issue_rate ();
20130 group_insns
= XALLOCAVEC (rtx
, issue_rate
);
20131 for (i
= 0; i
< issue_rate
; i
++)
20133 group_insns
[i
] = 0;
20135 can_issue_more
= issue_rate
;
20137 insn
= get_next_active_insn (prev_head_insn
, tail
);
20140 while (insn
!= NULL_RTX
)
20142 slot
= (issue_rate
- can_issue_more
);
20143 group_insns
[slot
] = insn
;
20145 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
20146 if (insn_terminates_group_p (insn
, current_group
))
20147 can_issue_more
= 0;
20149 next_insn
= get_next_active_insn (insn
, tail
);
20150 if (next_insn
== NULL_RTX
)
20151 return group_count
+ 1;
20153 /* Is next_insn going to start a new group? */
20155 = (can_issue_more
== 0
20156 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
20157 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
20158 || (can_issue_more
< issue_rate
&&
20159 insn_terminates_group_p (next_insn
, previous_group
)));
20161 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
20162 next_insn
, &group_end
, can_issue_more
,
20168 can_issue_more
= 0;
20169 for (i
= 0; i
< issue_rate
; i
++)
20171 group_insns
[i
] = 0;
20175 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
20176 PUT_MODE (next_insn
, VOIDmode
);
20177 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
20178 PUT_MODE (next_insn
, TImode
);
20181 if (can_issue_more
== 0)
20182 can_issue_more
= issue_rate
;
20185 return group_count
;
20188 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
20189 dispatch group boundaries that the scheduler had marked. Pad with nops
20190 any dispatch groups which have vacant issue slots, in order to force the
20191 scheduler's grouping on the processor dispatcher. The function
20192 returns the number of dispatch groups found. */
20195 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
20197 rtx insn
, next_insn
;
20200 int can_issue_more
;
20202 int group_count
= 0;
20204 /* Initialize issue_rate. */
20205 issue_rate
= rs6000_issue_rate ();
20206 can_issue_more
= issue_rate
;
20208 insn
= get_next_active_insn (prev_head_insn
, tail
);
20209 next_insn
= get_next_active_insn (insn
, tail
);
20211 while (insn
!= NULL_RTX
)
20214 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
20216 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
20218 if (next_insn
== NULL_RTX
)
20223 /* If the scheduler had marked group termination at this location
20224 (between insn and next_insn), and neither insn nor next_insn will
20225 force group termination, pad the group with nops to force group
20228 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
20229 && !insn_terminates_group_p (insn
, current_group
)
20230 && !insn_terminates_group_p (next_insn
, previous_group
))
20232 if (!is_branch_slot_insn (next_insn
))
20235 while (can_issue_more
)
20238 emit_insn_before (nop
, next_insn
);
20243 can_issue_more
= issue_rate
;
20248 next_insn
= get_next_active_insn (insn
, tail
);
20251 return group_count
;
20254 /* We're beginning a new block. Initialize data structures as necessary. */
20257 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED
,
20258 int sched_verbose ATTRIBUTE_UNUSED
,
20259 int max_ready ATTRIBUTE_UNUSED
)
20261 last_scheduled_insn
= NULL_RTX
;
20262 load_store_pendulum
= 0;
20265 /* The following function is called at the end of scheduling BB.
20266 After reload, it inserts nops at insn group bundling. */
20269 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
20274 fprintf (dump
, "=== Finishing schedule.\n");
20276 if (reload_completed
&& rs6000_sched_groups
)
20278 /* Do not run sched_finish hook when selective scheduling enabled. */
20279 if (sel_sched_p ())
20282 if (rs6000_sched_insert_nops
== sched_finish_none
)
20285 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
20286 n_groups
= pad_groups (dump
, sched_verbose
,
20287 current_sched_info
->prev_head
,
20288 current_sched_info
->next_tail
);
20290 n_groups
= redefine_groups (dump
, sched_verbose
,
20291 current_sched_info
->prev_head
,
20292 current_sched_info
->next_tail
);
20294 if (sched_verbose
>= 6)
20296 fprintf (dump
, "ngroups = %d\n", n_groups
);
20297 print_rtl (dump
, current_sched_info
->prev_head
);
20298 fprintf (dump
, "Done finish_sched\n");
20303 struct _rs6000_sched_context
20305 short cached_can_issue_more
;
20306 rtx last_scheduled_insn
;
20307 int load_store_pendulum
;
20310 typedef struct _rs6000_sched_context rs6000_sched_context_def
;
20311 typedef rs6000_sched_context_def
*rs6000_sched_context_t
;
20313 /* Allocate store for new scheduling context. */
20315 rs6000_alloc_sched_context (void)
20317 return xmalloc (sizeof (rs6000_sched_context_def
));
20320 /* If CLEAN_P is true then initializes _SC with clean data,
20321 and from the global context otherwise. */
20323 rs6000_init_sched_context (void *_sc
, bool clean_p
)
20325 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
20329 sc
->cached_can_issue_more
= 0;
20330 sc
->last_scheduled_insn
= NULL_RTX
;
20331 sc
->load_store_pendulum
= 0;
20335 sc
->cached_can_issue_more
= cached_can_issue_more
;
20336 sc
->last_scheduled_insn
= last_scheduled_insn
;
20337 sc
->load_store_pendulum
= load_store_pendulum
;
20341 /* Sets the global scheduling context to the one pointed to by _SC. */
20343 rs6000_set_sched_context (void *_sc
)
20345 rs6000_sched_context_t sc
= (rs6000_sched_context_t
) _sc
;
20347 gcc_assert (sc
!= NULL
);
20349 cached_can_issue_more
= sc
->cached_can_issue_more
;
20350 last_scheduled_insn
= sc
->last_scheduled_insn
;
20351 load_store_pendulum
= sc
->load_store_pendulum
;
20356 rs6000_free_sched_context (void *_sc
)
20358 gcc_assert (_sc
!= NULL
);
20364 /* Length in units of the trampoline for entering a nested function. */
20367 rs6000_trampoline_size (void)
20371 switch (DEFAULT_ABI
)
20374 gcc_unreachable ();
20377 ret
= (TARGET_32BIT
) ? 12 : 24;
20382 ret
= (TARGET_32BIT
) ? 40 : 48;
20389 /* Emit RTL insns to initialize the variable parts of a trampoline.
20390 FNADDR is an RTX for the address of the function's pure code.
20391 CXT is an RTX for the static chain value for the function. */
20394 rs6000_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
20396 int regsize
= (TARGET_32BIT
) ? 4 : 8;
20397 rtx ctx_reg
= force_reg (Pmode
, cxt
);
20399 switch (DEFAULT_ABI
)
20402 gcc_unreachable ();
20404 /* Macros to shorten the code expansions below. */
20405 #define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
20406 #define MEM_PLUS(addr,offset) \
20407 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
20409 /* Under AIX, just build the 3 word function descriptor */
20412 rtx fn_reg
= gen_reg_rtx (Pmode
);
20413 rtx toc_reg
= gen_reg_rtx (Pmode
);
20414 emit_move_insn (fn_reg
, MEM_DEREF (fnaddr
));
20415 emit_move_insn (toc_reg
, MEM_PLUS (fnaddr
, regsize
));
20416 emit_move_insn (MEM_DEREF (addr
), fn_reg
);
20417 emit_move_insn (MEM_PLUS (addr
, regsize
), toc_reg
);
20418 emit_move_insn (MEM_PLUS (addr
, 2*regsize
), ctx_reg
);
20422 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
20425 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__trampoline_setup"),
20426 FALSE
, VOIDmode
, 4,
20428 GEN_INT (rs6000_trampoline_size ()), SImode
,
20438 /* Table of valid machine attributes. */
20440 const struct attribute_spec rs6000_attribute_table
[] =
20442 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
20443 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
},
20444 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
20445 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
20446 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
20447 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
20448 #ifdef SUBTARGET_ATTRIBUTE_TABLE
20449 SUBTARGET_ATTRIBUTE_TABLE
,
20451 { NULL
, 0, 0, false, false, false, NULL
}
20454 /* Handle the "altivec" attribute. The attribute may have
20455 arguments as follows:
20457 __attribute__((altivec(vector__)))
20458 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
20459 __attribute__((altivec(bool__))) (always followed by 'unsigned')
20461 and may appear more than once (e.g., 'vector bool char') in a
20462 given declaration. */
20465 rs6000_handle_altivec_attribute (tree
*node
,
20466 tree name ATTRIBUTE_UNUSED
,
20468 int flags ATTRIBUTE_UNUSED
,
20469 bool *no_add_attrs
)
20471 tree type
= *node
, result
= NULL_TREE
;
20472 enum machine_mode mode
;
20475 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
20476 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
20477 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
20480 while (POINTER_TYPE_P (type
)
20481 || TREE_CODE (type
) == FUNCTION_TYPE
20482 || TREE_CODE (type
) == METHOD_TYPE
20483 || TREE_CODE (type
) == ARRAY_TYPE
)
20484 type
= TREE_TYPE (type
);
20486 mode
= TYPE_MODE (type
);
20488 /* Check for invalid AltiVec type qualifiers. */
20489 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
20492 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
20493 else if (rs6000_warn_altivec_long
)
20494 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
20496 else if (type
== long_long_unsigned_type_node
20497 || type
== long_long_integer_type_node
)
20498 error ("use of %<long long%> in AltiVec types is invalid");
20499 else if (type
== double_type_node
)
20500 error ("use of %<double%> in AltiVec types is invalid");
20501 else if (type
== long_double_type_node
)
20502 error ("use of %<long double%> in AltiVec types is invalid");
20503 else if (type
== boolean_type_node
)
20504 error ("use of boolean types in AltiVec types is invalid");
20505 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
20506 error ("use of %<complex%> in AltiVec types is invalid");
20507 else if (DECIMAL_FLOAT_MODE_P (mode
))
20508 error ("use of decimal floating point types in AltiVec types is invalid");
20510 switch (altivec_type
)
20513 unsigned_p
= TYPE_UNSIGNED (type
);
20517 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
20520 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
20523 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
20525 case SFmode
: result
= V4SF_type_node
; break;
20526 /* If the user says 'vector int bool', we may be handed the 'bool'
20527 attribute _before_ the 'vector' attribute, and so select the
20528 proper type in the 'b' case below. */
20529 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
20537 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
20538 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
20539 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
20546 case V8HImode
: result
= pixel_V8HI_type_node
;
20552 /* Propagate qualifiers attached to the element type
20553 onto the vector type. */
20554 if (result
&& result
!= type
&& TYPE_QUALS (type
))
20555 result
= build_qualified_type (result
, TYPE_QUALS (type
));
20557 *no_add_attrs
= true; /* No need to hang on to the attribute. */
20560 *node
= lang_hooks
.types
.reconstruct_complex_type (*node
, result
);
20565 /* AltiVec defines four built-in scalar types that serve as vector
20566 elements; we must teach the compiler how to mangle them. */
20568 static const char *
20569 rs6000_mangle_type (const_tree type
)
20571 type
= TYPE_MAIN_VARIANT (type
);
20573 if (TREE_CODE (type
) != VOID_TYPE
&& TREE_CODE (type
) != BOOLEAN_TYPE
20574 && TREE_CODE (type
) != INTEGER_TYPE
&& TREE_CODE (type
) != REAL_TYPE
)
20577 if (type
== bool_char_type_node
) return "U6__boolc";
20578 if (type
== bool_short_type_node
) return "U6__bools";
20579 if (type
== pixel_type_node
) return "u7__pixel";
20580 if (type
== bool_int_type_node
) return "U6__booli";
20582 /* Mangle IBM extended float long double as `g' (__float128) on
20583 powerpc*-linux where long-double-64 previously was the default. */
20584 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
20586 && TARGET_LONG_DOUBLE_128
20587 && !TARGET_IEEEQUAD
)
20590 /* For all other types, use normal C++ mangling. */
20594 /* Handle a "longcall" or "shortcall" attribute; arguments as in
20595 struct attribute_spec.handler. */
20598 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
20599 tree args ATTRIBUTE_UNUSED
,
20600 int flags ATTRIBUTE_UNUSED
,
20601 bool *no_add_attrs
)
20603 if (TREE_CODE (*node
) != FUNCTION_TYPE
20604 && TREE_CODE (*node
) != FIELD_DECL
20605 && TREE_CODE (*node
) != TYPE_DECL
)
20607 warning (OPT_Wattributes
, "%qs attribute only applies to functions",
20608 IDENTIFIER_POINTER (name
));
20609 *no_add_attrs
= true;
20615 /* Set longcall attributes on all functions declared when
20616 rs6000_default_long_calls is true. */
20618 rs6000_set_default_type_attributes (tree type
)
20620 if (rs6000_default_long_calls
20621 && (TREE_CODE (type
) == FUNCTION_TYPE
20622 || TREE_CODE (type
) == METHOD_TYPE
))
20623 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
20625 TYPE_ATTRIBUTES (type
));
20628 darwin_set_default_type_attributes (type
);
20632 /* Return a reference suitable for calling a function with the
20633 longcall attribute. */
20636 rs6000_longcall_ref (rtx call_ref
)
20638 const char *call_name
;
20641 if (GET_CODE (call_ref
) != SYMBOL_REF
)
20644 /* System V adds '.' to the internal name, so skip them. */
20645 call_name
= XSTR (call_ref
, 0);
20646 if (*call_name
== '.')
20648 while (*call_name
== '.')
20651 node
= get_identifier (call_name
);
20652 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
20655 return force_reg (Pmode
, call_ref
);
20658 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
20659 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
20662 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
20663 struct attribute_spec.handler. */
20665 rs6000_handle_struct_attribute (tree
*node
, tree name
,
20666 tree args ATTRIBUTE_UNUSED
,
20667 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
20670 if (DECL_P (*node
))
20672 if (TREE_CODE (*node
) == TYPE_DECL
)
20673 type
= &TREE_TYPE (*node
);
20678 if (!(type
&& (TREE_CODE (*type
) == RECORD_TYPE
20679 || TREE_CODE (*type
) == UNION_TYPE
)))
20681 warning (OPT_Wattributes
, "%qs attribute ignored", IDENTIFIER_POINTER (name
));
20682 *no_add_attrs
= true;
20685 else if ((is_attribute_p ("ms_struct", name
)
20686 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type
)))
20687 || ((is_attribute_p ("gcc_struct", name
)
20688 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type
)))))
20690 warning (OPT_Wattributes
, "%qs incompatible attribute ignored",
20691 IDENTIFIER_POINTER (name
));
20692 *no_add_attrs
= true;
20699 rs6000_ms_bitfield_layout_p (const_tree record_type
)
20701 return (TARGET_USE_MS_BITFIELD_LAYOUT
&&
20702 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type
)))
20703 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type
));
20706 #ifdef USING_ELFOS_H
20708 /* A get_unnamed_section callback, used for switching to toc_section. */
20711 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
20713 if (DEFAULT_ABI
== ABI_AIX
20714 && TARGET_MINIMAL_TOC
20715 && !TARGET_RELOCATABLE
)
20717 if (!toc_initialized
)
20719 toc_initialized
= 1;
20720 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
20721 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LCTOC", 0);
20722 fprintf (asm_out_file
, "\t.tc ");
20723 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1[TC],");
20724 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
20725 fprintf (asm_out_file
, "\n");
20727 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
20728 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
20729 fprintf (asm_out_file
, " = .+32768\n");
20732 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
20734 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_RELOCATABLE
)
20735 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
20738 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
20739 if (!toc_initialized
)
20741 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
20742 fprintf (asm_out_file
, " = .+32768\n");
20743 toc_initialized
= 1;
20748 /* Implement TARGET_ASM_INIT_SECTIONS. */
20751 rs6000_elf_asm_init_sections (void)
20754 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op
, NULL
);
20757 = get_unnamed_section (SECTION_WRITE
, output_section_asm_op
,
20758 SDATA2_SECTION_ASM_OP
);
20761 /* Implement TARGET_SELECT_RTX_SECTION. */
20764 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
20765 unsigned HOST_WIDE_INT align
)
20767 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
20768 return toc_section
;
20770 return default_elf_select_rtx_section (mode
, x
, align
);
20773 /* For a SYMBOL_REF, set generic flags and then perform some
20774 target-specific processing.
20776 When the AIX ABI is requested on a non-AIX system, replace the
20777 function name with the real name (with a leading .) rather than the
20778 function descriptor name. This saves a lot of overriding code to
20779 read the prefixes. */
20782 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
20784 default_encode_section_info (decl
, rtl
, first
);
20787 && TREE_CODE (decl
) == FUNCTION_DECL
20789 && DEFAULT_ABI
== ABI_AIX
)
20791 rtx sym_ref
= XEXP (rtl
, 0);
20792 size_t len
= strlen (XSTR (sym_ref
, 0));
20793 char *str
= XALLOCAVEC (char, len
+ 2);
20795 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
20796 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
20801 compare_section_name (const char *section
, const char *templ
)
20805 len
= strlen (templ
);
20806 return (strncmp (section
, templ
, len
) == 0
20807 && (section
[len
] == 0 || section
[len
] == '.'));
20811 rs6000_elf_in_small_data_p (const_tree decl
)
20813 if (rs6000_sdata
== SDATA_NONE
)
20816 /* We want to merge strings, so we never consider them small data. */
20817 if (TREE_CODE (decl
) == STRING_CST
)
20820 /* Functions are never in the small data area. */
20821 if (TREE_CODE (decl
) == FUNCTION_DECL
)
20824 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
20826 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
20827 if (compare_section_name (section
, ".sdata")
20828 || compare_section_name (section
, ".sdata2")
20829 || compare_section_name (section
, ".gnu.linkonce.s")
20830 || compare_section_name (section
, ".sbss")
20831 || compare_section_name (section
, ".sbss2")
20832 || compare_section_name (section
, ".gnu.linkonce.sb")
20833 || strcmp (section
, ".PPC.EMB.sdata0") == 0
20834 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
20839 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
20842 && (unsigned HOST_WIDE_INT
) size
<= g_switch_value
20843 /* If it's not public, and we're not going to reference it there,
20844 there's no need to put it in the small data section. */
20845 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
20852 #endif /* USING_ELFOS_H */
20854 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
20857 rs6000_use_blocks_for_constant_p (enum machine_mode mode
, const_rtx x
)
20859 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
);
20862 /* Return a REG that occurs in ADDR with coefficient 1.
20863 ADDR can be effectively incremented by incrementing REG.
20865 r0 is special and we must not select it as an address
20866 register by this routine since our caller will try to
20867 increment the returned register via an "la" instruction. */
20870 find_addr_reg (rtx addr
)
20872 while (GET_CODE (addr
) == PLUS
)
20874 if (GET_CODE (XEXP (addr
, 0)) == REG
20875 && REGNO (XEXP (addr
, 0)) != 0)
20876 addr
= XEXP (addr
, 0);
20877 else if (GET_CODE (XEXP (addr
, 1)) == REG
20878 && REGNO (XEXP (addr
, 1)) != 0)
20879 addr
= XEXP (addr
, 1);
20880 else if (CONSTANT_P (XEXP (addr
, 0)))
20881 addr
= XEXP (addr
, 1);
20882 else if (CONSTANT_P (XEXP (addr
, 1)))
20883 addr
= XEXP (addr
, 0);
20885 gcc_unreachable ();
20887 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
20892 rs6000_fatal_bad_address (rtx op
)
20894 fatal_insn ("bad address", op
);
20899 static tree branch_island_list
= 0;
20901 /* Remember to generate a branch island for far calls to the given
20905 add_compiler_branch_island (tree label_name
, tree function_name
,
20908 tree branch_island
= build_tree_list (function_name
, label_name
);
20909 TREE_TYPE (branch_island
) = build_int_cst (NULL_TREE
, line_number
);
20910 TREE_CHAIN (branch_island
) = branch_island_list
;
20911 branch_island_list
= branch_island
;
20914 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
20915 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
20916 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
20917 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
20919 /* Generate far-jump branch islands for everything on the
20920 branch_island_list. Invoked immediately after the last instruction
20921 of the epilogue has been emitted; the branch-islands must be
20922 appended to, and contiguous with, the function body. Mach-O stubs
20923 are generated in machopic_output_stub(). */
20926 macho_branch_islands (void)
20929 tree branch_island
;
20931 for (branch_island
= branch_island_list
;
20933 branch_island
= TREE_CHAIN (branch_island
))
20935 const char *label
=
20936 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island
));
20938 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island
));
20939 char name_buf
[512];
20940 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
20941 if (name
[0] == '*' || name
[0] == '&')
20942 strcpy (name_buf
, name
+1);
20946 strcpy (name_buf
+1, name
);
20948 strcpy (tmp_buf
, "\n");
20949 strcat (tmp_buf
, label
);
20950 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
20951 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
20952 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
20953 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
20956 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
20957 strcat (tmp_buf
, label
);
20958 strcat (tmp_buf
, "_pic\n");
20959 strcat (tmp_buf
, label
);
20960 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
20962 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
20963 strcat (tmp_buf
, name_buf
);
20964 strcat (tmp_buf
, " - ");
20965 strcat (tmp_buf
, label
);
20966 strcat (tmp_buf
, "_pic)\n");
20968 strcat (tmp_buf
, "\tmtlr r0\n");
20970 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
20971 strcat (tmp_buf
, name_buf
);
20972 strcat (tmp_buf
, " - ");
20973 strcat (tmp_buf
, label
);
20974 strcat (tmp_buf
, "_pic)\n");
20976 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
20980 strcat (tmp_buf
, ":\nlis r12,hi16(");
20981 strcat (tmp_buf
, name_buf
);
20982 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
20983 strcat (tmp_buf
, name_buf
);
20984 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
20986 output_asm_insn (tmp_buf
, 0);
20987 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
20988 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
20989 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
20990 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
20993 branch_island_list
= 0;
20996 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
20997 already there or not. */
21000 no_previous_def (tree function_name
)
21002 tree branch_island
;
21003 for (branch_island
= branch_island_list
;
21005 branch_island
= TREE_CHAIN (branch_island
))
21006 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
21011 /* GET_PREV_LABEL gets the label name from the previous definition of
21015 get_prev_label (tree function_name
)
21017 tree branch_island
;
21018 for (branch_island
= branch_island_list
;
21020 branch_island
= TREE_CHAIN (branch_island
))
21021 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
21022 return BRANCH_ISLAND_LABEL_NAME (branch_island
);
21026 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
21027 #define DARWIN_LINKER_GENERATES_ISLANDS 0
21030 /* KEXTs still need branch islands. */
21031 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
21032 || flag_mkernel || flag_apple_kext)
21034 /* INSN is either a function call or a millicode call. It may have an
21035 unconditional jump in its delay slot.
21037 CALL_DEST is the routine we are calling. */
21040 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
21041 int cookie_operand_number
)
21043 static char buf
[256];
21044 if (DARWIN_GENERATE_ISLANDS
21045 && GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
21046 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
21049 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
21051 if (no_previous_def (funname
))
21053 rtx label_rtx
= gen_label_rtx ();
21054 char *label_buf
, temp_buf
[256];
21055 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
21056 CODE_LABEL_NUMBER (label_rtx
));
21057 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
21058 labelname
= get_identifier (label_buf
);
21059 add_compiler_branch_island (labelname
, funname
, insn_line (insn
));
21062 labelname
= get_prev_label (funname
);
21064 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
21065 instruction will reach 'foo', otherwise link as 'bl L42'".
21066 "L42" should be a 'branch island', that will do a far jump to
21067 'foo'. Branch islands are generated in
21068 macho_branch_islands(). */
21069 sprintf (buf
, "jbsr %%z%d,%.246s",
21070 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
21073 sprintf (buf
, "bl %%z%d", dest_operand_number
);
21077 /* Generate PIC and indirect symbol stubs. */
21080 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
21082 unsigned int length
;
21083 char *symbol_name
, *lazy_ptr_name
;
21084 char *local_label_0
;
21085 static int label
= 0;
21087 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
21088 symb
= (*targetm
.strip_name_encoding
) (symb
);
21091 length
= strlen (symb
);
21092 symbol_name
= XALLOCAVEC (char, length
+ 32);
21093 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
21095 lazy_ptr_name
= XALLOCAVEC (char, length
+ 32);
21096 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
21099 switch_to_section (darwin_sections
[machopic_picsymbol_stub1_section
]);
21101 switch_to_section (darwin_sections
[machopic_symbol_stub1_section
]);
21105 fprintf (file
, "\t.align 5\n");
21107 fprintf (file
, "%s:\n", stub
);
21108 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
21111 local_label_0
= XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
21112 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
21114 fprintf (file
, "\tmflr r0\n");
21115 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
21116 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
21117 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
21118 lazy_ptr_name
, local_label_0
);
21119 fprintf (file
, "\tmtlr r0\n");
21120 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
21121 (TARGET_64BIT
? "ldu" : "lwzu"),
21122 lazy_ptr_name
, local_label_0
);
21123 fprintf (file
, "\tmtctr r12\n");
21124 fprintf (file
, "\tbctr\n");
21128 fprintf (file
, "\t.align 4\n");
21130 fprintf (file
, "%s:\n", stub
);
21131 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
21133 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
21134 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
21135 (TARGET_64BIT
? "ldu" : "lwzu"),
21137 fprintf (file
, "\tmtctr r12\n");
21138 fprintf (file
, "\tbctr\n");
21141 switch_to_section (darwin_sections
[machopic_lazy_symbol_ptr_section
]);
21142 fprintf (file
, "%s:\n", lazy_ptr_name
);
21143 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
21144 fprintf (file
, "%sdyld_stub_binding_helper\n",
21145 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
21148 /* Legitimize PIC addresses. If the address is already
21149 position-independent, we return ORIG. Newly generated
21150 position-independent addresses go into a reg. This is REG if non
21151 zero, otherwise we allocate register(s) as necessary. */
21153 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
21156 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
21161 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
21162 reg
= gen_reg_rtx (Pmode
);
21164 if (GET_CODE (orig
) == CONST
)
21168 if (GET_CODE (XEXP (orig
, 0)) == PLUS
21169 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
21172 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
21174 /* Use a different reg for the intermediate value, as
21175 it will be marked UNCHANGING. */
21176 reg_temp
= !can_create_pseudo_p () ? reg
: gen_reg_rtx (Pmode
);
21177 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
21180 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
21183 if (GET_CODE (offset
) == CONST_INT
)
21185 if (SMALL_INT (offset
))
21186 return plus_constant (base
, INTVAL (offset
));
21187 else if (! reload_in_progress
&& ! reload_completed
)
21188 offset
= force_reg (Pmode
, offset
);
21191 rtx mem
= force_const_mem (Pmode
, orig
);
21192 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
21195 return gen_rtx_PLUS (Pmode
, base
, offset
);
21198 /* Fall back on generic machopic code. */
21199 return machopic_legitimize_pic_address (orig
, mode
, reg
);
21202 /* Output a .machine directive for the Darwin assembler, and call
21203 the generic start_file routine. */
21206 rs6000_darwin_file_start (void)
21208 static const struct
21214 { "ppc64", "ppc64", MASK_64BIT
},
21215 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
21216 { "power4", "ppc970", 0 },
21217 { "G5", "ppc970", 0 },
21218 { "7450", "ppc7450", 0 },
21219 { "7400", "ppc7400", MASK_ALTIVEC
},
21220 { "G4", "ppc7400", 0 },
21221 { "750", "ppc750", 0 },
21222 { "740", "ppc750", 0 },
21223 { "G3", "ppc750", 0 },
21224 { "604e", "ppc604e", 0 },
21225 { "604", "ppc604", 0 },
21226 { "603e", "ppc603", 0 },
21227 { "603", "ppc603", 0 },
21228 { "601", "ppc601", 0 },
21229 { NULL
, "ppc", 0 } };
21230 const char *cpu_id
= "";
21233 rs6000_file_start ();
21234 darwin_file_start ();
21236 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
21237 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
21238 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
21239 && rs6000_select
[i
].string
[0] != '\0')
21240 cpu_id
= rs6000_select
[i
].string
;
21242 /* Look through the mapping array. Pick the first name that either
21243 matches the argument, has a bit set in IF_SET that is also set
21244 in the target flags, or has a NULL name. */
21247 while (mapping
[i
].arg
!= NULL
21248 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
21249 && (mapping
[i
].if_set
& target_flags
) == 0)
21252 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
21255 #endif /* TARGET_MACHO */
21259 rs6000_elf_reloc_rw_mask (void)
21263 else if (DEFAULT_ABI
== ABI_AIX
)
21269 /* Record an element in the table of global constructors. SYMBOL is
21270 a SYMBOL_REF of the function to be called; PRIORITY is a number
21271 between 0 and MAX_INIT_PRIORITY.
21273 This differs from default_named_section_asm_out_constructor in
21274 that we have special handling for -mrelocatable. */
21277 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
21279 const char *section
= ".ctors";
21282 if (priority
!= DEFAULT_INIT_PRIORITY
)
21284 sprintf (buf
, ".ctors.%.5u",
21285 /* Invert the numbering so the linker puts us in the proper
21286 order; constructors are run from right to left, and the
21287 linker sorts in increasing order. */
21288 MAX_INIT_PRIORITY
- priority
);
21292 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
21293 assemble_align (POINTER_SIZE
);
21295 if (TARGET_RELOCATABLE
)
21297 fputs ("\t.long (", asm_out_file
);
21298 output_addr_const (asm_out_file
, symbol
);
21299 fputs (")@fixup\n", asm_out_file
);
21302 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
21306 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
21308 const char *section
= ".dtors";
21311 if (priority
!= DEFAULT_INIT_PRIORITY
)
21313 sprintf (buf
, ".dtors.%.5u",
21314 /* Invert the numbering so the linker puts us in the proper
21315 order; constructors are run from right to left, and the
21316 linker sorts in increasing order. */
21317 MAX_INIT_PRIORITY
- priority
);
21321 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
21322 assemble_align (POINTER_SIZE
);
21324 if (TARGET_RELOCATABLE
)
21326 fputs ("\t.long (", asm_out_file
);
21327 output_addr_const (asm_out_file
, symbol
);
21328 fputs (")@fixup\n", asm_out_file
);
21331 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
21335 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
21339 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
21340 ASM_OUTPUT_LABEL (file
, name
);
21341 fputs (DOUBLE_INT_ASM_OP
, file
);
21342 rs6000_output_function_entry (file
, name
);
21343 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
21346 fputs ("\t.size\t", file
);
21347 assemble_name (file
, name
);
21348 fputs (",24\n\t.type\t.", file
);
21349 assemble_name (file
, name
);
21350 fputs (",@function\n", file
);
21351 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
21353 fputs ("\t.globl\t.", file
);
21354 assemble_name (file
, name
);
21359 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
21360 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
21361 rs6000_output_function_entry (file
, name
);
21362 fputs (":\n", file
);
21366 if (TARGET_RELOCATABLE
21367 && !TARGET_SECURE_PLT
21368 && (get_pool_size () != 0 || crtl
->profile
)
21373 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
21375 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
21376 fprintf (file
, "\t.long ");
21377 assemble_name (file
, buf
);
21379 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
21380 assemble_name (file
, buf
);
21384 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
21385 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
21387 if (DEFAULT_ABI
== ABI_AIX
)
21389 const char *desc_name
, *orig_name
;
21391 orig_name
= (*targetm
.strip_name_encoding
) (name
);
21392 desc_name
= orig_name
;
21393 while (*desc_name
== '.')
21396 if (TREE_PUBLIC (decl
))
21397 fprintf (file
, "\t.globl %s\n", desc_name
);
21399 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
21400 fprintf (file
, "%s:\n", desc_name
);
21401 fprintf (file
, "\t.long %s\n", orig_name
);
21402 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
21403 if (DEFAULT_ABI
== ABI_AIX
)
21404 fputs ("\t.long 0\n", file
);
21405 fprintf (file
, "\t.previous\n");
21407 ASM_OUTPUT_LABEL (file
, name
);
21411 rs6000_elf_end_indicate_exec_stack (void)
21414 file_end_indicate_exec_stack ();
21420 rs6000_xcoff_asm_output_anchor (rtx symbol
)
21424 sprintf (buffer
, "$ + " HOST_WIDE_INT_PRINT_DEC
,
21425 SYMBOL_REF_BLOCK_OFFSET (symbol
));
21426 ASM_OUTPUT_DEF (asm_out_file
, XSTR (symbol
, 0), buffer
);
21430 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
21432 fputs (GLOBAL_ASM_OP
, stream
);
21433 RS6000_OUTPUT_BASENAME (stream
, name
);
21434 putc ('\n', stream
);
21437 /* A get_unnamed_decl callback, used for read-only sections. PTR
21438 points to the section string variable. */
21441 rs6000_xcoff_output_readonly_section_asm_op (const void *directive
)
21443 fprintf (asm_out_file
, "\t.csect %s[RO],%s\n",
21444 *(const char *const *) directive
,
21445 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
21448 /* Likewise for read-write sections. */
21451 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive
)
21453 fprintf (asm_out_file
, "\t.csect %s[RW],%s\n",
21454 *(const char *const *) directive
,
21455 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
21458 /* A get_unnamed_section callback, used for switching to toc_section. */
21461 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
21463 if (TARGET_MINIMAL_TOC
)
21465 /* toc_section is always selected at least once from
21466 rs6000_xcoff_file_start, so this is guaranteed to
21467 always be defined once and only once in each file. */
21468 if (!toc_initialized
)
21470 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file
);
21471 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file
);
21472 toc_initialized
= 1;
21474 fprintf (asm_out_file
, "\t.csect toc_table[RW]%s\n",
21475 (TARGET_32BIT
? "" : ",3"));
21478 fputs ("\t.toc\n", asm_out_file
);
21481 /* Implement TARGET_ASM_INIT_SECTIONS. */
21484 rs6000_xcoff_asm_init_sections (void)
21486 read_only_data_section
21487 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
21488 &xcoff_read_only_section_name
);
21490 private_data_section
21491 = get_unnamed_section (SECTION_WRITE
,
21492 rs6000_xcoff_output_readwrite_section_asm_op
,
21493 &xcoff_private_data_section_name
);
21495 read_only_private_data_section
21496 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
21497 &xcoff_private_data_section_name
);
21500 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op
, NULL
);
21502 readonly_data_section
= read_only_data_section
;
21503 exception_section
= data_section
;
21507 rs6000_xcoff_reloc_rw_mask (void)
21513 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
21514 tree decl ATTRIBUTE_UNUSED
)
21517 static const char * const suffix
[3] = { "PR", "RO", "RW" };
21519 if (flags
& SECTION_CODE
)
21521 else if (flags
& SECTION_WRITE
)
21526 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
21527 (flags
& SECTION_CODE
) ? "." : "",
21528 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
21532 rs6000_xcoff_select_section (tree decl
, int reloc
,
21533 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
21535 if (decl_readonly_section (decl
, reloc
))
21537 if (TREE_PUBLIC (decl
))
21538 return read_only_data_section
;
21540 return read_only_private_data_section
;
21544 if (TREE_PUBLIC (decl
))
21545 return data_section
;
21547 return private_data_section
;
21552 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
21556 /* Use select_section for private and uninitialized data. */
21557 if (!TREE_PUBLIC (decl
)
21558 || DECL_COMMON (decl
)
21559 || DECL_INITIAL (decl
) == NULL_TREE
21560 || DECL_INITIAL (decl
) == error_mark_node
21561 || (flag_zero_initialized_in_bss
21562 && initializer_zerop (DECL_INITIAL (decl
))))
21565 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
21566 name
= (*targetm
.strip_name_encoding
) (name
);
21567 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
21570 /* Select section for constant in constant pool.
21572 On RS/6000, all constants are in the private read-only data area.
21573 However, if this is being placed in the TOC it must be output as a
21577 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
21578 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
21580 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
21581 return toc_section
;
21583 return read_only_private_data_section
;
21586 /* Remove any trailing [DS] or the like from the symbol name. */
21588 static const char *
21589 rs6000_xcoff_strip_name_encoding (const char *name
)
21594 len
= strlen (name
);
21595 if (name
[len
- 1] == ']')
21596 return ggc_alloc_string (name
, len
- 4);
21601 /* Section attributes. AIX is always PIC. */
21603 static unsigned int
21604 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
21606 unsigned int align
;
21607 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
21609 /* Align to at least UNIT size. */
21610 if (flags
& SECTION_CODE
)
21611 align
= MIN_UNITS_PER_WORD
;
21613 /* Increase alignment of large objects if not already stricter. */
21614 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
21615 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
21616 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
21618 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
21621 /* Output at beginning of assembler file.
21623 Initialize the section names for the RS/6000 at this point.
21625 Specify filename, including full path, to assembler.
21627 We want to go into the TOC section so at least one .toc will be emitted.
21628 Also, in order to output proper .bs/.es pairs, we need at least one static
21629 [RW] section emitted.
21631 Finally, declare mcount when profiling to make the assembler happy. */
21634 rs6000_xcoff_file_start (void)
21636 rs6000_gen_section_name (&xcoff_bss_section_name
,
21637 main_input_filename
, ".bss_");
21638 rs6000_gen_section_name (&xcoff_private_data_section_name
,
21639 main_input_filename
, ".rw_");
21640 rs6000_gen_section_name (&xcoff_read_only_section_name
,
21641 main_input_filename
, ".ro_");
21643 fputs ("\t.file\t", asm_out_file
);
21644 output_quoted_string (asm_out_file
, main_input_filename
);
21645 fputc ('\n', asm_out_file
);
21646 if (write_symbols
!= NO_DEBUG
)
21647 switch_to_section (private_data_section
);
21648 switch_to_section (text_section
);
21650 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
21651 rs6000_file_start ();
21654 /* Output at end of assembler file.
21655 On the RS/6000, referencing data should automatically pull in text. */
21658 rs6000_xcoff_file_end (void)
21660 switch_to_section (text_section
);
21661 fputs ("_section_.text:\n", asm_out_file
);
21662 switch_to_section (data_section
);
21663 fputs (TARGET_32BIT
21664 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
21667 #endif /* TARGET_XCOFF */
21669 /* Compute a (partial) cost for rtx X. Return true if the complete
21670 cost has been computed, and false if subexpressions should be
21671 scanned. In either case, *TOTAL contains the cost result. */
21674 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
21677 enum machine_mode mode
= GET_MODE (x
);
21681 /* On the RS/6000, if it is valid in the insn, it is free. */
21683 if (((outer_code
== SET
21684 || outer_code
== PLUS
21685 || outer_code
== MINUS
)
21686 && (satisfies_constraint_I (x
)
21687 || satisfies_constraint_L (x
)))
21688 || (outer_code
== AND
21689 && (satisfies_constraint_K (x
)
21691 ? satisfies_constraint_L (x
)
21692 : satisfies_constraint_J (x
))
21693 || mask_operand (x
, mode
)
21695 && mask64_operand (x
, DImode
))))
21696 || ((outer_code
== IOR
|| outer_code
== XOR
)
21697 && (satisfies_constraint_K (x
)
21699 ? satisfies_constraint_L (x
)
21700 : satisfies_constraint_J (x
))))
21701 || outer_code
== ASHIFT
21702 || outer_code
== ASHIFTRT
21703 || outer_code
== LSHIFTRT
21704 || outer_code
== ROTATE
21705 || outer_code
== ROTATERT
21706 || outer_code
== ZERO_EXTRACT
21707 || (outer_code
== MULT
21708 && satisfies_constraint_I (x
))
21709 || ((outer_code
== DIV
|| outer_code
== UDIV
21710 || outer_code
== MOD
|| outer_code
== UMOD
)
21711 && exact_log2 (INTVAL (x
)) >= 0)
21712 || (outer_code
== COMPARE
21713 && (satisfies_constraint_I (x
)
21714 || satisfies_constraint_K (x
)))
21715 || (outer_code
== EQ
21716 && (satisfies_constraint_I (x
)
21717 || satisfies_constraint_K (x
)
21719 ? satisfies_constraint_L (x
)
21720 : satisfies_constraint_J (x
))))
21721 || (outer_code
== GTU
21722 && satisfies_constraint_I (x
))
21723 || (outer_code
== LTU
21724 && satisfies_constraint_P (x
)))
21729 else if ((outer_code
== PLUS
21730 && reg_or_add_cint_operand (x
, VOIDmode
))
21731 || (outer_code
== MINUS
21732 && reg_or_sub_cint_operand (x
, VOIDmode
))
21733 || ((outer_code
== SET
21734 || outer_code
== IOR
21735 || outer_code
== XOR
)
21737 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
21739 *total
= COSTS_N_INSNS (1);
21745 if (mode
== DImode
&& code
== CONST_DOUBLE
)
21747 if ((outer_code
== IOR
|| outer_code
== XOR
)
21748 && CONST_DOUBLE_HIGH (x
) == 0
21749 && (CONST_DOUBLE_LOW (x
)
21750 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)
21755 else if ((outer_code
== AND
&& and64_2_operand (x
, DImode
))
21756 || ((outer_code
== SET
21757 || outer_code
== IOR
21758 || outer_code
== XOR
)
21759 && CONST_DOUBLE_HIGH (x
) == 0))
21761 *total
= COSTS_N_INSNS (1);
21771 /* When optimizing for size, MEM should be slightly more expensive
21772 than generating address, e.g., (plus (reg) (const)).
21773 L1 cache latency is about two instructions. */
21774 *total
= !speed
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
21782 if (mode
== DFmode
)
21784 if (GET_CODE (XEXP (x
, 0)) == MULT
)
21786 /* FNMA accounted in outer NEG. */
21787 if (outer_code
== NEG
)
21788 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
21790 *total
= rs6000_cost
->dmul
;
21793 *total
= rs6000_cost
->fp
;
21795 else if (mode
== SFmode
)
21797 /* FNMA accounted in outer NEG. */
21798 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
21801 *total
= rs6000_cost
->fp
;
21804 *total
= COSTS_N_INSNS (1);
21808 if (mode
== DFmode
)
21810 if (GET_CODE (XEXP (x
, 0)) == MULT
21811 || GET_CODE (XEXP (x
, 1)) == MULT
)
21813 /* FNMA accounted in outer NEG. */
21814 if (outer_code
== NEG
)
21815 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
21817 *total
= rs6000_cost
->dmul
;
21820 *total
= rs6000_cost
->fp
;
21822 else if (mode
== SFmode
)
21824 /* FNMA accounted in outer NEG. */
21825 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
21828 *total
= rs6000_cost
->fp
;
21831 *total
= COSTS_N_INSNS (1);
21835 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
21836 && satisfies_constraint_I (XEXP (x
, 1)))
21838 if (INTVAL (XEXP (x
, 1)) >= -256
21839 && INTVAL (XEXP (x
, 1)) <= 255)
21840 *total
= rs6000_cost
->mulsi_const9
;
21842 *total
= rs6000_cost
->mulsi_const
;
21844 /* FMA accounted in outer PLUS/MINUS. */
21845 else if ((mode
== DFmode
|| mode
== SFmode
)
21846 && (outer_code
== PLUS
|| outer_code
== MINUS
))
21848 else if (mode
== DFmode
)
21849 *total
= rs6000_cost
->dmul
;
21850 else if (mode
== SFmode
)
21851 *total
= rs6000_cost
->fp
;
21852 else if (mode
== DImode
)
21853 *total
= rs6000_cost
->muldi
;
21855 *total
= rs6000_cost
->mulsi
;
21860 if (FLOAT_MODE_P (mode
))
21862 *total
= mode
== DFmode
? rs6000_cost
->ddiv
21863 : rs6000_cost
->sdiv
;
21870 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
21871 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
21873 if (code
== DIV
|| code
== MOD
)
21875 *total
= COSTS_N_INSNS (2);
21878 *total
= COSTS_N_INSNS (1);
21882 if (GET_MODE (XEXP (x
, 1)) == DImode
)
21883 *total
= rs6000_cost
->divdi
;
21885 *total
= rs6000_cost
->divsi
;
21887 /* Add in shift and subtract for MOD. */
21888 if (code
== MOD
|| code
== UMOD
)
21889 *total
+= COSTS_N_INSNS (2);
21894 *total
= COSTS_N_INSNS (4);
21898 *total
= COSTS_N_INSNS (6);
21902 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
21914 *total
= COSTS_N_INSNS (1);
21922 /* Handle mul_highpart. */
21923 if (outer_code
== TRUNCATE
21924 && GET_CODE (XEXP (x
, 0)) == MULT
)
21926 if (mode
== DImode
)
21927 *total
= rs6000_cost
->muldi
;
21929 *total
= rs6000_cost
->mulsi
;
21932 else if (outer_code
== AND
)
21935 *total
= COSTS_N_INSNS (1);
21940 if (GET_CODE (XEXP (x
, 0)) == MEM
)
21943 *total
= COSTS_N_INSNS (1);
21949 if (!FLOAT_MODE_P (mode
))
21951 *total
= COSTS_N_INSNS (1);
21957 case UNSIGNED_FLOAT
:
21960 case FLOAT_TRUNCATE
:
21961 *total
= rs6000_cost
->fp
;
21965 if (mode
== DFmode
)
21968 *total
= rs6000_cost
->fp
;
21972 switch (XINT (x
, 1))
21975 *total
= rs6000_cost
->fp
;
21987 *total
= COSTS_N_INSNS (1);
21990 else if (FLOAT_MODE_P (mode
)
21991 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
21993 *total
= rs6000_cost
->fp
;
22001 /* Carry bit requires mode == Pmode.
22002 NEG or PLUS already counted so only add one. */
22004 && (outer_code
== NEG
|| outer_code
== PLUS
))
22006 *total
= COSTS_N_INSNS (1);
22009 if (outer_code
== SET
)
22011 if (XEXP (x
, 1) == const0_rtx
)
22013 *total
= COSTS_N_INSNS (2);
22016 else if (mode
== Pmode
)
22018 *total
= COSTS_N_INSNS (3);
22027 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
22029 *total
= COSTS_N_INSNS (2);
22033 if (outer_code
== COMPARE
)
22047 /* A C expression returning the cost of moving data from a register of class
22048 CLASS1 to one of CLASS2. */
22051 rs6000_register_move_cost (enum machine_mode mode
,
22052 enum reg_class from
, enum reg_class to
)
22054 /* Moves from/to GENERAL_REGS. */
22055 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
22056 || reg_classes_intersect_p (from
, GENERAL_REGS
))
22058 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
22061 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
)
22062 return (rs6000_memory_move_cost (mode
, from
, 0)
22063 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, 0));
22065 /* It's more expensive to move CR_REGS than CR0_REGS because of the
22067 else if (from
== CR_REGS
)
22070 /* Power6 has slower LR/CTR moves so make them more expensive than
22071 memory in order to bias spills to memory .*/
22072 else if (rs6000_cpu
== PROCESSOR_POWER6
22073 && reg_classes_intersect_p (from
, LINK_OR_CTR_REGS
))
22074 return 6 * hard_regno_nregs
[0][mode
];
22077 /* A move will cost one instruction per GPR moved. */
22078 return 2 * hard_regno_nregs
[0][mode
];
22081 /* Moving between two similar registers is just one instruction. */
22082 else if (reg_classes_intersect_p (to
, from
))
22083 return (mode
== TFmode
|| mode
== TDmode
) ? 4 : 2;
22085 /* Everything else has to go through GENERAL_REGS. */
22087 return (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
22088 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
22091 /* A C expressions returning the cost of moving data of MODE from a register to
22095 rs6000_memory_move_cost (enum machine_mode mode
, enum reg_class rclass
,
22096 int in ATTRIBUTE_UNUSED
)
22098 if (reg_classes_intersect_p (rclass
, GENERAL_REGS
))
22099 return 4 * hard_regno_nregs
[0][mode
];
22100 else if (reg_classes_intersect_p (rclass
, FLOAT_REGS
))
22101 return 4 * hard_regno_nregs
[32][mode
];
22102 else if (reg_classes_intersect_p (rclass
, ALTIVEC_REGS
))
22103 return 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
22105 return 4 + rs6000_register_move_cost (mode
, rclass
, GENERAL_REGS
);
22108 /* Returns a code for a target-specific builtin that implements
22109 reciprocal of the function, or NULL_TREE if not available. */
22112 rs6000_builtin_reciprocal (unsigned int fn
, bool md_fn
,
22113 bool sqrt ATTRIBUTE_UNUSED
)
22115 if (! (TARGET_RECIP
&& TARGET_PPC_GFXOPT
&& !optimize_size
22116 && flag_finite_math_only
&& !flag_trapping_math
22117 && flag_unsafe_math_optimizations
))
22125 case BUILT_IN_SQRTF
:
22126 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRTF
];
22133 /* Newton-Raphson approximation of single-precision floating point divide n/d.
22134 Assumes no trapping math and finite arguments. */
22137 rs6000_emit_swdivsf (rtx dst
, rtx n
, rtx d
)
22139 rtx x0
, e0
, e1
, y1
, u0
, v0
, one
;
22141 x0
= gen_reg_rtx (SFmode
);
22142 e0
= gen_reg_rtx (SFmode
);
22143 e1
= gen_reg_rtx (SFmode
);
22144 y1
= gen_reg_rtx (SFmode
);
22145 u0
= gen_reg_rtx (SFmode
);
22146 v0
= gen_reg_rtx (SFmode
);
22147 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
22149 /* x0 = 1./d estimate */
22150 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
22151 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, d
),
22153 /* e0 = 1. - d * x0 */
22154 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
22155 gen_rtx_MINUS (SFmode
, one
,
22156 gen_rtx_MULT (SFmode
, d
, x0
))));
22157 /* e1 = e0 + e0 * e0 */
22158 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
22159 gen_rtx_PLUS (SFmode
,
22160 gen_rtx_MULT (SFmode
, e0
, e0
), e0
)));
22161 /* y1 = x0 + e1 * x0 */
22162 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
22163 gen_rtx_PLUS (SFmode
,
22164 gen_rtx_MULT (SFmode
, e1
, x0
), x0
)));
22166 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
22167 gen_rtx_MULT (SFmode
, n
, y1
)));
22168 /* v0 = n - d * u0 */
22169 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
22170 gen_rtx_MINUS (SFmode
, n
,
22171 gen_rtx_MULT (SFmode
, d
, u0
))));
22172 /* dst = u0 + v0 * y1 */
22173 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
22174 gen_rtx_PLUS (SFmode
,
22175 gen_rtx_MULT (SFmode
, v0
, y1
), u0
)));
22178 /* Newton-Raphson approximation of double-precision floating point divide n/d.
22179 Assumes no trapping math and finite arguments. */
22182 rs6000_emit_swdivdf (rtx dst
, rtx n
, rtx d
)
22184 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
22186 x0
= gen_reg_rtx (DFmode
);
22187 e0
= gen_reg_rtx (DFmode
);
22188 e1
= gen_reg_rtx (DFmode
);
22189 e2
= gen_reg_rtx (DFmode
);
22190 y1
= gen_reg_rtx (DFmode
);
22191 y2
= gen_reg_rtx (DFmode
);
22192 y3
= gen_reg_rtx (DFmode
);
22193 u0
= gen_reg_rtx (DFmode
);
22194 v0
= gen_reg_rtx (DFmode
);
22195 one
= force_reg (DFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, DFmode
));
22197 /* x0 = 1./d estimate */
22198 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
22199 gen_rtx_UNSPEC (DFmode
, gen_rtvec (1, d
),
22201 /* e0 = 1. - d * x0 */
22202 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
22203 gen_rtx_MINUS (DFmode
, one
,
22204 gen_rtx_MULT (SFmode
, d
, x0
))));
22205 /* y1 = x0 + e0 * x0 */
22206 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
22207 gen_rtx_PLUS (DFmode
,
22208 gen_rtx_MULT (DFmode
, e0
, x0
), x0
)));
22210 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
22211 gen_rtx_MULT (DFmode
, e0
, e0
)));
22212 /* y2 = y1 + e1 * y1 */
22213 emit_insn (gen_rtx_SET (VOIDmode
, y2
,
22214 gen_rtx_PLUS (DFmode
,
22215 gen_rtx_MULT (DFmode
, e1
, y1
), y1
)));
22217 emit_insn (gen_rtx_SET (VOIDmode
, e2
,
22218 gen_rtx_MULT (DFmode
, e1
, e1
)));
22219 /* y3 = y2 + e2 * y2 */
22220 emit_insn (gen_rtx_SET (VOIDmode
, y3
,
22221 gen_rtx_PLUS (DFmode
,
22222 gen_rtx_MULT (DFmode
, e2
, y2
), y2
)));
22224 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
22225 gen_rtx_MULT (DFmode
, n
, y3
)));
22226 /* v0 = n - d * u0 */
22227 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
22228 gen_rtx_MINUS (DFmode
, n
,
22229 gen_rtx_MULT (DFmode
, d
, u0
))));
22230 /* dst = u0 + v0 * y3 */
22231 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
22232 gen_rtx_PLUS (DFmode
,
22233 gen_rtx_MULT (DFmode
, v0
, y3
), u0
)));
22237 /* Newton-Raphson approximation of single-precision floating point rsqrt.
22238 Assumes no trapping math and finite arguments. */
22241 rs6000_emit_swrsqrtsf (rtx dst
, rtx src
)
22243 rtx x0
, x1
, x2
, y1
, u0
, u1
, u2
, v0
, v1
, v2
, t0
,
22244 half
, one
, halfthree
, c1
, cond
, label
;
22246 x0
= gen_reg_rtx (SFmode
);
22247 x1
= gen_reg_rtx (SFmode
);
22248 x2
= gen_reg_rtx (SFmode
);
22249 y1
= gen_reg_rtx (SFmode
);
22250 u0
= gen_reg_rtx (SFmode
);
22251 u1
= gen_reg_rtx (SFmode
);
22252 u2
= gen_reg_rtx (SFmode
);
22253 v0
= gen_reg_rtx (SFmode
);
22254 v1
= gen_reg_rtx (SFmode
);
22255 v2
= gen_reg_rtx (SFmode
);
22256 t0
= gen_reg_rtx (SFmode
);
22257 halfthree
= gen_reg_rtx (SFmode
);
22258 cond
= gen_rtx_REG (CCFPmode
, CR1_REGNO
);
22259 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
22261 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
22262 emit_insn (gen_rtx_SET (VOIDmode
, t0
,
22263 gen_rtx_MULT (SFmode
, src
, src
)));
22265 emit_insn (gen_rtx_SET (VOIDmode
, cond
,
22266 gen_rtx_COMPARE (CCFPmode
, t0
, src
)));
22267 c1
= gen_rtx_EQ (VOIDmode
, cond
, const0_rtx
);
22268 emit_unlikely_jump (c1
, label
);
22270 half
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf
, SFmode
));
22271 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
22273 /* halfthree = 1.5 = 1.0 + 0.5 */
22274 emit_insn (gen_rtx_SET (VOIDmode
, halfthree
,
22275 gen_rtx_PLUS (SFmode
, one
, half
)));
22277 /* x0 = rsqrt estimate */
22278 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
22279 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, src
),
22282 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
22283 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
22284 gen_rtx_MINUS (SFmode
,
22285 gen_rtx_MULT (SFmode
, src
, halfthree
),
22288 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
22289 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
22290 gen_rtx_MULT (SFmode
, x0
, x0
)));
22291 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
22292 gen_rtx_MINUS (SFmode
,
22294 gen_rtx_MULT (SFmode
, y1
, u0
))));
22295 emit_insn (gen_rtx_SET (VOIDmode
, x1
,
22296 gen_rtx_MULT (SFmode
, x0
, v0
)));
22298 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
22299 emit_insn (gen_rtx_SET (VOIDmode
, u1
,
22300 gen_rtx_MULT (SFmode
, x1
, x1
)));
22301 emit_insn (gen_rtx_SET (VOIDmode
, v1
,
22302 gen_rtx_MINUS (SFmode
,
22304 gen_rtx_MULT (SFmode
, y1
, u1
))));
22305 emit_insn (gen_rtx_SET (VOIDmode
, x2
,
22306 gen_rtx_MULT (SFmode
, x1
, v1
)));
22308 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
22309 emit_insn (gen_rtx_SET (VOIDmode
, u2
,
22310 gen_rtx_MULT (SFmode
, x2
, x2
)));
22311 emit_insn (gen_rtx_SET (VOIDmode
, v2
,
22312 gen_rtx_MINUS (SFmode
,
22314 gen_rtx_MULT (SFmode
, y1
, u2
))));
22315 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
22316 gen_rtx_MULT (SFmode
, x2
, v2
)));
22318 emit_label (XEXP (label
, 0));
22321 /* Emit popcount intrinsic on TARGET_POPCNTB targets. DST is the
22322 target, and SRC is the argument operand. */
22325 rs6000_emit_popcount (rtx dst
, rtx src
)
22327 enum machine_mode mode
= GET_MODE (dst
);
22330 tmp1
= gen_reg_rtx (mode
);
22332 if (mode
== SImode
)
22334 emit_insn (gen_popcntbsi2 (tmp1
, src
));
22335 tmp2
= expand_mult (SImode
, tmp1
, GEN_INT (0x01010101),
22337 tmp2
= force_reg (SImode
, tmp2
);
22338 emit_insn (gen_lshrsi3 (dst
, tmp2
, GEN_INT (24)));
22342 emit_insn (gen_popcntbdi2 (tmp1
, src
));
22343 tmp2
= expand_mult (DImode
, tmp1
,
22344 GEN_INT ((HOST_WIDE_INT
)
22345 0x01010101 << 32 | 0x01010101),
22347 tmp2
= force_reg (DImode
, tmp2
);
22348 emit_insn (gen_lshrdi3 (dst
, tmp2
, GEN_INT (56)));
22353 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
22354 target, and SRC is the argument operand. */
22357 rs6000_emit_parity (rtx dst
, rtx src
)
22359 enum machine_mode mode
= GET_MODE (dst
);
22362 tmp
= gen_reg_rtx (mode
);
22363 if (mode
== SImode
)
22365 /* Is mult+shift >= shift+xor+shift+xor? */
22366 if (rs6000_cost
->mulsi_const
>= COSTS_N_INSNS (3))
22368 rtx tmp1
, tmp2
, tmp3
, tmp4
;
22370 tmp1
= gen_reg_rtx (SImode
);
22371 emit_insn (gen_popcntbsi2 (tmp1
, src
));
22373 tmp2
= gen_reg_rtx (SImode
);
22374 emit_insn (gen_lshrsi3 (tmp2
, tmp1
, GEN_INT (16)));
22375 tmp3
= gen_reg_rtx (SImode
);
22376 emit_insn (gen_xorsi3 (tmp3
, tmp1
, tmp2
));
22378 tmp4
= gen_reg_rtx (SImode
);
22379 emit_insn (gen_lshrsi3 (tmp4
, tmp3
, GEN_INT (8)));
22380 emit_insn (gen_xorsi3 (tmp
, tmp3
, tmp4
));
22383 rs6000_emit_popcount (tmp
, src
);
22384 emit_insn (gen_andsi3 (dst
, tmp
, const1_rtx
));
22388 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
22389 if (rs6000_cost
->muldi
>= COSTS_N_INSNS (5))
22391 rtx tmp1
, tmp2
, tmp3
, tmp4
, tmp5
, tmp6
;
22393 tmp1
= gen_reg_rtx (DImode
);
22394 emit_insn (gen_popcntbdi2 (tmp1
, src
));
22396 tmp2
= gen_reg_rtx (DImode
);
22397 emit_insn (gen_lshrdi3 (tmp2
, tmp1
, GEN_INT (32)));
22398 tmp3
= gen_reg_rtx (DImode
);
22399 emit_insn (gen_xordi3 (tmp3
, tmp1
, tmp2
));
22401 tmp4
= gen_reg_rtx (DImode
);
22402 emit_insn (gen_lshrdi3 (tmp4
, tmp3
, GEN_INT (16)));
22403 tmp5
= gen_reg_rtx (DImode
);
22404 emit_insn (gen_xordi3 (tmp5
, tmp3
, tmp4
));
22406 tmp6
= gen_reg_rtx (DImode
);
22407 emit_insn (gen_lshrdi3 (tmp6
, tmp5
, GEN_INT (8)));
22408 emit_insn (gen_xordi3 (tmp
, tmp5
, tmp6
));
22411 rs6000_emit_popcount (tmp
, src
);
22412 emit_insn (gen_anddi3 (dst
, tmp
, const1_rtx
));
22416 /* Return an RTX representing where to find the function value of a
22417 function returning MODE. */
22419 rs6000_complex_function_value (enum machine_mode mode
)
22421 unsigned int regno
;
22423 enum machine_mode inner
= GET_MODE_INNER (mode
);
22424 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
22426 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
22427 regno
= FP_ARG_RETURN
;
22430 regno
= GP_ARG_RETURN
;
22432 /* 32-bit is OK since it'll go in r3/r4. */
22433 if (TARGET_32BIT
&& inner_bytes
>= 4)
22434 return gen_rtx_REG (mode
, regno
);
22437 if (inner_bytes
>= 8)
22438 return gen_rtx_REG (mode
, regno
);
22440 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
22442 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
22443 GEN_INT (inner_bytes
));
22444 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
22447 /* Define how to find the value returned by a function.
22448 VALTYPE is the data type of the value (as a tree).
22449 If the precise function being called is known, FUNC is its FUNCTION_DECL;
22450 otherwise, FUNC is 0.
22452 On the SPE, both FPs and vectors are returned in r3.
22454 On RS/6000 an integer value is in r3 and a floating-point value is in
22455 fp1, unless -msoft-float. */
22458 rs6000_function_value (const_tree valtype
, const_tree func ATTRIBUTE_UNUSED
)
22460 enum machine_mode mode
;
22461 unsigned int regno
;
22463 /* Special handling for structs in darwin64. */
22464 if (rs6000_darwin64_abi
22465 && TYPE_MODE (valtype
) == BLKmode
22466 && TREE_CODE (valtype
) == RECORD_TYPE
22467 && int_size_in_bytes (valtype
) > 0)
22469 CUMULATIVE_ARGS valcum
;
22473 valcum
.fregno
= FP_ARG_MIN_REG
;
22474 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
22475 /* Do a trial code generation as if this were going to be passed as
22476 an argument; if any part goes in memory, we return NULL. */
22477 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, 1, true);
22480 /* Otherwise fall through to standard ABI rules. */
22483 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
22485 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
22486 return gen_rtx_PARALLEL (DImode
,
22488 gen_rtx_EXPR_LIST (VOIDmode
,
22489 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
22491 gen_rtx_EXPR_LIST (VOIDmode
,
22492 gen_rtx_REG (SImode
,
22493 GP_ARG_RETURN
+ 1),
22496 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
22498 return gen_rtx_PARALLEL (DCmode
,
22500 gen_rtx_EXPR_LIST (VOIDmode
,
22501 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
22503 gen_rtx_EXPR_LIST (VOIDmode
,
22504 gen_rtx_REG (SImode
,
22505 GP_ARG_RETURN
+ 1),
22507 gen_rtx_EXPR_LIST (VOIDmode
,
22508 gen_rtx_REG (SImode
,
22509 GP_ARG_RETURN
+ 2),
22511 gen_rtx_EXPR_LIST (VOIDmode
,
22512 gen_rtx_REG (SImode
,
22513 GP_ARG_RETURN
+ 3),
22517 mode
= TYPE_MODE (valtype
);
22518 if ((INTEGRAL_TYPE_P (valtype
) && GET_MODE_BITSIZE (mode
) < BITS_PER_WORD
)
22519 || POINTER_TYPE_P (valtype
))
22520 mode
= TARGET_32BIT
? SImode
: DImode
;
22522 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
22523 /* _Decimal128 must use an even/odd register pair. */
22524 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
22525 else if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_FPRS
22526 && (TARGET_HARD_FLOAT
22527 && ((TARGET_SINGLE_FLOAT
&& mode
== SFmode
)
22528 || TARGET_DOUBLE_FLOAT
)))
22529 regno
= FP_ARG_RETURN
;
22530 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
22531 && targetm
.calls
.split_complex_arg
)
22532 return rs6000_complex_function_value (mode
);
22533 else if (TREE_CODE (valtype
) == VECTOR_TYPE
22534 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
22535 && ALTIVEC_VECTOR_MODE (mode
))
22536 regno
= ALTIVEC_ARG_RETURN
;
22537 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
22538 && (mode
== DFmode
|| mode
== DCmode
22539 || mode
== TFmode
|| mode
== TCmode
))
22540 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
22542 regno
= GP_ARG_RETURN
;
22544 return gen_rtx_REG (mode
, regno
);
22547 /* Define how to find the value returned by a library function
22548 assuming the value has mode MODE. */
22550 rs6000_libcall_value (enum machine_mode mode
)
22552 unsigned int regno
;
22554 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
22556 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
22557 return gen_rtx_PARALLEL (DImode
,
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),
22568 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
22569 /* _Decimal128 must use an even/odd register pair. */
22570 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
22571 else if (SCALAR_FLOAT_MODE_P (mode
)
22572 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
22573 regno
= FP_ARG_RETURN
;
22574 else if (ALTIVEC_VECTOR_MODE (mode
)
22575 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
22576 regno
= ALTIVEC_ARG_RETURN
;
22577 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
22578 return rs6000_complex_function_value (mode
);
22579 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
22580 && (mode
== DFmode
|| mode
== DCmode
22581 || mode
== TFmode
|| mode
== TCmode
))
22582 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
22584 regno
= GP_ARG_RETURN
;
22586 return gen_rtx_REG (mode
, regno
);
22589 /* Define the offset between two registers, FROM to be eliminated and its
22590 replacement TO, at the start of a routine. */
22592 rs6000_initial_elimination_offset (int from
, int to
)
22594 rs6000_stack_t
*info
= rs6000_stack_info ();
22595 HOST_WIDE_INT offset
;
22597 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
22598 offset
= info
->push_p
? 0 : -info
->total_size
;
22599 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
22601 offset
= info
->push_p
? 0 : -info
->total_size
;
22602 if (FRAME_GROWS_DOWNWARD
)
22603 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
22605 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
22606 offset
= FRAME_GROWS_DOWNWARD
22607 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
22609 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
22610 offset
= info
->total_size
;
22611 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
22612 offset
= info
->push_p
? info
->total_size
: 0;
22613 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
22616 gcc_unreachable ();
22621 /* Return true if TYPE is a SPE or AltiVec opaque type. */
22624 rs6000_is_opaque_type (const_tree type
)
22626 return (type
== opaque_V2SI_type_node
22627 || type
== opaque_V2SF_type_node
22628 || type
== opaque_V4SI_type_node
);
22632 rs6000_dwarf_register_span (rtx reg
)
22637 && (SPE_VECTOR_MODE (GET_MODE (reg
))
22638 || (TARGET_E500_DOUBLE
22639 && (GET_MODE (reg
) == DFmode
|| GET_MODE (reg
) == DDmode
))))
22644 regno
= REGNO (reg
);
22646 /* The duality of the SPE register size wreaks all kinds of havoc.
22647 This is a way of distinguishing r0 in 32-bits from r0 in
22650 gen_rtx_PARALLEL (VOIDmode
,
22653 gen_rtx_REG (SImode
, regno
+ 1200),
22654 gen_rtx_REG (SImode
, regno
))
22656 gen_rtx_REG (SImode
, regno
),
22657 gen_rtx_REG (SImode
, regno
+ 1200)));
22660 /* Fill in sizes for SPE register high parts in table used by unwinder. */
22663 rs6000_init_dwarf_reg_sizes_extra (tree address
)
22668 enum machine_mode mode
= TYPE_MODE (char_type_node
);
22669 rtx addr
= expand_expr (address
, NULL_RTX
, VOIDmode
, 0);
22670 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
22671 rtx value
= gen_int_mode (4, mode
);
22673 for (i
= 1201; i
< 1232; i
++)
22675 int column
= DWARF_REG_TO_UNWIND_COLUMN (i
);
22676 HOST_WIDE_INT offset
22677 = DWARF_FRAME_REGNUM (column
) * GET_MODE_SIZE (mode
);
22679 emit_move_insn (adjust_address (mem
, mode
, offset
), value
);
22684 /* Map internal gcc register numbers to DWARF2 register numbers. */
22687 rs6000_dbx_register_number (unsigned int regno
)
22689 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
22691 if (regno
== MQ_REGNO
)
22693 if (regno
== LR_REGNO
)
22695 if (regno
== CTR_REGNO
)
22697 if (CR_REGNO_P (regno
))
22698 return regno
- CR0_REGNO
+ 86;
22699 if (regno
== XER_REGNO
)
22701 if (ALTIVEC_REGNO_P (regno
))
22702 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
22703 if (regno
== VRSAVE_REGNO
)
22705 if (regno
== VSCR_REGNO
)
22707 if (regno
== SPE_ACC_REGNO
)
22709 if (regno
== SPEFSCR_REGNO
)
22711 /* SPE high reg number. We get these values of regno from
22712 rs6000_dwarf_register_span. */
22713 gcc_assert (regno
>= 1200 && regno
< 1232);
22717 /* target hook eh_return_filter_mode */
22718 static enum machine_mode
22719 rs6000_eh_return_filter_mode (void)
22721 return TARGET_32BIT
? SImode
: word_mode
;
22724 /* Target hook for scalar_mode_supported_p. */
22726 rs6000_scalar_mode_supported_p (enum machine_mode mode
)
22728 if (DECIMAL_FLOAT_MODE_P (mode
))
22731 return default_scalar_mode_supported_p (mode
);
22734 /* Target hook for vector_mode_supported_p. */
22736 rs6000_vector_mode_supported_p (enum machine_mode mode
)
22739 if (TARGET_PAIRED_FLOAT
&& PAIRED_VECTOR_MODE (mode
))
22742 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
22745 else if (TARGET_ALTIVEC
&& ALTIVEC_VECTOR_MODE (mode
))
22752 /* Target hook for invalid_arg_for_unprototyped_fn. */
22753 static const char *
22754 invalid_arg_for_unprototyped_fn (const_tree typelist
, const_tree funcdecl
, const_tree val
)
22756 return (!rs6000_darwin64_abi
22758 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
22759 && (funcdecl
== NULL_TREE
22760 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
22761 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
22762 ? N_("AltiVec argument passed to unprototyped function")
22766 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
22767 setup by using __stack_chk_fail_local hidden function instead of
22768 calling __stack_chk_fail directly. Otherwise it is better to call
22769 __stack_chk_fail directly. */
22772 rs6000_stack_protect_fail (void)
22774 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
22775 ? default_hidden_stack_protect_fail ()
22776 : default_external_stack_protect_fail ();
22779 #include "gt-rs6000.h"