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
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"
55 #include "tree-gimple.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 POWER4 and POWER5 processors. */
699 struct processor_costs power4_cost
= {
700 COSTS_N_INSNS (3), /* mulsi */
701 COSTS_N_INSNS (2), /* mulsi_const */
702 COSTS_N_INSNS (2), /* mulsi_const9 */
703 COSTS_N_INSNS (4), /* muldi */
704 COSTS_N_INSNS (18), /* divsi */
705 COSTS_N_INSNS (34), /* divdi */
706 COSTS_N_INSNS (3), /* fp */
707 COSTS_N_INSNS (3), /* dmul */
708 COSTS_N_INSNS (17), /* sdiv */
709 COSTS_N_INSNS (17), /* ddiv */
710 128, /* cache line size */
713 8, /* prefetch streams /*/
716 /* Instruction costs on POWER6 processors. */
718 struct processor_costs power6_cost
= {
719 COSTS_N_INSNS (8), /* mulsi */
720 COSTS_N_INSNS (8), /* mulsi_const */
721 COSTS_N_INSNS (8), /* mulsi_const9 */
722 COSTS_N_INSNS (8), /* muldi */
723 COSTS_N_INSNS (22), /* divsi */
724 COSTS_N_INSNS (28), /* divdi */
725 COSTS_N_INSNS (3), /* fp */
726 COSTS_N_INSNS (3), /* dmul */
727 COSTS_N_INSNS (13), /* sdiv */
728 COSTS_N_INSNS (16), /* ddiv */
729 128, /* cache line size */
732 16, /* prefetch streams */
736 static bool rs6000_function_ok_for_sibcall (tree
, tree
);
737 static const char *rs6000_invalid_within_doloop (const_rtx
);
738 static rtx
rs6000_generate_compare (enum rtx_code
);
739 static void rs6000_emit_stack_tie (void);
740 static void rs6000_frame_related (rtx
, rtx
, HOST_WIDE_INT
, rtx
, rtx
);
741 static bool spe_func_has_64bit_regs_p (void);
742 static void emit_frame_save (rtx
, rtx
, enum machine_mode
, unsigned int,
744 static rtx
gen_frame_mem_offset (enum machine_mode
, rtx
, int);
745 static void rs6000_emit_allocate_stack (HOST_WIDE_INT
, int);
746 static unsigned rs6000_hash_constant (rtx
);
747 static unsigned toc_hash_function (const void *);
748 static int toc_hash_eq (const void *, const void *);
749 static int constant_pool_expr_1 (rtx
, int *, int *);
750 static bool constant_pool_expr_p (rtx
);
751 static bool legitimate_small_data_p (enum machine_mode
, rtx
);
752 static bool legitimate_lo_sum_address_p (enum machine_mode
, rtx
, int);
753 static struct machine_function
* rs6000_init_machine_status (void);
754 static bool rs6000_assemble_integer (rtx
, unsigned int, int);
755 static bool no_global_regs_above (int);
756 #ifdef HAVE_GAS_HIDDEN
757 static void rs6000_assemble_visibility (tree
, int);
759 static int rs6000_ra_ever_killed (void);
760 static tree
rs6000_handle_longcall_attribute (tree
*, tree
, tree
, int, bool *);
761 static tree
rs6000_handle_altivec_attribute (tree
*, tree
, tree
, int, bool *);
762 static bool rs6000_ms_bitfield_layout_p (const_tree
);
763 static tree
rs6000_handle_struct_attribute (tree
*, tree
, tree
, int, bool *);
764 static void rs6000_eliminate_indexed_memrefs (rtx operands
[2]);
765 static const char *rs6000_mangle_type (const_tree
);
766 extern const struct attribute_spec rs6000_attribute_table
[];
767 static void rs6000_set_default_type_attributes (tree
);
768 static bool rs6000_reg_live_or_pic_offset_p (int);
769 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT
);
770 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT
);
771 static void rs6000_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
773 static rtx
rs6000_emit_set_long_const (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
774 static bool rs6000_return_in_memory (const_tree
, const_tree
);
775 static void rs6000_file_start (void);
777 static int rs6000_elf_reloc_rw_mask (void);
778 static void rs6000_elf_asm_out_constructor (rtx
, int);
779 static void rs6000_elf_asm_out_destructor (rtx
, int);
780 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED
;
781 static void rs6000_elf_asm_init_sections (void);
782 static section
*rs6000_elf_select_rtx_section (enum machine_mode
, rtx
,
783 unsigned HOST_WIDE_INT
);
784 static void rs6000_elf_encode_section_info (tree
, rtx
, int)
787 static bool rs6000_use_blocks_for_constant_p (enum machine_mode
, const_rtx
);
788 static void rs6000_alloc_sdmode_stack_slot (void);
789 static void rs6000_instantiate_decls (void);
791 static void rs6000_xcoff_asm_output_anchor (rtx
);
792 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
793 static void rs6000_xcoff_asm_init_sections (void);
794 static int rs6000_xcoff_reloc_rw_mask (void);
795 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree
);
796 static section
*rs6000_xcoff_select_section (tree
, int,
797 unsigned HOST_WIDE_INT
);
798 static void rs6000_xcoff_unique_section (tree
, int);
799 static section
*rs6000_xcoff_select_rtx_section
800 (enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
);
801 static const char * rs6000_xcoff_strip_name_encoding (const char *);
802 static unsigned int rs6000_xcoff_section_type_flags (tree
, const char *, int);
803 static void rs6000_xcoff_file_start (void);
804 static void rs6000_xcoff_file_end (void);
806 static int rs6000_variable_issue (FILE *, int, rtx
, int);
807 static bool rs6000_rtx_costs (rtx
, int, int, int *);
808 static int rs6000_adjust_cost (rtx
, rtx
, rtx
, int);
809 static void rs6000_sched_init (FILE *, int, int);
810 static bool is_microcoded_insn (rtx
);
811 static bool is_nonpipeline_insn (rtx
);
812 static bool is_cracked_insn (rtx
);
813 static bool is_branch_slot_insn (rtx
);
814 static bool is_load_insn (rtx
);
815 static rtx
get_store_dest (rtx pat
);
816 static bool is_store_insn (rtx
);
817 static bool set_to_load_agen (rtx
,rtx
);
818 static bool adjacent_mem_locations (rtx
,rtx
);
819 static int rs6000_adjust_priority (rtx
, int);
820 static int rs6000_issue_rate (void);
821 static bool rs6000_is_costly_dependence (dep_t
, int, int);
822 static rtx
get_next_active_insn (rtx
, rtx
);
823 static bool insn_terminates_group_p (rtx
, enum group_termination
);
824 static bool insn_must_be_first_in_group (rtx
);
825 static bool insn_must_be_last_in_group (rtx
);
826 static bool is_costly_group (rtx
*, rtx
);
827 static int force_new_group (int, FILE *, rtx
*, rtx
, bool *, int, int *);
828 static int redefine_groups (FILE *, int, rtx
, rtx
);
829 static int pad_groups (FILE *, int, rtx
, rtx
);
830 static void rs6000_sched_finish (FILE *, int);
831 static int rs6000_sched_reorder (FILE *, int, rtx
*, int *, int);
832 static int rs6000_sched_reorder2 (FILE *, int, rtx
*, int *, int);
833 static int rs6000_use_sched_lookahead (void);
834 static int rs6000_use_sched_lookahead_guard (rtx
);
835 static tree
rs6000_builtin_reciprocal (unsigned int, bool, bool);
836 static tree
rs6000_builtin_mask_for_load (void);
837 static tree
rs6000_builtin_mul_widen_even (tree
);
838 static tree
rs6000_builtin_mul_widen_odd (tree
);
839 static tree
rs6000_builtin_conversion (enum tree_code
, tree
);
841 static void def_builtin (int, const char *, tree
, int);
842 static bool rs6000_vector_alignment_reachable (const_tree
, bool);
843 static void rs6000_init_builtins (void);
844 static rtx
rs6000_expand_unop_builtin (enum insn_code
, tree
, rtx
);
845 static rtx
rs6000_expand_binop_builtin (enum insn_code
, tree
, rtx
);
846 static rtx
rs6000_expand_ternop_builtin (enum insn_code
, tree
, rtx
);
847 static rtx
rs6000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
848 static void altivec_init_builtins (void);
849 static void rs6000_common_init_builtins (void);
850 static void rs6000_init_libfuncs (void);
852 static void paired_init_builtins (void);
853 static rtx
paired_expand_builtin (tree
, rtx
, bool *);
854 static rtx
paired_expand_lv_builtin (enum insn_code
, tree
, rtx
);
855 static rtx
paired_expand_stv_builtin (enum insn_code
, tree
);
856 static rtx
paired_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
858 static void enable_mask_for_builtins (struct builtin_description
*, int,
859 enum rs6000_builtins
,
860 enum rs6000_builtins
);
861 static tree
build_opaque_vector_type (tree
, int);
862 static void spe_init_builtins (void);
863 static rtx
spe_expand_builtin (tree
, rtx
, bool *);
864 static rtx
spe_expand_stv_builtin (enum insn_code
, tree
);
865 static rtx
spe_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
866 static rtx
spe_expand_evsel_builtin (enum insn_code
, tree
, rtx
);
867 static int rs6000_emit_int_cmove (rtx
, rtx
, rtx
, rtx
);
868 static rs6000_stack_t
*rs6000_stack_info (void);
869 static void debug_stack_info (rs6000_stack_t
*);
871 static rtx
altivec_expand_builtin (tree
, rtx
, bool *);
872 static rtx
altivec_expand_ld_builtin (tree
, rtx
, bool *);
873 static rtx
altivec_expand_st_builtin (tree
, rtx
, bool *);
874 static rtx
altivec_expand_dst_builtin (tree
, rtx
, bool *);
875 static rtx
altivec_expand_abs_builtin (enum insn_code
, tree
, rtx
);
876 static rtx
altivec_expand_predicate_builtin (enum insn_code
,
877 const char *, tree
, rtx
);
878 static rtx
altivec_expand_lv_builtin (enum insn_code
, tree
, rtx
);
879 static rtx
altivec_expand_stv_builtin (enum insn_code
, tree
);
880 static rtx
altivec_expand_vec_init_builtin (tree
, tree
, rtx
);
881 static rtx
altivec_expand_vec_set_builtin (tree
);
882 static rtx
altivec_expand_vec_ext_builtin (tree
, rtx
);
883 static int get_element_number (tree
, tree
);
884 static bool rs6000_handle_option (size_t, const char *, int);
885 static void rs6000_parse_tls_size_option (void);
886 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
887 static int first_altivec_reg_to_save (void);
888 static unsigned int compute_vrsave_mask (void);
889 static void compute_save_world_info (rs6000_stack_t
*info_ptr
);
890 static void is_altivec_return_reg (rtx
, void *);
891 static rtx
generate_set_vrsave (rtx
, rs6000_stack_t
*, int);
892 int easy_vector_constant (rtx
, enum machine_mode
);
893 static bool rs6000_is_opaque_type (const_tree
);
894 static rtx
rs6000_dwarf_register_span (rtx
);
895 static void rs6000_init_dwarf_reg_sizes_extra (tree
);
896 static rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
897 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
898 static rtx
rs6000_tls_get_addr (void);
899 static rtx
rs6000_got_sym (void);
900 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
901 static const char *rs6000_get_some_local_dynamic_name (void);
902 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
903 static rtx
rs6000_complex_function_value (enum machine_mode
);
904 static rtx
rs6000_spe_function_arg (CUMULATIVE_ARGS
*,
905 enum machine_mode
, tree
);
906 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
908 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
909 tree
, HOST_WIDE_INT
);
910 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
913 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
914 const_tree
, HOST_WIDE_INT
,
916 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, const_tree
, int, bool);
917 static rtx
rs6000_mixed_function_arg (enum machine_mode
, tree
, int);
918 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
919 static void setup_incoming_varargs (CUMULATIVE_ARGS
*,
920 enum machine_mode
, tree
,
922 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
924 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
926 static const char *invalid_arg_for_unprototyped_fn (const_tree
, const_tree
, const_tree
);
928 static void macho_branch_islands (void);
929 static int no_previous_def (tree function_name
);
930 static tree
get_prev_label (tree function_name
);
931 static void rs6000_darwin_file_start (void);
934 static tree
rs6000_build_builtin_va_list (void);
935 static void rs6000_va_start (tree
, rtx
);
936 static tree
rs6000_gimplify_va_arg (tree
, tree
, tree
*, tree
*);
937 static bool rs6000_must_pass_in_stack (enum machine_mode
, const_tree
);
938 static bool rs6000_scalar_mode_supported_p (enum machine_mode
);
939 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
940 static int get_vec_cmp_insn (enum rtx_code
, enum machine_mode
,
942 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
944 static int get_vsel_insn (enum machine_mode
);
945 static void rs6000_emit_vector_select (rtx
, rtx
, rtx
, rtx
);
946 static tree
rs6000_stack_protect_fail (void);
948 const int INSN_NOT_AVAILABLE
= -1;
949 static enum machine_mode
rs6000_eh_return_filter_mode (void);
951 /* Hash table stuff for keeping track of TOC entries. */
953 struct toc_hash_struct
GTY(())
955 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
956 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
958 enum machine_mode key_mode
;
962 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
964 /* Default register names. */
965 char rs6000_reg_names
[][8] =
967 "0", "1", "2", "3", "4", "5", "6", "7",
968 "8", "9", "10", "11", "12", "13", "14", "15",
969 "16", "17", "18", "19", "20", "21", "22", "23",
970 "24", "25", "26", "27", "28", "29", "30", "31",
971 "0", "1", "2", "3", "4", "5", "6", "7",
972 "8", "9", "10", "11", "12", "13", "14", "15",
973 "16", "17", "18", "19", "20", "21", "22", "23",
974 "24", "25", "26", "27", "28", "29", "30", "31",
975 "mq", "lr", "ctr","ap",
976 "0", "1", "2", "3", "4", "5", "6", "7",
978 /* AltiVec registers. */
979 "0", "1", "2", "3", "4", "5", "6", "7",
980 "8", "9", "10", "11", "12", "13", "14", "15",
981 "16", "17", "18", "19", "20", "21", "22", "23",
982 "24", "25", "26", "27", "28", "29", "30", "31",
985 "spe_acc", "spefscr",
986 /* Soft frame pointer. */
990 #ifdef TARGET_REGNAMES
991 static const char alt_reg_names
[][8] =
993 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
994 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
995 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
996 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
997 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
998 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
999 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1000 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1001 "mq", "lr", "ctr", "ap",
1002 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1004 /* AltiVec registers. */
1005 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1006 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1007 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1008 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1010 /* SPE registers. */
1011 "spe_acc", "spefscr",
1012 /* Soft frame pointer. */
1017 #ifndef MASK_STRICT_ALIGN
1018 #define MASK_STRICT_ALIGN 0
1020 #ifndef TARGET_PROFILE_KERNEL
1021 #define TARGET_PROFILE_KERNEL 0
1024 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1025 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1027 /* Initialize the GCC target structure. */
1028 #undef TARGET_ATTRIBUTE_TABLE
1029 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1030 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1031 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1033 #undef TARGET_ASM_ALIGNED_DI_OP
1034 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1036 /* Default unaligned ops are only provided for ELF. Find the ops needed
1037 for non-ELF systems. */
1038 #ifndef OBJECT_FORMAT_ELF
1040 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1042 #undef TARGET_ASM_UNALIGNED_HI_OP
1043 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1044 #undef TARGET_ASM_UNALIGNED_SI_OP
1045 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1046 #undef TARGET_ASM_UNALIGNED_DI_OP
1047 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1050 #undef TARGET_ASM_UNALIGNED_HI_OP
1051 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1052 #undef TARGET_ASM_UNALIGNED_SI_OP
1053 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1054 #undef TARGET_ASM_UNALIGNED_DI_OP
1055 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1056 #undef TARGET_ASM_ALIGNED_DI_OP
1057 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1061 /* This hook deals with fixups for relocatable code and DI-mode objects
1063 #undef TARGET_ASM_INTEGER
1064 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1066 #ifdef HAVE_GAS_HIDDEN
1067 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1068 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1071 #undef TARGET_HAVE_TLS
1072 #define TARGET_HAVE_TLS HAVE_AS_TLS
1074 #undef TARGET_CANNOT_FORCE_CONST_MEM
1075 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1077 #undef TARGET_ASM_FUNCTION_PROLOGUE
1078 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1079 #undef TARGET_ASM_FUNCTION_EPILOGUE
1080 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1082 #undef TARGET_SCHED_VARIABLE_ISSUE
1083 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1085 #undef TARGET_SCHED_ISSUE_RATE
1086 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1087 #undef TARGET_SCHED_ADJUST_COST
1088 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1089 #undef TARGET_SCHED_ADJUST_PRIORITY
1090 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1091 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1092 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1093 #undef TARGET_SCHED_INIT
1094 #define TARGET_SCHED_INIT rs6000_sched_init
1095 #undef TARGET_SCHED_FINISH
1096 #define TARGET_SCHED_FINISH rs6000_sched_finish
1097 #undef TARGET_SCHED_REORDER
1098 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1099 #undef TARGET_SCHED_REORDER2
1100 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1102 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1103 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1105 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1106 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1108 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1109 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1110 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1111 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1112 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1113 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1114 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1115 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1117 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1118 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1120 #undef TARGET_INIT_BUILTINS
1121 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1123 #undef TARGET_EXPAND_BUILTIN
1124 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1126 #undef TARGET_MANGLE_TYPE
1127 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1129 #undef TARGET_INIT_LIBFUNCS
1130 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1133 #undef TARGET_BINDS_LOCAL_P
1134 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1137 #undef TARGET_MS_BITFIELD_LAYOUT_P
1138 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1140 #undef TARGET_ASM_OUTPUT_MI_THUNK
1141 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1143 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1144 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1146 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1147 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1149 #undef TARGET_INVALID_WITHIN_DOLOOP
1150 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1152 #undef TARGET_RTX_COSTS
1153 #define TARGET_RTX_COSTS rs6000_rtx_costs
1154 #undef TARGET_ADDRESS_COST
1155 #define TARGET_ADDRESS_COST hook_int_rtx_0
1157 #undef TARGET_VECTOR_OPAQUE_P
1158 #define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
1160 #undef TARGET_DWARF_REGISTER_SPAN
1161 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1163 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1164 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1166 /* On rs6000, function arguments are promoted, as are function return
1168 #undef TARGET_PROMOTE_FUNCTION_ARGS
1169 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
1170 #undef TARGET_PROMOTE_FUNCTION_RETURN
1171 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
1173 #undef TARGET_RETURN_IN_MEMORY
1174 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1176 #undef TARGET_SETUP_INCOMING_VARARGS
1177 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1179 /* Always strict argument naming on rs6000. */
1180 #undef TARGET_STRICT_ARGUMENT_NAMING
1181 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1182 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1183 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1184 #undef TARGET_SPLIT_COMPLEX_ARG
1185 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1186 #undef TARGET_MUST_PASS_IN_STACK
1187 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1188 #undef TARGET_PASS_BY_REFERENCE
1189 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1190 #undef TARGET_ARG_PARTIAL_BYTES
1191 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1193 #undef TARGET_BUILD_BUILTIN_VA_LIST
1194 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1196 #undef TARGET_EXPAND_BUILTIN_VA_START
1197 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1199 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1200 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1202 #undef TARGET_EH_RETURN_FILTER_MODE
1203 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1205 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1206 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1208 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1209 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1211 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1212 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1214 #undef TARGET_HANDLE_OPTION
1215 #define TARGET_HANDLE_OPTION rs6000_handle_option
1217 #undef TARGET_DEFAULT_TARGET_FLAGS
1218 #define TARGET_DEFAULT_TARGET_FLAGS \
1221 #undef TARGET_STACK_PROTECT_FAIL
1222 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1224 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1225 The PowerPC architecture requires only weak consistency among
1226 processors--that is, memory accesses between processors need not be
1227 sequentially consistent and memory accesses among processors can occur
1228 in any order. The ability to order memory accesses weakly provides
1229 opportunities for more efficient use of the system bus. Unless a
1230 dependency exists, the 604e allows read operations to precede store
1232 #undef TARGET_RELAXED_ORDERING
1233 #define TARGET_RELAXED_ORDERING true
1236 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1237 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1240 /* Use a 32-bit anchor range. This leads to sequences like:
1242 addis tmp,anchor,high
1245 where tmp itself acts as an anchor, and can be shared between
1246 accesses to the same 64k page. */
1247 #undef TARGET_MIN_ANCHOR_OFFSET
1248 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1249 #undef TARGET_MAX_ANCHOR_OFFSET
1250 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1251 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1252 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1254 #undef TARGET_BUILTIN_RECIPROCAL
1255 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1257 #undef TARGET_EXPAND_TO_RTL_HOOK
1258 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1260 #undef TARGET_INSTANTIATE_DECLS
1261 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1263 struct gcc_target targetm
= TARGET_INITIALIZER
;
1266 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1269 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
1271 /* The GPRs can hold any mode, but values bigger than one register
1272 cannot go past R31. */
1273 if (INT_REGNO_P (regno
))
1274 return INT_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1);
1276 /* The float registers can only hold floating modes and DImode.
1277 This excludes the 32-bit decimal float mode for now. */
1278 if (FP_REGNO_P (regno
))
1280 ((SCALAR_FLOAT_MODE_P (mode
)
1281 && (mode
!= TDmode
|| (regno
% 2) == 0)
1282 && FP_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1))
1283 || (GET_MODE_CLASS (mode
) == MODE_INT
1284 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
)
1285 || (PAIRED_SIMD_REGNO_P (regno
) && TARGET_PAIRED_FLOAT
1286 && PAIRED_VECTOR_MODE (mode
)));
1288 /* The CR register can only hold CC modes. */
1289 if (CR_REGNO_P (regno
))
1290 return GET_MODE_CLASS (mode
) == MODE_CC
;
1292 if (XER_REGNO_P (regno
))
1293 return mode
== PSImode
;
1295 /* AltiVec only in AldyVec registers. */
1296 if (ALTIVEC_REGNO_P (regno
))
1297 return ALTIVEC_VECTOR_MODE (mode
);
1299 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1300 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1303 /* We cannot put TImode anywhere except general register and it must be
1304 able to fit within the register set. */
1306 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1309 /* Initialize rs6000_hard_regno_mode_ok_p table. */
1311 rs6000_init_hard_regno_mode_ok (void)
1315 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
1316 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1317 if (rs6000_hard_regno_mode_ok (r
, m
))
1318 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
1322 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
1325 darwin_rs6000_override_options (void)
1327 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
1329 rs6000_altivec_abi
= 1;
1330 TARGET_ALTIVEC_VRSAVE
= 1;
1331 if (DEFAULT_ABI
== ABI_DARWIN
)
1333 if (MACHO_DYNAMIC_NO_PIC_P
)
1336 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
1339 else if (flag_pic
== 1)
1344 if (TARGET_64BIT
&& ! TARGET_POWERPC64
)
1346 target_flags
|= MASK_POWERPC64
;
1347 warning (0, "-m64 requires PowerPC64 architecture, enabling");
1351 rs6000_default_long_calls
= 1;
1352 target_flags
|= MASK_SOFT_FLOAT
;
1355 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
1357 if (!flag_mkernel
&& !flag_apple_kext
1359 && ! (target_flags_explicit
& MASK_ALTIVEC
))
1360 target_flags
|= MASK_ALTIVEC
;
1362 /* Unless the user (not the configurer) has explicitly overridden
1363 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
1364 G4 unless targetting the kernel. */
1367 && strverscmp (darwin_macosx_version_min
, "10.5") >= 0
1368 && ! (target_flags_explicit
& MASK_ALTIVEC
)
1369 && ! rs6000_select
[1].string
)
1371 target_flags
|= MASK_ALTIVEC
;
1376 /* If not otherwise specified by a target, make 'long double' equivalent to
1379 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1380 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1383 /* Override command line options. Mostly we process the processor
1384 type and sometimes adjust other TARGET_ options. */
1387 rs6000_override_options (const char *default_cpu
)
1390 struct rs6000_cpu_select
*ptr
;
1393 /* Simplifications for entries below. */
1396 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
1397 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
1400 /* This table occasionally claims that a processor does not support
1401 a particular feature even though it does, but the feature is slower
1402 than the alternative. Thus, it shouldn't be relied on as a
1403 complete description of the processor's support.
1405 Please keep this list in order, and don't forget to update the
1406 documentation in invoke.texi when adding a new processor or
1410 const char *const name
; /* Canonical processor name. */
1411 const enum processor_type processor
; /* Processor type enum value. */
1412 const int target_enable
; /* Target flags to enable. */
1413 } const processor_target_table
[]
1414 = {{"401", PROCESSOR_PPC403
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1415 {"403", PROCESSOR_PPC403
,
1416 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_STRICT_ALIGN
},
1417 {"405", PROCESSOR_PPC405
,
1418 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1419 {"405fp", PROCESSOR_PPC405
,
1420 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1421 {"440", PROCESSOR_PPC440
,
1422 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1423 {"440fp", PROCESSOR_PPC440
,
1424 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1425 {"505", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
},
1426 {"601", PROCESSOR_PPC601
,
1427 MASK_POWER
| POWERPC_BASE_MASK
| MASK_MULTIPLE
| MASK_STRING
},
1428 {"602", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1429 {"603", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1430 {"603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1431 {"604", PROCESSOR_PPC604
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1432 {"604e", PROCESSOR_PPC604e
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1433 {"620", PROCESSOR_PPC620
,
1434 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1435 {"630", PROCESSOR_PPC630
,
1436 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1437 {"740", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1438 {"7400", PROCESSOR_PPC7400
, POWERPC_7400_MASK
},
1439 {"7450", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1440 {"750", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1441 {"801", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1442 {"821", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1443 {"823", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1444 {"8540", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
},
1445 /* 8548 has a dummy entry for now. */
1446 {"8548", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
},
1447 {"e300c2", PROCESSOR_PPCE300C2
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1448 {"e300c3", PROCESSOR_PPCE300C3
, POWERPC_BASE_MASK
},
1449 {"860", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1450 {"970", PROCESSOR_POWER4
,
1451 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1452 {"cell", PROCESSOR_CELL
,
1453 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1454 {"common", PROCESSOR_COMMON
, MASK_NEW_MNEMONICS
},
1455 {"ec603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1456 {"G3", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1457 {"G4", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1458 {"G5", PROCESSOR_POWER4
,
1459 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1460 {"power", PROCESSOR_POWER
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1461 {"power2", PROCESSOR_POWER
,
1462 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1463 {"power3", PROCESSOR_PPC630
,
1464 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1465 {"power4", PROCESSOR_POWER4
,
1466 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1467 {"power5", PROCESSOR_POWER5
,
1468 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GFXOPT
1469 | MASK_MFCRF
| MASK_POPCNTB
},
1470 {"power5+", PROCESSOR_POWER5
,
1471 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GFXOPT
1472 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
},
1473 {"power6", PROCESSOR_POWER6
,
1474 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_MFCRF
| MASK_POPCNTB
1475 | MASK_FPRND
| MASK_CMPB
| MASK_DFP
},
1476 {"power6x", PROCESSOR_POWER6
,
1477 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_MFCRF
| MASK_POPCNTB
1478 | MASK_FPRND
| MASK_CMPB
| MASK_MFPGPR
| MASK_DFP
},
1479 {"powerpc", PROCESSOR_POWERPC
, POWERPC_BASE_MASK
},
1480 {"powerpc64", PROCESSOR_POWERPC64
,
1481 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1482 {"rios", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1483 {"rios1", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1484 {"rios2", PROCESSOR_RIOS2
,
1485 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1486 {"rsc", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1487 {"rsc1", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1488 {"rs64", PROCESSOR_RS64A
,
1489 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
}
1492 const size_t ptt_size
= ARRAY_SIZE (processor_target_table
);
1494 /* Some OSs don't support saving the high part of 64-bit registers on
1495 context switch. Other OSs don't support saving Altivec registers.
1496 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1497 settings; if the user wants either, the user must explicitly specify
1498 them and we won't interfere with the user's specification. */
1501 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
1502 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
| MASK_STRICT_ALIGN
1503 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
1504 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_MULHW
1505 | MASK_DLMZB
| MASK_CMPB
| MASK_MFPGPR
| MASK_DFP
)
1508 rs6000_init_hard_regno_mode_ok ();
1510 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
1511 #ifdef OS_MISSING_POWERPC64
1512 if (OS_MISSING_POWERPC64
)
1513 set_masks
&= ~MASK_POWERPC64
;
1515 #ifdef OS_MISSING_ALTIVEC
1516 if (OS_MISSING_ALTIVEC
)
1517 set_masks
&= ~MASK_ALTIVEC
;
1520 /* Don't override by the processor default if given explicitly. */
1521 set_masks
&= ~target_flags_explicit
;
1523 /* Identify the processor type. */
1524 rs6000_select
[0].string
= default_cpu
;
1525 rs6000_cpu
= TARGET_POWERPC64
? PROCESSOR_DEFAULT64
: PROCESSOR_DEFAULT
;
1527 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
1529 ptr
= &rs6000_select
[i
];
1530 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
1532 for (j
= 0; j
< ptt_size
; j
++)
1533 if (! strcmp (ptr
->string
, processor_target_table
[j
].name
))
1535 if (ptr
->set_tune_p
)
1536 rs6000_cpu
= processor_target_table
[j
].processor
;
1538 if (ptr
->set_arch_p
)
1540 target_flags
&= ~set_masks
;
1541 target_flags
|= (processor_target_table
[j
].target_enable
1548 error ("bad value (%s) for %s switch", ptr
->string
, ptr
->name
);
1555 if (rs6000_cpu
== PROCESSOR_PPCE300C2
|| rs6000_cpu
== PROCESSOR_PPCE300C3
)
1558 error ("AltiVec not supported in this target");
1560 error ("Spe not supported in this target");
1563 /* If we are optimizing big endian systems for space, use the load/store
1564 multiple and string instructions. */
1565 if (BYTES_BIG_ENDIAN
&& optimize_size
)
1566 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
1568 /* Don't allow -mmultiple or -mstring on little endian systems
1569 unless the cpu is a 750, because the hardware doesn't support the
1570 instructions used in little endian mode, and causes an alignment
1571 trap. The 750 does not cause an alignment trap (except when the
1572 target is unaligned). */
1574 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
1576 if (TARGET_MULTIPLE
)
1578 target_flags
&= ~MASK_MULTIPLE
;
1579 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
1580 warning (0, "-mmultiple is not supported on little endian systems");
1585 target_flags
&= ~MASK_STRING
;
1586 if ((target_flags_explicit
& MASK_STRING
) != 0)
1587 warning (0, "-mstring is not supported on little endian systems");
1591 /* Set debug flags */
1592 if (rs6000_debug_name
)
1594 if (! strcmp (rs6000_debug_name
, "all"))
1595 rs6000_debug_stack
= rs6000_debug_arg
= 1;
1596 else if (! strcmp (rs6000_debug_name
, "stack"))
1597 rs6000_debug_stack
= 1;
1598 else if (! strcmp (rs6000_debug_name
, "arg"))
1599 rs6000_debug_arg
= 1;
1601 error ("unknown -mdebug-%s switch", rs6000_debug_name
);
1604 if (rs6000_traceback_name
)
1606 if (! strncmp (rs6000_traceback_name
, "full", 4))
1607 rs6000_traceback
= traceback_full
;
1608 else if (! strncmp (rs6000_traceback_name
, "part", 4))
1609 rs6000_traceback
= traceback_part
;
1610 else if (! strncmp (rs6000_traceback_name
, "no", 2))
1611 rs6000_traceback
= traceback_none
;
1613 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
1614 rs6000_traceback_name
);
1617 if (!rs6000_explicit_options
.long_double
)
1618 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1620 #ifndef POWERPC_LINUX
1621 if (!rs6000_explicit_options
.ieee
)
1622 rs6000_ieeequad
= 1;
1625 /* Enable Altivec ABI for AIX -maltivec. */
1626 if (TARGET_XCOFF
&& TARGET_ALTIVEC
)
1627 rs6000_altivec_abi
= 1;
1629 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
1630 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
1631 be explicitly overridden in either case. */
1634 if (!rs6000_explicit_options
.altivec_abi
1635 && (TARGET_64BIT
|| TARGET_ALTIVEC
))
1636 rs6000_altivec_abi
= 1;
1638 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
1639 if (!rs6000_explicit_options
.vrsave
)
1640 TARGET_ALTIVEC_VRSAVE
= rs6000_altivec_abi
;
1643 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1644 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
1646 rs6000_darwin64_abi
= 1;
1648 darwin_one_byte_bool
= 1;
1650 /* Default to natural alignment, for better performance. */
1651 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
1654 /* Place FP constants in the constant pool instead of TOC
1655 if section anchors enabled. */
1656 if (flag_section_anchors
)
1657 TARGET_NO_FP_IN_TOC
= 1;
1659 /* Handle -mtls-size option. */
1660 rs6000_parse_tls_size_option ();
1662 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1663 SUBTARGET_OVERRIDE_OPTIONS
;
1665 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1666 SUBSUBTARGET_OVERRIDE_OPTIONS
;
1668 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
1669 SUB3TARGET_OVERRIDE_OPTIONS
;
1674 /* The e500 does not have string instructions, and we set
1675 MASK_STRING above when optimizing for size. */
1676 if ((target_flags
& MASK_STRING
) != 0)
1677 target_flags
= target_flags
& ~MASK_STRING
;
1679 else if (rs6000_select
[1].string
!= NULL
)
1681 /* For the powerpc-eabispe configuration, we set all these by
1682 default, so let's unset them if we manually set another
1683 CPU that is not the E500. */
1684 if (!rs6000_explicit_options
.spe_abi
)
1686 if (!rs6000_explicit_options
.spe
)
1688 if (!rs6000_explicit_options
.float_gprs
)
1689 rs6000_float_gprs
= 0;
1690 if (!rs6000_explicit_options
.isel
)
1694 /* Detect invalid option combinations with E500. */
1697 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
1698 && rs6000_cpu
!= PROCESSOR_POWER5
1699 && rs6000_cpu
!= PROCESSOR_POWER6
1700 && rs6000_cpu
!= PROCESSOR_CELL
);
1701 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
1702 || rs6000_cpu
== PROCESSOR_POWER5
);
1703 rs6000_align_branch_targets
= (rs6000_cpu
== PROCESSOR_POWER4
1704 || rs6000_cpu
== PROCESSOR_POWER5
1705 || rs6000_cpu
== PROCESSOR_POWER6
);
1707 rs6000_sched_restricted_insns_priority
1708 = (rs6000_sched_groups
? 1 : 0);
1710 /* Handle -msched-costly-dep option. */
1711 rs6000_sched_costly_dep
1712 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
1714 if (rs6000_sched_costly_dep_str
)
1716 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
1717 rs6000_sched_costly_dep
= no_dep_costly
;
1718 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
1719 rs6000_sched_costly_dep
= all_deps_costly
;
1720 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
1721 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
1722 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
1723 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
1725 rs6000_sched_costly_dep
= atoi (rs6000_sched_costly_dep_str
);
1728 /* Handle -minsert-sched-nops option. */
1729 rs6000_sched_insert_nops
1730 = (rs6000_sched_groups
? sched_finish_regroup_exact
: sched_finish_none
);
1732 if (rs6000_sched_insert_nops_str
)
1734 if (! strcmp (rs6000_sched_insert_nops_str
, "no"))
1735 rs6000_sched_insert_nops
= sched_finish_none
;
1736 else if (! strcmp (rs6000_sched_insert_nops_str
, "pad"))
1737 rs6000_sched_insert_nops
= sched_finish_pad_groups
;
1738 else if (! strcmp (rs6000_sched_insert_nops_str
, "regroup_exact"))
1739 rs6000_sched_insert_nops
= sched_finish_regroup_exact
;
1741 rs6000_sched_insert_nops
= atoi (rs6000_sched_insert_nops_str
);
1744 #ifdef TARGET_REGNAMES
1745 /* If the user desires alternate register names, copy in the
1746 alternate names now. */
1747 if (TARGET_REGNAMES
)
1748 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
1751 /* Set aix_struct_return last, after the ABI is determined.
1752 If -maix-struct-return or -msvr4-struct-return was explicitly
1753 used, don't override with the ABI default. */
1754 if (!rs6000_explicit_options
.aix_struct_ret
)
1755 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
1757 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
1758 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
1761 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
1763 /* We can only guarantee the availability of DI pseudo-ops when
1764 assembling for 64-bit targets. */
1767 targetm
.asm_out
.aligned_op
.di
= NULL
;
1768 targetm
.asm_out
.unaligned_op
.di
= NULL
;
1771 /* Set branch target alignment, if not optimizing for size. */
1774 /* Cell wants to be aligned 8byte for dual issue. */
1775 if (rs6000_cpu
== PROCESSOR_CELL
)
1777 if (align_functions
<= 0)
1778 align_functions
= 8;
1779 if (align_jumps
<= 0)
1781 if (align_loops
<= 0)
1784 if (rs6000_align_branch_targets
)
1786 if (align_functions
<= 0)
1787 align_functions
= 16;
1788 if (align_jumps
<= 0)
1790 if (align_loops
<= 0)
1793 if (align_jumps_max_skip
<= 0)
1794 align_jumps_max_skip
= 15;
1795 if (align_loops_max_skip
<= 0)
1796 align_loops_max_skip
= 15;
1799 /* Arrange to save and restore machine status around nested functions. */
1800 init_machine_status
= rs6000_init_machine_status
;
1802 /* We should always be splitting complex arguments, but we can't break
1803 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1804 if (DEFAULT_ABI
!= ABI_AIX
)
1805 targetm
.calls
.split_complex_arg
= NULL
;
1807 /* Initialize rs6000_cost with the appropriate target costs. */
1809 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
1813 case PROCESSOR_RIOS1
:
1814 rs6000_cost
= &rios1_cost
;
1817 case PROCESSOR_RIOS2
:
1818 rs6000_cost
= &rios2_cost
;
1821 case PROCESSOR_RS64A
:
1822 rs6000_cost
= &rs64a_cost
;
1825 case PROCESSOR_MPCCORE
:
1826 rs6000_cost
= &mpccore_cost
;
1829 case PROCESSOR_PPC403
:
1830 rs6000_cost
= &ppc403_cost
;
1833 case PROCESSOR_PPC405
:
1834 rs6000_cost
= &ppc405_cost
;
1837 case PROCESSOR_PPC440
:
1838 rs6000_cost
= &ppc440_cost
;
1841 case PROCESSOR_PPC601
:
1842 rs6000_cost
= &ppc601_cost
;
1845 case PROCESSOR_PPC603
:
1846 rs6000_cost
= &ppc603_cost
;
1849 case PROCESSOR_PPC604
:
1850 rs6000_cost
= &ppc604_cost
;
1853 case PROCESSOR_PPC604e
:
1854 rs6000_cost
= &ppc604e_cost
;
1857 case PROCESSOR_PPC620
:
1858 rs6000_cost
= &ppc620_cost
;
1861 case PROCESSOR_PPC630
:
1862 rs6000_cost
= &ppc630_cost
;
1865 case PROCESSOR_CELL
:
1866 rs6000_cost
= &ppccell_cost
;
1869 case PROCESSOR_PPC750
:
1870 case PROCESSOR_PPC7400
:
1871 rs6000_cost
= &ppc750_cost
;
1874 case PROCESSOR_PPC7450
:
1875 rs6000_cost
= &ppc7450_cost
;
1878 case PROCESSOR_PPC8540
:
1879 rs6000_cost
= &ppc8540_cost
;
1882 case PROCESSOR_PPCE300C2
:
1883 case PROCESSOR_PPCE300C3
:
1884 rs6000_cost
= &ppce300c2c3_cost
;
1887 case PROCESSOR_POWER4
:
1888 case PROCESSOR_POWER5
:
1889 rs6000_cost
= &power4_cost
;
1892 case PROCESSOR_POWER6
:
1893 rs6000_cost
= &power6_cost
;
1900 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES
))
1901 set_param_value ("simultaneous-prefetches",
1902 rs6000_cost
->simultaneous_prefetches
);
1903 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE
))
1904 set_param_value ("l1-cache-size", rs6000_cost
->l1_cache_size
);
1905 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE
))
1906 set_param_value ("l1-cache-line-size", rs6000_cost
->cache_line_size
);
1907 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE
))
1908 set_param_value ("l2-cache-size", rs6000_cost
->l2_cache_size
);
1910 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
1911 can be optimized to ap = __builtin_next_arg (0). */
1912 if (DEFAULT_ABI
!= ABI_V4
)
1913 targetm
.expand_builtin_va_start
= NULL
;
1916 /* Implement targetm.vectorize.builtin_mask_for_load. */
1918 rs6000_builtin_mask_for_load (void)
1921 return altivec_builtin_mask_for_load
;
1926 /* Implement targetm.vectorize.builtin_conversion. */
1928 rs6000_builtin_conversion (enum tree_code code
, tree type
)
1930 if (!TARGET_ALTIVEC
)
1936 switch (TYPE_MODE (type
))
1939 return TYPE_UNSIGNED (type
) ?
1940 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCFUX
] :
1941 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCFSX
];
1950 /* Implement targetm.vectorize.builtin_mul_widen_even. */
1952 rs6000_builtin_mul_widen_even (tree type
)
1954 if (!TARGET_ALTIVEC
)
1957 switch (TYPE_MODE (type
))
1960 return TYPE_UNSIGNED (type
) ?
1961 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUH
] :
1962 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESH
];
1965 return TYPE_UNSIGNED (type
) ?
1966 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUB
] :
1967 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESB
];
1973 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
1975 rs6000_builtin_mul_widen_odd (tree type
)
1977 if (!TARGET_ALTIVEC
)
1980 switch (TYPE_MODE (type
))
1983 return TYPE_UNSIGNED (type
) ?
1984 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUH
] :
1985 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSH
];
1988 return TYPE_UNSIGNED (type
) ?
1989 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUB
] :
1990 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSB
];
1997 /* Return true iff, data reference of TYPE can reach vector alignment (16)
1998 after applying N number of iterations. This routine does not determine
1999 how may iterations are required to reach desired alignment. */
2002 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED
, bool is_packed
)
2009 if (rs6000_alignment_flags
== MASK_ALIGN_NATURAL
)
2012 if (rs6000_alignment_flags
== MASK_ALIGN_POWER
)
2022 /* Assuming that all other types are naturally aligned. CHECKME! */
2027 /* Handle generic options of the form -mfoo=yes/no.
2028 NAME is the option name.
2029 VALUE is the option value.
2030 FLAG is the pointer to the flag where to store a 1 or 0, depending on
2031 whether the option value is 'yes' or 'no' respectively. */
2033 rs6000_parse_yes_no_option (const char *name
, const char *value
, int *flag
)
2037 else if (!strcmp (value
, "yes"))
2039 else if (!strcmp (value
, "no"))
2042 error ("unknown -m%s= option specified: '%s'", name
, value
);
2045 /* Validate and record the size specified with the -mtls-size option. */
2048 rs6000_parse_tls_size_option (void)
2050 if (rs6000_tls_size_string
== 0)
2052 else if (strcmp (rs6000_tls_size_string
, "16") == 0)
2053 rs6000_tls_size
= 16;
2054 else if (strcmp (rs6000_tls_size_string
, "32") == 0)
2055 rs6000_tls_size
= 32;
2056 else if (strcmp (rs6000_tls_size_string
, "64") == 0)
2057 rs6000_tls_size
= 64;
2059 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string
);
2063 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
2065 if (DEFAULT_ABI
== ABI_DARWIN
)
2066 /* The Darwin libraries never set errno, so we might as well
2067 avoid calling them when that's the only reason we would. */
2068 flag_errno_math
= 0;
2070 /* Double growth factor to counter reduced min jump length. */
2071 set_param_value ("max-grow-copy-bb-insns", 16);
2073 /* Enable section anchors by default.
2074 Skip section anchors for Objective C and Objective C++
2075 until front-ends fixed. */
2076 if (!TARGET_MACHO
&& lang_hooks
.name
[4] != 'O')
2077 flag_section_anchors
= 1;
2080 /* Implement TARGET_HANDLE_OPTION. */
2083 rs6000_handle_option (size_t code
, const char *arg
, int value
)
2088 target_flags
&= ~(MASK_POWER
| MASK_POWER2
2089 | MASK_MULTIPLE
| MASK_STRING
);
2090 target_flags_explicit
|= (MASK_POWER
| MASK_POWER2
2091 | MASK_MULTIPLE
| MASK_STRING
);
2093 case OPT_mno_powerpc
:
2094 target_flags
&= ~(MASK_POWERPC
| MASK_PPC_GPOPT
2095 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
2096 target_flags_explicit
|= (MASK_POWERPC
| MASK_PPC_GPOPT
2097 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
2100 target_flags
&= ~MASK_MINIMAL_TOC
;
2101 TARGET_NO_FP_IN_TOC
= 0;
2102 TARGET_NO_SUM_IN_TOC
= 0;
2103 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2104 #ifdef TARGET_USES_SYSV4_OPT
2105 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
2106 just the same as -mminimal-toc. */
2107 target_flags
|= MASK_MINIMAL_TOC
;
2108 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2112 #ifdef TARGET_USES_SYSV4_OPT
2114 /* Make -mtoc behave like -mminimal-toc. */
2115 target_flags
|= MASK_MINIMAL_TOC
;
2116 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2120 #ifdef TARGET_USES_AIX64_OPT
2125 target_flags
|= MASK_POWERPC64
| MASK_POWERPC
;
2126 target_flags
|= ~target_flags_explicit
& MASK_PPC_GFXOPT
;
2127 target_flags_explicit
|= MASK_POWERPC64
| MASK_POWERPC
;
2130 #ifdef TARGET_USES_AIX64_OPT
2135 target_flags
&= ~MASK_POWERPC64
;
2136 target_flags_explicit
|= MASK_POWERPC64
;
2139 case OPT_minsert_sched_nops_
:
2140 rs6000_sched_insert_nops_str
= arg
;
2143 case OPT_mminimal_toc
:
2146 TARGET_NO_FP_IN_TOC
= 0;
2147 TARGET_NO_SUM_IN_TOC
= 0;
2154 target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
2155 target_flags_explicit
|= (MASK_MULTIPLE
| MASK_STRING
);
2162 target_flags
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
2163 target_flags_explicit
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
2167 case OPT_mpowerpc_gpopt
:
2168 case OPT_mpowerpc_gfxopt
:
2171 target_flags
|= MASK_POWERPC
;
2172 target_flags_explicit
|= MASK_POWERPC
;
2176 case OPT_maix_struct_return
:
2177 case OPT_msvr4_struct_return
:
2178 rs6000_explicit_options
.aix_struct_ret
= true;
2182 rs6000_explicit_options
.vrsave
= true;
2183 rs6000_parse_yes_no_option ("vrsave", arg
, &(TARGET_ALTIVEC_VRSAVE
));
2187 rs6000_explicit_options
.isel
= true;
2188 rs6000_isel
= value
;
2192 rs6000_explicit_options
.isel
= true;
2193 rs6000_parse_yes_no_option ("isel", arg
, &(rs6000_isel
));
2197 rs6000_explicit_options
.spe
= true;
2202 rs6000_explicit_options
.spe
= true;
2203 rs6000_parse_yes_no_option ("spe", arg
, &(rs6000_spe
));
2207 rs6000_debug_name
= arg
;
2210 #ifdef TARGET_USES_SYSV4_OPT
2212 rs6000_abi_name
= arg
;
2216 rs6000_sdata_name
= arg
;
2219 case OPT_mtls_size_
:
2220 rs6000_tls_size_string
= arg
;
2223 case OPT_mrelocatable
:
2226 target_flags
|= MASK_MINIMAL_TOC
;
2227 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2228 TARGET_NO_FP_IN_TOC
= 1;
2232 case OPT_mrelocatable_lib
:
2235 target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
2236 target_flags_explicit
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
2237 TARGET_NO_FP_IN_TOC
= 1;
2241 target_flags
&= ~MASK_RELOCATABLE
;
2242 target_flags_explicit
|= MASK_RELOCATABLE
;
2248 if (!strcmp (arg
, "altivec"))
2250 rs6000_explicit_options
.altivec_abi
= true;
2251 rs6000_altivec_abi
= 1;
2253 /* Enabling the AltiVec ABI turns off the SPE ABI. */
2256 else if (! strcmp (arg
, "no-altivec"))
2258 rs6000_explicit_options
.altivec_abi
= true;
2259 rs6000_altivec_abi
= 0;
2261 else if (! strcmp (arg
, "spe"))
2263 rs6000_explicit_options
.spe_abi
= true;
2265 rs6000_altivec_abi
= 0;
2266 if (!TARGET_SPE_ABI
)
2267 error ("not configured for ABI: '%s'", arg
);
2269 else if (! strcmp (arg
, "no-spe"))
2271 rs6000_explicit_options
.spe_abi
= true;
2275 /* These are here for testing during development only, do not
2276 document in the manual please. */
2277 else if (! strcmp (arg
, "d64"))
2279 rs6000_darwin64_abi
= 1;
2280 warning (0, "Using darwin64 ABI");
2282 else if (! strcmp (arg
, "d32"))
2284 rs6000_darwin64_abi
= 0;
2285 warning (0, "Using old darwin ABI");
2288 else if (! strcmp (arg
, "ibmlongdouble"))
2290 rs6000_explicit_options
.ieee
= true;
2291 rs6000_ieeequad
= 0;
2292 warning (0, "Using IBM extended precision long double");
2294 else if (! strcmp (arg
, "ieeelongdouble"))
2296 rs6000_explicit_options
.ieee
= true;
2297 rs6000_ieeequad
= 1;
2298 warning (0, "Using IEEE extended precision long double");
2303 error ("unknown ABI specified: '%s'", arg
);
2309 rs6000_select
[1].string
= arg
;
2313 rs6000_select
[2].string
= arg
;
2316 case OPT_mtraceback_
:
2317 rs6000_traceback_name
= arg
;
2320 case OPT_mfloat_gprs_
:
2321 rs6000_explicit_options
.float_gprs
= true;
2322 if (! strcmp (arg
, "yes") || ! strcmp (arg
, "single"))
2323 rs6000_float_gprs
= 1;
2324 else if (! strcmp (arg
, "double"))
2325 rs6000_float_gprs
= 2;
2326 else if (! strcmp (arg
, "no"))
2327 rs6000_float_gprs
= 0;
2330 error ("invalid option for -mfloat-gprs: '%s'", arg
);
2335 case OPT_mlong_double_
:
2336 rs6000_explicit_options
.long_double
= true;
2337 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2338 if (value
!= 64 && value
!= 128)
2340 error ("Unknown switch -mlong-double-%s", arg
);
2341 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2345 rs6000_long_double_type_size
= value
;
2348 case OPT_msched_costly_dep_
:
2349 rs6000_sched_costly_dep_str
= arg
;
2353 rs6000_explicit_options
.alignment
= true;
2354 if (! strcmp (arg
, "power"))
2356 /* On 64-bit Darwin, power alignment is ABI-incompatible with
2357 some C library functions, so warn about it. The flag may be
2358 useful for performance studies from time to time though, so
2359 don't disable it entirely. */
2360 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
2361 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2362 " it is incompatible with the installed C and C++ libraries");
2363 rs6000_alignment_flags
= MASK_ALIGN_POWER
;
2365 else if (! strcmp (arg
, "natural"))
2366 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
2369 error ("unknown -malign-XXXXX option specified: '%s'", arg
);
2377 /* Do anything needed at the start of the asm file. */
2380 rs6000_file_start (void)
2384 const char *start
= buffer
;
2385 struct rs6000_cpu_select
*ptr
;
2386 const char *default_cpu
= TARGET_CPU_DEFAULT
;
2387 FILE *file
= asm_out_file
;
2389 default_file_start ();
2391 #ifdef TARGET_BI_ARCH
2392 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
2396 if (flag_verbose_asm
)
2398 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
2399 rs6000_select
[0].string
= default_cpu
;
2401 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
2403 ptr
= &rs6000_select
[i
];
2404 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
2406 fprintf (file
, "%s %s%s", start
, ptr
->name
, ptr
->string
);
2411 if (PPC405_ERRATUM77
)
2413 fprintf (file
, "%s PPC405CR_ERRATUM77", start
);
2417 #ifdef USING_ELFOS_H
2418 switch (rs6000_sdata
)
2420 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
2421 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
2422 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
2423 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
2426 if (rs6000_sdata
&& g_switch_value
)
2428 fprintf (file
, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED
, start
,
2438 #ifdef HAVE_AS_GNU_ATTRIBUTE
2439 if (TARGET_32BIT
&& DEFAULT_ABI
== ABI_V4
)
2441 fprintf (file
, "\t.gnu_attribute 4, %d\n",
2442 (TARGET_HARD_FLOAT
&& TARGET_FPRS
) ? 1 : 2);
2443 fprintf (file
, "\t.gnu_attribute 8, %d\n",
2444 (TARGET_ALTIVEC_ABI
? 2
2445 : TARGET_SPE_ABI
? 3
2450 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
2452 switch_to_section (toc_section
);
2453 switch_to_section (text_section
);
2458 /* Return nonzero if this function is known to have a null epilogue. */
2461 direct_return (void)
2463 if (reload_completed
)
2465 rs6000_stack_t
*info
= rs6000_stack_info ();
2467 if (info
->first_gp_reg_save
== 32
2468 && info
->first_fp_reg_save
== 64
2469 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
2470 && ! info
->lr_save_p
2471 && ! info
->cr_save_p
2472 && info
->vrsave_mask
== 0
2480 /* Return the number of instructions it takes to form a constant in an
2481 integer register. */
2484 num_insns_constant_wide (HOST_WIDE_INT value
)
2486 /* signed constant loadable with {cal|addi} */
2487 if ((unsigned HOST_WIDE_INT
) (value
+ 0x8000) < 0x10000)
2490 /* constant loadable with {cau|addis} */
2491 else if ((value
& 0xffff) == 0
2492 && (value
>> 31 == -1 || value
>> 31 == 0))
2495 #if HOST_BITS_PER_WIDE_INT == 64
2496 else if (TARGET_POWERPC64
)
2498 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
2499 HOST_WIDE_INT high
= value
>> 31;
2501 if (high
== 0 || high
== -1)
2507 return num_insns_constant_wide (high
) + 1;
2509 return (num_insns_constant_wide (high
)
2510 + num_insns_constant_wide (low
) + 1);
2519 num_insns_constant (rtx op
, enum machine_mode mode
)
2521 HOST_WIDE_INT low
, high
;
2523 switch (GET_CODE (op
))
2526 #if HOST_BITS_PER_WIDE_INT == 64
2527 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
2528 && mask64_operand (op
, mode
))
2532 return num_insns_constant_wide (INTVAL (op
));
2535 if (mode
== SFmode
|| mode
== SDmode
)
2540 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2541 if (DECIMAL_FLOAT_MODE_P (mode
))
2542 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
2544 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
2545 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
2548 if (mode
== VOIDmode
|| mode
== DImode
)
2550 high
= CONST_DOUBLE_HIGH (op
);
2551 low
= CONST_DOUBLE_LOW (op
);
2558 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2559 if (DECIMAL_FLOAT_MODE_P (mode
))
2560 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, l
);
2562 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
2563 high
= l
[WORDS_BIG_ENDIAN
== 0];
2564 low
= l
[WORDS_BIG_ENDIAN
!= 0];
2568 return (num_insns_constant_wide (low
)
2569 + num_insns_constant_wide (high
));
2572 if ((high
== 0 && low
>= 0)
2573 || (high
== -1 && low
< 0))
2574 return num_insns_constant_wide (low
);
2576 else if (mask64_operand (op
, mode
))
2580 return num_insns_constant_wide (high
) + 1;
2583 return (num_insns_constant_wide (high
)
2584 + num_insns_constant_wide (low
) + 1);
2592 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
2593 If the mode of OP is MODE_VECTOR_INT, this simply returns the
2594 corresponding element of the vector, but for V4SFmode and V2SFmode,
2595 the corresponding "float" is interpreted as an SImode integer. */
2597 static HOST_WIDE_INT
2598 const_vector_elt_as_int (rtx op
, unsigned int elt
)
2600 rtx tmp
= CONST_VECTOR_ELT (op
, elt
);
2601 if (GET_MODE (op
) == V4SFmode
2602 || GET_MODE (op
) == V2SFmode
)
2603 tmp
= gen_lowpart (SImode
, tmp
);
2604 return INTVAL (tmp
);
2607 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
2608 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2609 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2610 all items are set to the same value and contain COPIES replicas of the
2611 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2612 operand and the others are set to the value of the operand's msb. */
2615 vspltis_constant (rtx op
, unsigned step
, unsigned copies
)
2617 enum machine_mode mode
= GET_MODE (op
);
2618 enum machine_mode inner
= GET_MODE_INNER (mode
);
2621 unsigned nunits
= GET_MODE_NUNITS (mode
);
2622 unsigned bitsize
= GET_MODE_BITSIZE (inner
);
2623 unsigned mask
= GET_MODE_MASK (inner
);
2625 HOST_WIDE_INT val
= const_vector_elt_as_int (op
, nunits
- 1);
2626 HOST_WIDE_INT splat_val
= val
;
2627 HOST_WIDE_INT msb_val
= val
> 0 ? 0 : -1;
2629 /* Construct the value to be splatted, if possible. If not, return 0. */
2630 for (i
= 2; i
<= copies
; i
*= 2)
2632 HOST_WIDE_INT small_val
;
2634 small_val
= splat_val
>> bitsize
;
2636 if (splat_val
!= ((small_val
<< bitsize
) | (small_val
& mask
)))
2638 splat_val
= small_val
;
2641 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2642 if (EASY_VECTOR_15 (splat_val
))
2645 /* Also check if we can splat, and then add the result to itself. Do so if
2646 the value is positive, of if the splat instruction is using OP's mode;
2647 for splat_val < 0, the splat and the add should use the same mode. */
2648 else if (EASY_VECTOR_15_ADD_SELF (splat_val
)
2649 && (splat_val
>= 0 || (step
== 1 && copies
== 1)))
2655 /* Check if VAL is present in every STEP-th element, and the
2656 other elements are filled with its most significant bit. */
2657 for (i
= 0; i
< nunits
- 1; ++i
)
2659 HOST_WIDE_INT desired_val
;
2660 if (((i
+ 1) & (step
- 1)) == 0)
2663 desired_val
= msb_val
;
2665 if (desired_val
!= const_vector_elt_as_int (op
, i
))
2673 /* Return true if OP is of the given MODE and can be synthesized
2674 with a vspltisb, vspltish or vspltisw. */
2677 easy_altivec_constant (rtx op
, enum machine_mode mode
)
2679 unsigned step
, copies
;
2681 if (mode
== VOIDmode
)
2682 mode
= GET_MODE (op
);
2683 else if (mode
!= GET_MODE (op
))
2686 /* Start with a vspltisw. */
2687 step
= GET_MODE_NUNITS (mode
) / 4;
2690 if (vspltis_constant (op
, step
, copies
))
2693 /* Then try with a vspltish. */
2699 if (vspltis_constant (op
, step
, copies
))
2702 /* And finally a vspltisb. */
2708 if (vspltis_constant (op
, step
, copies
))
2714 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2715 result is OP. Abort if it is not possible. */
2718 gen_easy_altivec_constant (rtx op
)
2720 enum machine_mode mode
= GET_MODE (op
);
2721 int nunits
= GET_MODE_NUNITS (mode
);
2722 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
2723 unsigned step
= nunits
/ 4;
2724 unsigned copies
= 1;
2726 /* Start with a vspltisw. */
2727 if (vspltis_constant (op
, step
, copies
))
2728 return gen_rtx_VEC_DUPLICATE (V4SImode
, gen_lowpart (SImode
, last
));
2730 /* Then try with a vspltish. */
2736 if (vspltis_constant (op
, step
, copies
))
2737 return gen_rtx_VEC_DUPLICATE (V8HImode
, gen_lowpart (HImode
, last
));
2739 /* And finally a vspltisb. */
2745 if (vspltis_constant (op
, step
, copies
))
2746 return gen_rtx_VEC_DUPLICATE (V16QImode
, gen_lowpart (QImode
, last
));
2752 output_vec_const_move (rtx
*operands
)
2755 enum machine_mode mode
;
2760 mode
= GET_MODE (dest
);
2765 if (zero_constant (vec
, mode
))
2766 return "vxor %0,%0,%0";
2768 splat_vec
= gen_easy_altivec_constant (vec
);
2769 gcc_assert (GET_CODE (splat_vec
) == VEC_DUPLICATE
);
2770 operands
[1] = XEXP (splat_vec
, 0);
2771 if (!EASY_VECTOR_15 (INTVAL (operands
[1])))
2774 switch (GET_MODE (splat_vec
))
2777 return "vspltisw %0,%1";
2780 return "vspltish %0,%1";
2783 return "vspltisb %0,%1";
2790 gcc_assert (TARGET_SPE
);
2792 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2793 pattern of V1DI, V4HI, and V2SF.
2795 FIXME: We should probably return # and add post reload
2796 splitters for these, but this way is so easy ;-). */
2797 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
2798 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
2799 operands
[1] = CONST_VECTOR_ELT (vec
, 0);
2800 operands
[2] = CONST_VECTOR_ELT (vec
, 1);
2802 return "li %0,%1\n\tevmergelo %0,%0,%0";
2804 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
2807 /* Initialize TARGET of vector PAIRED to VALS. */
2810 paired_expand_vector_init (rtx target
, rtx vals
)
2812 enum machine_mode mode
= GET_MODE (target
);
2813 int n_elts
= GET_MODE_NUNITS (mode
);
2815 rtx x
, new, tmp
, constant_op
, op1
, op2
;
2818 for (i
= 0; i
< n_elts
; ++i
)
2820 x
= XVECEXP (vals
, 0, i
);
2821 if (!CONSTANT_P (x
))
2826 /* Load from constant pool. */
2827 emit_move_insn (target
, gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0)));
2833 /* The vector is initialized only with non-constants. */
2834 new = gen_rtx_VEC_CONCAT (V2SFmode
, XVECEXP (vals
, 0, 0),
2835 XVECEXP (vals
, 0, 1));
2837 emit_move_insn (target
, new);
2841 /* One field is non-constant and the other one is a constant. Load the
2842 constant from the constant pool and use ps_merge instruction to
2843 construct the whole vector. */
2844 op1
= XVECEXP (vals
, 0, 0);
2845 op2
= XVECEXP (vals
, 0, 1);
2847 constant_op
= (CONSTANT_P (op1
)) ? op1
: op2
;
2849 tmp
= gen_reg_rtx (GET_MODE (constant_op
));
2850 emit_move_insn (tmp
, constant_op
);
2852 if (CONSTANT_P (op1
))
2853 new = gen_rtx_VEC_CONCAT (V2SFmode
, tmp
, op2
);
2855 new = gen_rtx_VEC_CONCAT (V2SFmode
, op1
, tmp
);
2857 emit_move_insn (target
, new);
2861 paired_expand_vector_move (rtx operands
[])
2863 rtx op0
= operands
[0], op1
= operands
[1];
2865 emit_move_insn (op0
, op1
);
2868 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
2869 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
2870 operands for the relation operation COND. This is a recursive
2874 paired_emit_vector_compare (enum rtx_code rcode
,
2875 rtx dest
, rtx op0
, rtx op1
,
2876 rtx cc_op0
, rtx cc_op1
)
2878 rtx tmp
= gen_reg_rtx (V2SFmode
);
2879 rtx tmp1
, max
, min
, equal_zero
;
2881 gcc_assert (TARGET_PAIRED_FLOAT
);
2882 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
2888 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
2892 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
2893 emit_insn (gen_selv2sf4 (dest
, tmp
, op0
, op1
, CONST0_RTX (SFmode
)));
2897 paired_emit_vector_compare (GE
, dest
, op0
, op1
, cc_op1
, cc_op0
);
2900 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
2903 tmp1
= gen_reg_rtx (V2SFmode
);
2904 max
= gen_reg_rtx (V2SFmode
);
2905 min
= gen_reg_rtx (V2SFmode
);
2906 equal_zero
= gen_reg_rtx (V2SFmode
);
2908 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
2909 emit_insn (gen_selv2sf4
2910 (max
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
2911 emit_insn (gen_subv2sf3 (tmp
, cc_op1
, cc_op0
));
2912 emit_insn (gen_selv2sf4
2913 (min
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
2914 emit_insn (gen_subv2sf3 (tmp1
, min
, max
));
2915 emit_insn (gen_selv2sf4 (dest
, tmp1
, op0
, op1
, CONST0_RTX (SFmode
)));
2918 paired_emit_vector_compare (EQ
, dest
, op1
, op0
, cc_op0
, cc_op1
);
2921 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
2924 paired_emit_vector_compare (LT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
2927 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
2930 paired_emit_vector_compare (GT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
2939 /* Emit vector conditional expression.
2940 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
2941 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
2944 paired_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
2945 rtx cond
, rtx cc_op0
, rtx cc_op1
)
2947 enum rtx_code rcode
= GET_CODE (cond
);
2949 if (!TARGET_PAIRED_FLOAT
)
2952 paired_emit_vector_compare (rcode
, dest
, op1
, op2
, cc_op0
, cc_op1
);
2957 /* Initialize vector TARGET to VALS. */
2960 rs6000_expand_vector_init (rtx target
, rtx vals
)
2962 enum machine_mode mode
= GET_MODE (target
);
2963 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
2964 int n_elts
= GET_MODE_NUNITS (mode
);
2965 int n_var
= 0, one_var
= -1;
2966 bool all_same
= true, all_const_zero
= true;
2970 for (i
= 0; i
< n_elts
; ++i
)
2972 x
= XVECEXP (vals
, 0, i
);
2973 if (!CONSTANT_P (x
))
2974 ++n_var
, one_var
= i
;
2975 else if (x
!= CONST0_RTX (inner_mode
))
2976 all_const_zero
= false;
2978 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
2984 rtx const_vec
= gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0));
2985 if (mode
!= V4SFmode
&& all_const_zero
)
2987 /* Zero register. */
2988 emit_insn (gen_rtx_SET (VOIDmode
, target
,
2989 gen_rtx_XOR (mode
, target
, target
)));
2992 else if (mode
!= V4SFmode
&& easy_vector_constant (const_vec
, mode
))
2994 /* Splat immediate. */
2995 emit_insn (gen_rtx_SET (VOIDmode
, target
, const_vec
));
2999 ; /* Splat vector element. */
3002 /* Load from constant pool. */
3003 emit_move_insn (target
, const_vec
);
3008 /* Store value to stack temp. Load vector element. Splat. */
3011 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
3012 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0),
3013 XVECEXP (vals
, 0, 0));
3014 x
= gen_rtx_UNSPEC (VOIDmode
,
3015 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
3016 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3018 gen_rtx_SET (VOIDmode
,
3021 x
= gen_rtx_VEC_SELECT (inner_mode
, target
,
3022 gen_rtx_PARALLEL (VOIDmode
,
3023 gen_rtvec (1, const0_rtx
)));
3024 emit_insn (gen_rtx_SET (VOIDmode
, target
,
3025 gen_rtx_VEC_DUPLICATE (mode
, x
)));
3029 /* One field is non-constant. Load constant then overwrite
3033 rtx copy
= copy_rtx (vals
);
3035 /* Load constant part of vector, substitute neighboring value for
3037 XVECEXP (copy
, 0, one_var
) = XVECEXP (vals
, 0, (one_var
+ 1) % n_elts
);
3038 rs6000_expand_vector_init (target
, copy
);
3040 /* Insert variable. */
3041 rs6000_expand_vector_set (target
, XVECEXP (vals
, 0, one_var
), one_var
);
3045 /* Construct the vector in memory one field at a time
3046 and load the whole vector. */
3047 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
3048 for (i
= 0; i
< n_elts
; i
++)
3049 emit_move_insn (adjust_address_nv (mem
, inner_mode
,
3050 i
* GET_MODE_SIZE (inner_mode
)),
3051 XVECEXP (vals
, 0, i
));
3052 emit_move_insn (target
, mem
);
3055 /* Set field ELT of TARGET to VAL. */
3058 rs6000_expand_vector_set (rtx target
, rtx val
, int elt
)
3060 enum machine_mode mode
= GET_MODE (target
);
3061 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
3062 rtx reg
= gen_reg_rtx (mode
);
3064 int width
= GET_MODE_SIZE (inner_mode
);
3067 /* Load single variable value. */
3068 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
3069 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0), val
);
3070 x
= gen_rtx_UNSPEC (VOIDmode
,
3071 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
3072 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3074 gen_rtx_SET (VOIDmode
,
3078 /* Linear sequence. */
3079 mask
= gen_rtx_PARALLEL (V16QImode
, rtvec_alloc (16));
3080 for (i
= 0; i
< 16; ++i
)
3081 XVECEXP (mask
, 0, i
) = GEN_INT (i
);
3083 /* Set permute mask to insert element into target. */
3084 for (i
= 0; i
< width
; ++i
)
3085 XVECEXP (mask
, 0, elt
*width
+ i
)
3086 = GEN_INT (i
+ 0x10);
3087 x
= gen_rtx_CONST_VECTOR (V16QImode
, XVEC (mask
, 0));
3088 x
= gen_rtx_UNSPEC (mode
,
3089 gen_rtvec (3, target
, reg
,
3090 force_reg (V16QImode
, x
)),
3092 emit_insn (gen_rtx_SET (VOIDmode
, target
, x
));
3095 /* Extract field ELT from VEC into TARGET. */
3098 rs6000_expand_vector_extract (rtx target
, rtx vec
, int elt
)
3100 enum machine_mode mode
= GET_MODE (vec
);
3101 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
3104 /* Allocate mode-sized buffer. */
3105 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
3107 /* Add offset to field within buffer matching vector element. */
3108 mem
= adjust_address_nv (mem
, mode
, elt
* GET_MODE_SIZE (inner_mode
));
3110 /* Store single field into mode-sized buffer. */
3111 x
= gen_rtx_UNSPEC (VOIDmode
,
3112 gen_rtvec (1, const0_rtx
), UNSPEC_STVE
);
3113 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3115 gen_rtx_SET (VOIDmode
,
3118 emit_move_insn (target
, adjust_address_nv (mem
, inner_mode
, 0));
3121 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
3122 implement ANDing by the mask IN. */
3124 build_mask64_2_operands (rtx in
, rtx
*out
)
3126 #if HOST_BITS_PER_WIDE_INT >= 64
3127 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
3130 gcc_assert (GET_CODE (in
) == CONST_INT
);
3135 /* Assume c initially something like 0x00fff000000fffff. The idea
3136 is to rotate the word so that the middle ^^^^^^ group of zeros
3137 is at the MS end and can be cleared with an rldicl mask. We then
3138 rotate back and clear off the MS ^^ group of zeros with a
3140 c
= ~c
; /* c == 0xff000ffffff00000 */
3141 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
3142 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
3143 c
= ~c
; /* c == 0x00fff000000fffff */
3144 c
&= -lsb
; /* c == 0x00fff00000000000 */
3145 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
3146 c
= ~c
; /* c == 0xff000fffffffffff */
3147 c
&= -lsb
; /* c == 0xff00000000000000 */
3149 while ((lsb
>>= 1) != 0)
3150 shift
++; /* shift == 44 on exit from loop */
3151 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
3152 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
3153 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
3157 /* Assume c initially something like 0xff000f0000000000. The idea
3158 is to rotate the word so that the ^^^ middle group of zeros
3159 is at the LS end and can be cleared with an rldicr mask. We then
3160 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
3162 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
3163 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
3164 c
= ~c
; /* c == 0x00fff0ffffffffff */
3165 c
&= -lsb
; /* c == 0x00fff00000000000 */
3166 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
3167 c
= ~c
; /* c == 0xff000fffffffffff */
3168 c
&= -lsb
; /* c == 0xff00000000000000 */
3170 while ((lsb
>>= 1) != 0)
3171 shift
++; /* shift == 44 on exit from loop */
3172 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
3173 m1
>>= shift
; /* m1 == 0x0000000000000fff */
3174 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
3177 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
3178 masks will be all 1's. We are guaranteed more than one transition. */
3179 out
[0] = GEN_INT (64 - shift
);
3180 out
[1] = GEN_INT (m1
);
3181 out
[2] = GEN_INT (shift
);
3182 out
[3] = GEN_INT (m2
);
3190 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
3193 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
3195 if (TARGET_E500_DOUBLE
)
3197 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
3198 subreg:TI and reg:TF. */
3199 if (GET_CODE (op
) == SUBREG
3200 && (mode
== SImode
|| mode
== DImode
|| mode
== TImode
)
3201 && REG_P (SUBREG_REG (op
))
3202 && (GET_MODE (SUBREG_REG (op
)) == DFmode
3203 || GET_MODE (SUBREG_REG (op
)) == TFmode
3204 || GET_MODE (SUBREG_REG (op
)) == DDmode
3205 || GET_MODE (SUBREG_REG (op
)) == TDmode
))
3208 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
3210 if (GET_CODE (op
) == SUBREG
3211 && (mode
== DFmode
|| mode
== TFmode
3212 || mode
== DDmode
|| mode
== TDmode
)
3213 && REG_P (SUBREG_REG (op
))
3214 && (GET_MODE (SUBREG_REG (op
)) == DImode
3215 || GET_MODE (SUBREG_REG (op
)) == TImode
))
3220 && GET_CODE (op
) == SUBREG
3222 && REG_P (SUBREG_REG (op
))
3223 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op
))))
3229 /* AIX increases natural record alignment to doubleword if the first
3230 field is an FP double while the FP fields remain word aligned. */
3233 rs6000_special_round_type_align (tree type
, unsigned int computed
,
3234 unsigned int specified
)
3236 unsigned int align
= MAX (computed
, specified
);
3237 tree field
= TYPE_FIELDS (type
);
3239 /* Skip all non field decls */
3240 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
3241 field
= TREE_CHAIN (field
);
3243 if (field
!= NULL
&& field
!= type
)
3245 type
= TREE_TYPE (field
);
3246 while (TREE_CODE (type
) == ARRAY_TYPE
)
3247 type
= TREE_TYPE (type
);
3249 if (type
!= error_mark_node
&& TYPE_MODE (type
) == DFmode
)
3250 align
= MAX (align
, 64);
3256 /* Darwin increases record alignment to the natural alignment of
3260 darwin_rs6000_special_round_type_align (tree type
, unsigned int computed
,
3261 unsigned int specified
)
3263 unsigned int align
= MAX (computed
, specified
);
3265 if (TYPE_PACKED (type
))
3268 /* Find the first field, looking down into aggregates. */
3270 tree field
= TYPE_FIELDS (type
);
3271 /* Skip all non field decls */
3272 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
3273 field
= TREE_CHAIN (field
);
3276 type
= TREE_TYPE (field
);
3277 while (TREE_CODE (type
) == ARRAY_TYPE
)
3278 type
= TREE_TYPE (type
);
3279 } while (AGGREGATE_TYPE_P (type
));
3281 if (! AGGREGATE_TYPE_P (type
) && type
!= error_mark_node
)
3282 align
= MAX (align
, TYPE_ALIGN (type
));
3287 /* Return 1 for an operand in small memory on V.4/eabi. */
3290 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
3291 enum machine_mode mode ATTRIBUTE_UNUSED
)
3296 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
3299 if (DEFAULT_ABI
!= ABI_V4
)
3302 /* Vector and float memory instructions have a limited offset on the
3303 SPE, so using a vector or float variable directly as an operand is
3306 && (SPE_VECTOR_MODE (mode
) || FLOAT_MODE_P (mode
)))
3309 if (GET_CODE (op
) == SYMBOL_REF
)
3312 else if (GET_CODE (op
) != CONST
3313 || GET_CODE (XEXP (op
, 0)) != PLUS
3314 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
3315 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
3320 rtx sum
= XEXP (op
, 0);
3321 HOST_WIDE_INT summand
;
3323 /* We have to be careful here, because it is the referenced address
3324 that must be 32k from _SDA_BASE_, not just the symbol. */
3325 summand
= INTVAL (XEXP (sum
, 1));
3326 if (summand
< 0 || (unsigned HOST_WIDE_INT
) summand
> g_switch_value
)
3329 sym_ref
= XEXP (sum
, 0);
3332 return SYMBOL_REF_SMALL_P (sym_ref
);
3338 /* Return true if either operand is a general purpose register. */
3341 gpr_or_gpr_p (rtx op0
, rtx op1
)
3343 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
3344 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
3348 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
3351 constant_pool_expr_1 (rtx op
, int *have_sym
, int *have_toc
)
3353 switch (GET_CODE (op
))
3356 if (RS6000_SYMBOL_REF_TLS_P (op
))
3358 else if (CONSTANT_POOL_ADDRESS_P (op
))
3360 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op
), Pmode
))
3368 else if (! strcmp (XSTR (op
, 0), toc_label_name
))
3377 return (constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
)
3378 && constant_pool_expr_1 (XEXP (op
, 1), have_sym
, have_toc
));
3380 return constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
);
3389 constant_pool_expr_p (rtx op
)
3393 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_sym
;
3397 toc_relative_expr_p (rtx op
)
3401 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_toc
;
3405 legitimate_constant_pool_address_p (rtx x
)
3408 && GET_CODE (x
) == PLUS
3409 && GET_CODE (XEXP (x
, 0)) == REG
3410 && (TARGET_MINIMAL_TOC
|| REGNO (XEXP (x
, 0)) == TOC_REGISTER
)
3411 && constant_pool_expr_p (XEXP (x
, 1)));
3415 legitimate_small_data_p (enum machine_mode mode
, rtx x
)
3417 return (DEFAULT_ABI
== ABI_V4
3418 && !flag_pic
&& !TARGET_TOC
3419 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
3420 && small_data_operand (x
, mode
));
3423 /* SPE offset addressing is limited to 5-bits worth of double words. */
3424 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
3427 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
3429 unsigned HOST_WIDE_INT offset
, extra
;
3431 if (GET_CODE (x
) != PLUS
)
3433 if (GET_CODE (XEXP (x
, 0)) != REG
)
3435 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
3437 if (legitimate_constant_pool_address_p (x
))
3439 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
3442 offset
= INTVAL (XEXP (x
, 1));
3450 /* AltiVec vector modes. Only reg+reg addressing is valid and
3451 constant offset zero should not occur due to canonicalization. */
3458 /* Paired vector modes. Only reg+reg addressing is valid and
3459 constant offset zero should not occur due to canonicalization. */
3460 if (TARGET_PAIRED_FLOAT
)
3462 /* SPE vector modes. */
3463 return SPE_CONST_OFFSET_OK (offset
);
3467 if (TARGET_E500_DOUBLE
)
3468 return SPE_CONST_OFFSET_OK (offset
);
3471 /* On e500v2, we may have:
3473 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
3475 Which gets addressed with evldd instructions. */
3476 if (TARGET_E500_DOUBLE
)
3477 return SPE_CONST_OFFSET_OK (offset
);
3479 if (mode
== DFmode
|| mode
== DDmode
|| !TARGET_POWERPC64
)
3481 else if (offset
& 3)
3487 if (TARGET_E500_DOUBLE
)
3488 return (SPE_CONST_OFFSET_OK (offset
)
3489 && SPE_CONST_OFFSET_OK (offset
+ 8));
3492 if (mode
== TFmode
|| mode
== TDmode
|| !TARGET_POWERPC64
)
3494 else if (offset
& 3)
3505 return (offset
< 0x10000) && (offset
+ extra
< 0x10000);
3509 legitimate_indexed_address_p (rtx x
, int strict
)
3513 if (GET_CODE (x
) != PLUS
)
3519 /* Recognize the rtl generated by reload which we know will later be
3520 replaced with proper base and index regs. */
3522 && reload_in_progress
3523 && (REG_P (op0
) || GET_CODE (op0
) == PLUS
)
3527 return (REG_P (op0
) && REG_P (op1
)
3528 && ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
3529 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
3530 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
3531 && INT_REG_OK_FOR_INDEX_P (op0
, strict
))));
3535 legitimate_indirect_address_p (rtx x
, int strict
)
3537 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
3541 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
3543 if (!TARGET_MACHO
|| !flag_pic
3544 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
3548 if (GET_CODE (x
) != LO_SUM
)
3550 if (GET_CODE (XEXP (x
, 0)) != REG
)
3552 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
3556 return CONSTANT_P (x
);
3560 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
3562 if (GET_CODE (x
) != LO_SUM
)
3564 if (GET_CODE (XEXP (x
, 0)) != REG
)
3566 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
3568 /* Restrict addressing for DI because of our SUBREG hackery. */
3569 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3570 || mode
== DDmode
|| mode
== TDmode
3575 if (TARGET_ELF
|| TARGET_MACHO
)
3577 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
3581 if (GET_MODE_NUNITS (mode
) != 1)
3583 if (GET_MODE_BITSIZE (mode
) > 64
3584 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
3585 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
3586 && (mode
== DFmode
|| mode
== DDmode
))))
3589 return CONSTANT_P (x
);
3596 /* Try machine-dependent ways of modifying an illegitimate address
3597 to be legitimate. If we find one, return the new, valid address.
3598 This is used from only one place: `memory_address' in explow.c.
3600 OLDX is the address as it was before break_out_memory_refs was
3601 called. In some cases it is useful to look at this to decide what
3604 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
3606 It is always safe for this function to do nothing. It exists to
3607 recognize opportunities to optimize the output.
3609 On RS/6000, first check for the sum of a register with a constant
3610 integer that is out of range. If so, generate code to add the
3611 constant with the low-order 16 bits masked to the register and force
3612 this result into another register (this can be done with `cau').
3613 Then generate an address of REG+(CONST&0xffff), allowing for the
3614 possibility of bit 16 being a one.
3616 Then check for the sum of a register and something not constant, try to
3617 load the other things into a register and return the sum. */
3620 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3621 enum machine_mode mode
)
3623 if (GET_CODE (x
) == SYMBOL_REF
)
3625 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
3627 return rs6000_legitimize_tls_address (x
, model
);
3630 if (GET_CODE (x
) == PLUS
3631 && GET_CODE (XEXP (x
, 0)) == REG
3632 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3633 && (unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000) >= 0x10000
3634 && !(SPE_VECTOR_MODE (mode
)
3635 || ALTIVEC_VECTOR_MODE (mode
)
3636 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3637 || mode
== DImode
))))
3639 HOST_WIDE_INT high_int
, low_int
;
3641 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
3642 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
3643 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
3644 GEN_INT (high_int
)), 0);
3645 return gen_rtx_PLUS (Pmode
, sum
, GEN_INT (low_int
));
3647 else if (GET_CODE (x
) == PLUS
3648 && GET_CODE (XEXP (x
, 0)) == REG
3649 && GET_CODE (XEXP (x
, 1)) != CONST_INT
3650 && GET_MODE_NUNITS (mode
) == 1
3651 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
3653 || ((mode
!= DImode
&& mode
!= DFmode
&& mode
!= DDmode
)
3654 || TARGET_E500_DOUBLE
))
3655 && (TARGET_POWERPC64
|| mode
!= DImode
)
3660 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
3661 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
3663 else if (ALTIVEC_VECTOR_MODE (mode
))
3667 /* Make sure both operands are registers. */
3668 if (GET_CODE (x
) == PLUS
)
3669 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, XEXP (x
, 0)),
3670 force_reg (Pmode
, XEXP (x
, 1)));
3672 reg
= force_reg (Pmode
, x
);
3675 else if (SPE_VECTOR_MODE (mode
)
3676 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3677 || mode
== DDmode
|| mode
== TDmode
3678 || mode
== DImode
)))
3682 /* We accept [reg + reg] and [reg + OFFSET]. */
3684 if (GET_CODE (x
) == PLUS
)
3686 rtx op1
= XEXP (x
, 0);
3687 rtx op2
= XEXP (x
, 1);
3690 op1
= force_reg (Pmode
, op1
);
3692 if (GET_CODE (op2
) != REG
3693 && (GET_CODE (op2
) != CONST_INT
3694 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))
3695 || (GET_MODE_SIZE (mode
) > 8
3696 && !SPE_CONST_OFFSET_OK (INTVAL (op2
) + 8))))
3697 op2
= force_reg (Pmode
, op2
);
3699 /* We can't always do [reg + reg] for these, because [reg +
3700 reg + offset] is not a legitimate addressing mode. */
3701 y
= gen_rtx_PLUS (Pmode
, op1
, op2
);
3703 if (GET_MODE_SIZE (mode
) > 8 && REG_P (op2
))
3704 return force_reg (Pmode
, y
);
3709 return force_reg (Pmode
, x
);
3715 && GET_CODE (x
) != CONST_INT
3716 && GET_CODE (x
) != CONST_DOUBLE
3718 && GET_MODE_NUNITS (mode
) == 1
3719 && (GET_MODE_BITSIZE (mode
) <= 32
3720 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
3721 && (mode
== DFmode
|| mode
== DDmode
))))
3723 rtx reg
= gen_reg_rtx (Pmode
);
3724 emit_insn (gen_elf_high (reg
, x
));
3725 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
3727 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
3730 && ! MACHO_DYNAMIC_NO_PIC_P
3732 && GET_CODE (x
) != CONST_INT
3733 && GET_CODE (x
) != CONST_DOUBLE
3735 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
3736 || (mode
!= DFmode
&& mode
!= DDmode
))
3740 rtx reg
= gen_reg_rtx (Pmode
);
3741 emit_insn (gen_macho_high (reg
, x
));
3742 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
3745 && constant_pool_expr_p (x
)
3746 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
3748 return create_TOC_reference (x
);
3754 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
3755 We need to emit DTP-relative relocations. */
3758 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
3763 fputs ("\t.long\t", file
);
3766 fputs (DOUBLE_INT_ASM_OP
, file
);
3771 output_addr_const (file
, x
);
3772 fputs ("@dtprel+0x8000", file
);
3775 /* Construct the SYMBOL_REF for the tls_get_addr function. */
3777 static GTY(()) rtx rs6000_tls_symbol
;
3779 rs6000_tls_get_addr (void)
3781 if (!rs6000_tls_symbol
)
3782 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
3784 return rs6000_tls_symbol
;
3787 /* Construct the SYMBOL_REF for TLS GOT references. */
3789 static GTY(()) rtx rs6000_got_symbol
;
3791 rs6000_got_sym (void)
3793 if (!rs6000_got_symbol
)
3795 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
3796 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
3797 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
3800 return rs6000_got_symbol
;
3803 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3804 this (thread-local) address. */
3807 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
3811 dest
= gen_reg_rtx (Pmode
);
3812 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
3818 tlsreg
= gen_rtx_REG (Pmode
, 13);
3819 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
3823 tlsreg
= gen_rtx_REG (Pmode
, 2);
3824 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
3828 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
3832 tmp
= gen_reg_rtx (Pmode
);
3835 tlsreg
= gen_rtx_REG (Pmode
, 13);
3836 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
3840 tlsreg
= gen_rtx_REG (Pmode
, 2);
3841 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
3845 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
3847 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
3852 rtx r3
, got
, tga
, tmp1
, tmp2
, eqv
;
3854 /* We currently use relocations like @got@tlsgd for tls, which
3855 means the linker will handle allocation of tls entries, placing
3856 them in the .got section. So use a pointer to the .got section,
3857 not one to secondary TOC sections used by 64-bit -mminimal-toc,
3858 or to secondary GOT sections used by 32-bit -fPIC. */
3860 got
= gen_rtx_REG (Pmode
, 2);
3864 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
3867 rtx gsym
= rs6000_got_sym ();
3868 got
= gen_reg_rtx (Pmode
);
3870 rs6000_emit_move (got
, gsym
, Pmode
);
3876 tmp1
= gen_reg_rtx (Pmode
);
3877 tmp2
= gen_reg_rtx (Pmode
);
3878 tmp3
= gen_reg_rtx (Pmode
);
3879 mem
= gen_const_mem (Pmode
, tmp1
);
3881 first
= emit_insn (gen_load_toc_v4_PIC_1b (gsym
));
3882 emit_move_insn (tmp1
,
3883 gen_rtx_REG (Pmode
, LR_REGNO
));
3884 emit_move_insn (tmp2
, mem
);
3885 emit_insn (gen_addsi3 (tmp3
, tmp1
, tmp2
));
3886 last
= emit_move_insn (got
, tmp3
);
3887 set_unique_reg_note (last
, REG_EQUAL
, gsym
);
3888 maybe_encapsulate_block (first
, last
, gsym
);
3893 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
3895 r3
= gen_rtx_REG (Pmode
, 3);
3897 insn
= gen_tls_gd_64 (r3
, got
, addr
);
3899 insn
= gen_tls_gd_32 (r3
, got
, addr
);
3902 tga
= gen_rtx_MEM (Pmode
, rs6000_tls_get_addr ());
3903 insn
= gen_call_value (r3
, tga
, const0_rtx
, const0_rtx
);
3904 insn
= emit_call_insn (insn
);
3905 CONST_OR_PURE_CALL_P (insn
) = 1;
3906 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
3907 insn
= get_insns ();
3909 emit_libcall_block (insn
, dest
, r3
, addr
);
3911 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
3913 r3
= gen_rtx_REG (Pmode
, 3);
3915 insn
= gen_tls_ld_64 (r3
, got
);
3917 insn
= gen_tls_ld_32 (r3
, got
);
3920 tga
= gen_rtx_MEM (Pmode
, rs6000_tls_get_addr ());
3921 insn
= gen_call_value (r3
, tga
, const0_rtx
, const0_rtx
);
3922 insn
= emit_call_insn (insn
);
3923 CONST_OR_PURE_CALL_P (insn
) = 1;
3924 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
3925 insn
= get_insns ();
3927 tmp1
= gen_reg_rtx (Pmode
);
3928 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
),
3930 emit_libcall_block (insn
, tmp1
, r3
, eqv
);
3931 if (rs6000_tls_size
== 16)
3934 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
3936 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
3938 else if (rs6000_tls_size
== 32)
3940 tmp2
= gen_reg_rtx (Pmode
);
3942 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
3944 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
3947 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
3949 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
3953 tmp2
= gen_reg_rtx (Pmode
);
3955 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
3957 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
3959 insn
= gen_rtx_SET (Pmode
, dest
,
3960 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
3966 /* IE, or 64-bit offset LE. */
3967 tmp2
= gen_reg_rtx (Pmode
);
3969 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
3971 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
3974 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
3976 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
3984 /* Return 1 if X contains a thread-local symbol. */
3987 rs6000_tls_referenced_p (rtx x
)
3989 if (! TARGET_HAVE_TLS
)
3992 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
3995 /* Return 1 if *X is a thread-local symbol. This is the same as
3996 rs6000_tls_symbol_ref except for the type of the unused argument. */
3999 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
4001 return RS6000_SYMBOL_REF_TLS_P (*x
);
4004 /* The convention appears to be to define this wherever it is used.
4005 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
4006 is now used here. */
4007 #ifndef REG_MODE_OK_FOR_BASE_P
4008 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
4011 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
4012 replace the input X, or the original X if no replacement is called for.
4013 The output parameter *WIN is 1 if the calling macro should goto WIN,
4016 For RS/6000, we wish to handle large displacements off a base
4017 register by splitting the addend across an addiu/addis and the mem insn.
4018 This cuts number of extra insns needed from 3 to 1.
4020 On Darwin, we use this to generate code for floating point constants.
4021 A movsf_low is generated so we wind up with 2 instructions rather than 3.
4022 The Darwin code is inside #if TARGET_MACHO because only then is
4023 machopic_function_base_name() defined. */
4025 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
4026 int opnum
, int type
,
4027 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
4029 /* We must recognize output that we have already generated ourselves. */
4030 if (GET_CODE (x
) == PLUS
4031 && GET_CODE (XEXP (x
, 0)) == PLUS
4032 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
4033 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
4034 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
4036 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4037 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
4038 opnum
, (enum reload_type
)type
);
4044 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
4045 && GET_CODE (x
) == LO_SUM
4046 && GET_CODE (XEXP (x
, 0)) == PLUS
4047 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
4048 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
4049 && GET_CODE (XEXP (XEXP (XEXP (x
, 0), 1), 0)) == CONST
4050 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
4051 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == MINUS
4052 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 0)) == SYMBOL_REF
4053 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 1)) == SYMBOL_REF
)
4055 /* Result of previous invocation of this function on Darwin
4056 floating point constant. */
4057 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4058 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
4059 opnum
, (enum reload_type
)type
);
4065 /* Force ld/std non-word aligned offset into base register by wrapping
4067 if (GET_CODE (x
) == PLUS
4068 && GET_CODE (XEXP (x
, 0)) == REG
4069 && REGNO (XEXP (x
, 0)) < 32
4070 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
4071 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4072 && (INTVAL (XEXP (x
, 1)) & 3) != 0
4073 && !ALTIVEC_VECTOR_MODE (mode
)
4074 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
4075 && TARGET_POWERPC64
)
4077 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
4078 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4079 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
4080 opnum
, (enum reload_type
) type
);
4085 if (GET_CODE (x
) == PLUS
4086 && GET_CODE (XEXP (x
, 0)) == REG
4087 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
4088 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
4089 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4090 && !SPE_VECTOR_MODE (mode
)
4091 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
4092 || mode
== DDmode
|| mode
== TDmode
4094 && !ALTIVEC_VECTOR_MODE (mode
))
4096 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
4097 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
4099 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
4101 /* Check for 32-bit overflow. */
4102 if (high
+ low
!= val
)
4108 /* Reload the high part into a base reg; leave the low part
4109 in the mem directly. */
4111 x
= gen_rtx_PLUS (GET_MODE (x
),
4112 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
4116 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4117 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
4118 opnum
, (enum reload_type
)type
);
4123 if (GET_CODE (x
) == SYMBOL_REF
4124 && !ALTIVEC_VECTOR_MODE (mode
)
4125 && !SPE_VECTOR_MODE (mode
)
4127 && DEFAULT_ABI
== ABI_DARWIN
4128 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
4130 && DEFAULT_ABI
== ABI_V4
4133 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
4134 The same goes for DImode without 64-bit gprs and DFmode and DDmode
4138 && (mode
!= DImode
|| TARGET_POWERPC64
)
4139 && ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_POWERPC64
4140 || (TARGET_FPRS
&& TARGET_HARD_FLOAT
)))
4145 rtx offset
= gen_rtx_CONST (Pmode
,
4146 gen_rtx_MINUS (Pmode
, x
,
4147 machopic_function_base_sym ()));
4148 x
= gen_rtx_LO_SUM (GET_MODE (x
),
4149 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
4150 gen_rtx_HIGH (Pmode
, offset
)), offset
);
4154 x
= gen_rtx_LO_SUM (GET_MODE (x
),
4155 gen_rtx_HIGH (Pmode
, x
), x
);
4157 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4158 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
4159 opnum
, (enum reload_type
)type
);
4164 /* Reload an offset address wrapped by an AND that represents the
4165 masking of the lower bits. Strip the outer AND and let reload
4166 convert the offset address into an indirect address. */
4168 && ALTIVEC_VECTOR_MODE (mode
)
4169 && GET_CODE (x
) == AND
4170 && GET_CODE (XEXP (x
, 0)) == PLUS
4171 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
4172 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
4173 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4174 && INTVAL (XEXP (x
, 1)) == -16)
4182 && constant_pool_expr_p (x
)
4183 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
4185 x
= create_TOC_reference (x
);
4193 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
4194 that is a valid memory address for an instruction.
4195 The MODE argument is the machine mode for the MEM expression
4196 that wants to use this address.
4198 On the RS/6000, there are four valid address: a SYMBOL_REF that
4199 refers to a constant pool entry of an address (or the sum of it
4200 plus a constant), a short (16-bit signed) constant plus a register,
4201 the sum of two registers, or a register indirect, possibly with an
4202 auto-increment. For DFmode, DDmode and DImode with a constant plus
4203 register, we must ensure that both words are addressable or PowerPC64
4204 with offset word aligned.
4206 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
4207 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
4208 because adjacent memory cells are accessed by adding word-sized offsets
4209 during assembly output. */
4211 rs6000_legitimate_address (enum machine_mode mode
, rtx x
, int reg_ok_strict
)
4213 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
4215 && ALTIVEC_VECTOR_MODE (mode
)
4216 && GET_CODE (x
) == AND
4217 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4218 && INTVAL (XEXP (x
, 1)) == -16)
4221 if (RS6000_SYMBOL_REF_TLS_P (x
))
4223 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
4225 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
4226 && !ALTIVEC_VECTOR_MODE (mode
)
4227 && !SPE_VECTOR_MODE (mode
)
4230 /* Restrict addressing for DI because of our SUBREG hackery. */
4231 && !(TARGET_E500_DOUBLE
4232 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
4234 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
4236 if (legitimate_small_data_p (mode
, x
))
4238 if (legitimate_constant_pool_address_p (x
))
4240 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
4242 && GET_CODE (x
) == PLUS
4243 && GET_CODE (XEXP (x
, 0)) == REG
4244 && (XEXP (x
, 0) == virtual_stack_vars_rtx
4245 || XEXP (x
, 0) == arg_pointer_rtx
)
4246 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
4248 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
4253 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
4255 || ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_E500_DOUBLE
))
4256 && (TARGET_POWERPC64
|| mode
!= DImode
)
4257 && legitimate_indexed_address_p (x
, reg_ok_strict
))
4259 if (GET_CODE (x
) == PRE_MODIFY
4263 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
4265 || ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_E500_DOUBLE
))
4266 && (TARGET_POWERPC64
|| mode
!= DImode
)
4267 && !ALTIVEC_VECTOR_MODE (mode
)
4268 && !SPE_VECTOR_MODE (mode
)
4269 /* Restrict addressing for DI because of our SUBREG hackery. */
4270 && !(TARGET_E500_DOUBLE
4271 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
4273 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
)
4274 && (rs6000_legitimate_offset_address_p (mode
, XEXP (x
, 1), reg_ok_strict
)
4275 || legitimate_indexed_address_p (XEXP (x
, 1), reg_ok_strict
))
4276 && rtx_equal_p (XEXP (XEXP (x
, 1), 0), XEXP (x
, 0)))
4278 if (legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
4283 /* Go to LABEL if ADDR (a legitimate address expression)
4284 has an effect that depends on the machine mode it is used for.
4286 On the RS/6000 this is true of all integral offsets (since AltiVec
4287 modes don't allow them) or is a pre-increment or decrement.
4289 ??? Except that due to conceptual problems in offsettable_address_p
4290 we can't really report the problems of integral offsets. So leave
4291 this assuming that the adjustable offset must be valid for the
4292 sub-words of a TFmode operand, which is what we had before. */
4295 rs6000_mode_dependent_address (rtx addr
)
4297 switch (GET_CODE (addr
))
4300 if (GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
4302 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
4303 return val
+ 12 + 0x8000 >= 0x10000;
4313 return TARGET_UPDATE
;
4322 /* More elaborate version of recog's offsettable_memref_p predicate
4323 that works around the ??? note of rs6000_mode_dependent_address.
4324 In particular it accepts
4326 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
4328 in 32-bit mode, that the recog predicate rejects. */
4331 rs6000_offsettable_memref_p (rtx op
)
4336 /* First mimic offsettable_memref_p. */
4337 if (offsettable_address_p (1, GET_MODE (op
), XEXP (op
, 0)))
4340 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
4341 the latter predicate knows nothing about the mode of the memory
4342 reference and, therefore, assumes that it is the largest supported
4343 mode (TFmode). As a consequence, legitimate offsettable memory
4344 references are rejected. rs6000_legitimate_offset_address_p contains
4345 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
4346 return rs6000_legitimate_offset_address_p (GET_MODE (op
), XEXP (op
, 0), 1);
4349 /* Return number of consecutive hard regs needed starting at reg REGNO
4350 to hold something of mode MODE.
4351 This is ordinarily the length in words of a value of mode MODE
4352 but can be less for certain modes in special long registers.
4354 For the SPE, GPRs are 64 bits but only 32 bits are visible in
4355 scalar instructions. The upper 32 bits are only available to the
4358 POWER and PowerPC GPRs hold 32 bits worth;
4359 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
4362 rs6000_hard_regno_nregs (int regno
, enum machine_mode mode
)
4364 if (FP_REGNO_P (regno
))
4365 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
4367 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
4368 return (GET_MODE_SIZE (mode
) + UNITS_PER_SPE_WORD
- 1) / UNITS_PER_SPE_WORD
;
4370 if (ALTIVEC_REGNO_P (regno
))
4372 (GET_MODE_SIZE (mode
) + UNITS_PER_ALTIVEC_WORD
- 1) / UNITS_PER_ALTIVEC_WORD
;
4374 /* The value returned for SCmode in the E500 double case is 2 for
4375 ABI compatibility; storing an SCmode value in a single register
4376 would require function_arg and rs6000_spe_function_arg to handle
4377 SCmode so as to pass the value correctly in a pair of
4379 if (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
) && mode
!= SCmode
)
4380 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
4382 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
4385 /* Change register usage conditional on target flags. */
4387 rs6000_conditional_register_usage (void)
4391 /* Set MQ register fixed (already call_used) if not POWER
4392 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
4397 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
4399 fixed_regs
[13] = call_used_regs
[13]
4400 = call_really_used_regs
[13] = 1;
4402 /* Conditionally disable FPRs. */
4403 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
4404 for (i
= 32; i
< 64; i
++)
4405 fixed_regs
[i
] = call_used_regs
[i
]
4406 = call_really_used_regs
[i
] = 1;
4408 /* The TOC register is not killed across calls in a way that is
4409 visible to the compiler. */
4410 if (DEFAULT_ABI
== ABI_AIX
)
4411 call_really_used_regs
[2] = 0;
4413 if (DEFAULT_ABI
== ABI_V4
4414 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
4416 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4418 if (DEFAULT_ABI
== ABI_V4
4419 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
4421 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4422 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4423 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4425 if (DEFAULT_ABI
== ABI_DARWIN
4426 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
4427 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4428 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4429 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4431 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
4432 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4433 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4437 global_regs
[SPEFSCR_REGNO
] = 1;
4438 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
4439 registers in prologues and epilogues. We no longer use r14
4440 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
4441 pool for link-compatibility with older versions of GCC. Once
4442 "old" code has died out, we can return r14 to the allocation
4445 = call_used_regs
[14]
4446 = call_really_used_regs
[14] = 1;
4449 if (!TARGET_ALTIVEC
)
4451 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
4452 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4453 call_really_used_regs
[VRSAVE_REGNO
] = 1;
4457 global_regs
[VSCR_REGNO
] = 1;
4459 if (TARGET_ALTIVEC_ABI
)
4461 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
4462 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4464 /* AIX reserves VR20:31 in non-extended ABI mode. */
4466 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
< FIRST_ALTIVEC_REGNO
+ 32; ++i
)
4467 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4471 /* Try to output insns to set TARGET equal to the constant C if it can
4472 be done in less than N insns. Do all computations in MODE.
4473 Returns the place where the output has been placed if it can be
4474 done and the insns have been emitted. If it would take more than N
4475 insns, zero is returned and no insns and emitted. */
4478 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
4479 rtx source
, int n ATTRIBUTE_UNUSED
)
4481 rtx result
, insn
, set
;
4482 HOST_WIDE_INT c0
, c1
;
4489 dest
= gen_reg_rtx (mode
);
4490 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
4494 result
= !can_create_pseudo_p () ? dest
: gen_reg_rtx (SImode
);
4496 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (result
),
4497 GEN_INT (INTVAL (source
)
4498 & (~ (HOST_WIDE_INT
) 0xffff))));
4499 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
4500 gen_rtx_IOR (SImode
, copy_rtx (result
),
4501 GEN_INT (INTVAL (source
) & 0xffff))));
4506 switch (GET_CODE (source
))
4509 c0
= INTVAL (source
);
4514 #if HOST_BITS_PER_WIDE_INT >= 64
4515 c0
= CONST_DOUBLE_LOW (source
);
4518 c0
= CONST_DOUBLE_LOW (source
);
4519 c1
= CONST_DOUBLE_HIGH (source
);
4527 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
4534 insn
= get_last_insn ();
4535 set
= single_set (insn
);
4536 if (! CONSTANT_P (SET_SRC (set
)))
4537 set_unique_reg_note (insn
, REG_EQUAL
, source
);
4542 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
4543 fall back to a straight forward decomposition. We do this to avoid
4544 exponential run times encountered when looking for longer sequences
4545 with rs6000_emit_set_const. */
4547 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
4549 if (!TARGET_POWERPC64
)
4551 rtx operand1
, operand2
;
4553 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
4555 operand2
= operand_subword_force (copy_rtx (dest
), WORDS_BIG_ENDIAN
!= 0,
4557 emit_move_insn (operand1
, GEN_INT (c1
));
4558 emit_move_insn (operand2
, GEN_INT (c2
));
4562 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
4565 ud2
= (c1
& 0xffff0000) >> 16;
4566 #if HOST_BITS_PER_WIDE_INT >= 64
4570 ud4
= (c2
& 0xffff0000) >> 16;
4572 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
4573 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
4576 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
4578 emit_move_insn (dest
, GEN_INT (ud1
));
4581 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
4582 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
4585 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
4588 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
4590 emit_move_insn (copy_rtx (dest
),
4591 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4594 else if ((ud4
== 0xffff && (ud3
& 0x8000))
4595 || (ud4
== 0 && ! (ud3
& 0x8000)))
4598 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
4601 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
4604 emit_move_insn (copy_rtx (dest
),
4605 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4607 emit_move_insn (copy_rtx (dest
),
4608 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
4611 emit_move_insn (copy_rtx (dest
),
4612 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4618 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
4621 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
4624 emit_move_insn (copy_rtx (dest
),
4625 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4628 emit_move_insn (copy_rtx (dest
),
4629 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
4632 emit_move_insn (copy_rtx (dest
),
4633 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4634 GEN_INT (ud2
<< 16)));
4636 emit_move_insn (copy_rtx (dest
),
4637 gen_rtx_IOR (DImode
, copy_rtx (dest
), GEN_INT (ud1
)));
4643 /* Helper for the following. Get rid of [r+r] memory refs
4644 in cases where it won't work (TImode, TFmode, TDmode). */
4647 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
4649 if (GET_CODE (operands
[0]) == MEM
4650 && GET_CODE (XEXP (operands
[0], 0)) != REG
4651 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0))
4652 && ! reload_in_progress
)
4654 = replace_equiv_address (operands
[0],
4655 copy_addr_to_reg (XEXP (operands
[0], 0)));
4657 if (GET_CODE (operands
[1]) == MEM
4658 && GET_CODE (XEXP (operands
[1], 0)) != REG
4659 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0))
4660 && ! reload_in_progress
)
4662 = replace_equiv_address (operands
[1],
4663 copy_addr_to_reg (XEXP (operands
[1], 0)));
4666 /* Emit a move from SOURCE to DEST in mode MODE. */
4668 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
4672 operands
[1] = source
;
4674 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
4675 if (GET_CODE (operands
[1]) == CONST_DOUBLE
4676 && ! FLOAT_MODE_P (mode
)
4677 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
4679 /* FIXME. This should never happen. */
4680 /* Since it seems that it does, do the safe thing and convert
4682 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
4684 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
4685 || FLOAT_MODE_P (mode
)
4686 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
4687 || CONST_DOUBLE_LOW (operands
[1]) < 0)
4688 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
4689 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
4691 /* Check if GCC is setting up a block move that will end up using FP
4692 registers as temporaries. We must make sure this is acceptable. */
4693 if (GET_CODE (operands
[0]) == MEM
4694 && GET_CODE (operands
[1]) == MEM
4696 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
4697 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
4698 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
4699 ? 32 : MEM_ALIGN (operands
[0])))
4700 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
4702 : MEM_ALIGN (operands
[1]))))
4703 && ! MEM_VOLATILE_P (operands
[0])
4704 && ! MEM_VOLATILE_P (operands
[1]))
4706 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
4707 adjust_address (operands
[1], SImode
, 0));
4708 emit_move_insn (adjust_address (copy_rtx (operands
[0]), SImode
, 4),
4709 adjust_address (copy_rtx (operands
[1]), SImode
, 4));
4713 if (can_create_pseudo_p () && GET_CODE (operands
[0]) == MEM
4714 && !gpc_reg_operand (operands
[1], mode
))
4715 operands
[1] = force_reg (mode
, operands
[1]);
4717 if (mode
== SFmode
&& ! TARGET_POWERPC
4718 && TARGET_HARD_FLOAT
&& TARGET_FPRS
4719 && GET_CODE (operands
[0]) == MEM
)
4723 if (reload_in_progress
|| reload_completed
)
4724 regnum
= true_regnum (operands
[1]);
4725 else if (GET_CODE (operands
[1]) == REG
)
4726 regnum
= REGNO (operands
[1]);
4730 /* If operands[1] is a register, on POWER it may have
4731 double-precision data in it, so truncate it to single
4733 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
4736 newreg
= (!can_create_pseudo_p () ? copy_rtx (operands
[1])
4737 : gen_reg_rtx (mode
));
4738 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
4739 operands
[1] = newreg
;
4743 /* Recognize the case where operand[1] is a reference to thread-local
4744 data and load its address to a register. */
4745 if (rs6000_tls_referenced_p (operands
[1]))
4747 enum tls_model model
;
4748 rtx tmp
= operands
[1];
4751 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
4753 addend
= XEXP (XEXP (tmp
, 0), 1);
4754 tmp
= XEXP (XEXP (tmp
, 0), 0);
4757 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
4758 model
= SYMBOL_REF_TLS_MODEL (tmp
);
4759 gcc_assert (model
!= 0);
4761 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
4764 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
4765 tmp
= force_operand (tmp
, operands
[0]);
4770 /* Handle the case where reload calls us with an invalid address. */
4771 if (reload_in_progress
&& mode
== Pmode
4772 && (! general_operand (operands
[1], mode
)
4773 || ! nonimmediate_operand (operands
[0], mode
)))
4776 /* 128-bit constant floating-point values on Darwin should really be
4777 loaded as two parts. */
4778 if (!TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
4779 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
4781 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
4782 know how to get a DFmode SUBREG of a TFmode. */
4783 enum machine_mode imode
= (TARGET_E500_DOUBLE
? DFmode
: DImode
);
4784 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
, 0),
4785 simplify_gen_subreg (imode
, operands
[1], mode
, 0),
4787 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
,
4788 GET_MODE_SIZE (imode
)),
4789 simplify_gen_subreg (imode
, operands
[1], mode
,
4790 GET_MODE_SIZE (imode
)),
4795 if (reload_in_progress
&& cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
4796 cfun
->machine
->sdmode_stack_slot
=
4797 eliminate_regs (cfun
->machine
->sdmode_stack_slot
, VOIDmode
, NULL_RTX
);
4799 if (reload_in_progress
4801 && MEM_P (operands
[0])
4802 && rtx_equal_p (operands
[0], cfun
->machine
->sdmode_stack_slot
)
4803 && REG_P (operands
[1]))
4805 if (FP_REGNO_P (REGNO (operands
[1])))
4807 rtx mem
= adjust_address_nv (operands
[0], DDmode
, 0);
4808 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
4809 emit_insn (gen_movsd_store (mem
, operands
[1]));
4811 else if (INT_REGNO_P (REGNO (operands
[1])))
4813 rtx mem
= adjust_address_nv (operands
[0], mode
, 4);
4814 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
4815 emit_insn (gen_movsd_hardfloat (mem
, operands
[1]));
4821 if (reload_in_progress
4823 && REG_P (operands
[0])
4824 && MEM_P (operands
[1])
4825 && rtx_equal_p (operands
[1], cfun
->machine
->sdmode_stack_slot
))
4827 if (FP_REGNO_P (REGNO (operands
[0])))
4829 rtx mem
= adjust_address_nv (operands
[1], DDmode
, 0);
4830 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
4831 emit_insn (gen_movsd_load (operands
[0], mem
));
4833 else if (INT_REGNO_P (REGNO (operands
[0])))
4835 rtx mem
= adjust_address_nv (operands
[1], mode
, 4);
4836 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
4837 emit_insn (gen_movsd_hardfloat (operands
[0], mem
));
4844 /* FIXME: In the long term, this switch statement should go away
4845 and be replaced by a sequence of tests based on things like
4851 if (CONSTANT_P (operands
[1])
4852 && GET_CODE (operands
[1]) != CONST_INT
)
4853 operands
[1] = force_const_mem (mode
, operands
[1]);
4858 rs6000_eliminate_indexed_memrefs (operands
);
4865 if (CONSTANT_P (operands
[1])
4866 && ! easy_fp_constant (operands
[1], mode
))
4867 operands
[1] = force_const_mem (mode
, operands
[1]);
4878 if (CONSTANT_P (operands
[1])
4879 && !easy_vector_constant (operands
[1], mode
))
4880 operands
[1] = force_const_mem (mode
, operands
[1]);
4885 /* Use default pattern for address of ELF small data */
4888 && DEFAULT_ABI
== ABI_V4
4889 && (GET_CODE (operands
[1]) == SYMBOL_REF
4890 || GET_CODE (operands
[1]) == CONST
)
4891 && small_data_operand (operands
[1], mode
))
4893 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
4897 if (DEFAULT_ABI
== ABI_V4
4898 && mode
== Pmode
&& mode
== SImode
4899 && flag_pic
== 1 && got_operand (operands
[1], mode
))
4901 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
4905 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
4909 && CONSTANT_P (operands
[1])
4910 && GET_CODE (operands
[1]) != HIGH
4911 && GET_CODE (operands
[1]) != CONST_INT
)
4913 rtx target
= (!can_create_pseudo_p ()
4915 : gen_reg_rtx (mode
));
4917 /* If this is a function address on -mcall-aixdesc,
4918 convert it to the address of the descriptor. */
4919 if (DEFAULT_ABI
== ABI_AIX
4920 && GET_CODE (operands
[1]) == SYMBOL_REF
4921 && XSTR (operands
[1], 0)[0] == '.')
4923 const char *name
= XSTR (operands
[1], 0);
4925 while (*name
== '.')
4927 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
4928 CONSTANT_POOL_ADDRESS_P (new_ref
)
4929 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
4930 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
4931 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
4932 SYMBOL_REF_DATA (new_ref
) = SYMBOL_REF_DATA (operands
[1]);
4933 operands
[1] = new_ref
;
4936 if (DEFAULT_ABI
== ABI_DARWIN
)
4939 if (MACHO_DYNAMIC_NO_PIC_P
)
4941 /* Take care of any required data indirection. */
4942 operands
[1] = rs6000_machopic_legitimize_pic_address (
4943 operands
[1], mode
, operands
[0]);
4944 if (operands
[0] != operands
[1])
4945 emit_insn (gen_rtx_SET (VOIDmode
,
4946 operands
[0], operands
[1]));
4950 emit_insn (gen_macho_high (target
, operands
[1]));
4951 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
4955 emit_insn (gen_elf_high (target
, operands
[1]));
4956 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
4960 /* If this is a SYMBOL_REF that refers to a constant pool entry,
4961 and we have put it in the TOC, we just need to make a TOC-relative
4964 && GET_CODE (operands
[1]) == SYMBOL_REF
4965 && constant_pool_expr_p (operands
[1])
4966 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
4967 get_pool_mode (operands
[1])))
4969 operands
[1] = create_TOC_reference (operands
[1]);
4971 else if (mode
== Pmode
4972 && CONSTANT_P (operands
[1])
4973 && ((GET_CODE (operands
[1]) != CONST_INT
4974 && ! easy_fp_constant (operands
[1], mode
))
4975 || (GET_CODE (operands
[1]) == CONST_INT
4976 && num_insns_constant (operands
[1], mode
) > 2)
4977 || (GET_CODE (operands
[0]) == REG
4978 && FP_REGNO_P (REGNO (operands
[0]))))
4979 && GET_CODE (operands
[1]) != HIGH
4980 && ! legitimate_constant_pool_address_p (operands
[1])
4981 && ! toc_relative_expr_p (operands
[1]))
4983 /* Emit a USE operation so that the constant isn't deleted if
4984 expensive optimizations are turned on because nobody
4985 references it. This should only be done for operands that
4986 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
4987 This should not be done for operands that contain LABEL_REFs.
4988 For now, we just handle the obvious case. */
4989 if (GET_CODE (operands
[1]) != LABEL_REF
)
4990 emit_insn (gen_rtx_USE (VOIDmode
, operands
[1]));
4993 /* Darwin uses a special PIC legitimizer. */
4994 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
4997 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
4999 if (operands
[0] != operands
[1])
5000 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
5005 /* If we are to limit the number of things we put in the TOC and
5006 this is a symbol plus a constant we can add in one insn,
5007 just put the symbol in the TOC and add the constant. Don't do
5008 this if reload is in progress. */
5009 if (GET_CODE (operands
[1]) == CONST
5010 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
5011 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
5012 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
5013 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
5014 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
5015 && ! side_effects_p (operands
[0]))
5018 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
5019 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
5021 sym
= force_reg (mode
, sym
);
5023 emit_insn (gen_addsi3 (operands
[0], sym
, other
));
5025 emit_insn (gen_adddi3 (operands
[0], sym
, other
));
5029 operands
[1] = force_const_mem (mode
, operands
[1]);
5032 && constant_pool_expr_p (XEXP (operands
[1], 0))
5033 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
5034 get_pool_constant (XEXP (operands
[1], 0)),
5035 get_pool_mode (XEXP (operands
[1], 0))))
5038 = gen_const_mem (mode
,
5039 create_TOC_reference (XEXP (operands
[1], 0)));
5040 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
5046 rs6000_eliminate_indexed_memrefs (operands
);
5050 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
5052 gen_rtx_SET (VOIDmode
,
5053 operands
[0], operands
[1]),
5054 gen_rtx_CLOBBER (VOIDmode
,
5055 gen_rtx_SCRATCH (SImode
)))));
5064 /* Above, we may have called force_const_mem which may have returned
5065 an invalid address. If we can, fix this up; otherwise, reload will
5066 have to deal with it. */
5067 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
5068 operands
[1] = validize_mem (operands
[1]);
5071 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
5074 /* Nonzero if we can use a floating-point register to pass this arg. */
5075 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
5076 (SCALAR_FLOAT_MODE_P (MODE) \
5077 && (CUM)->fregno <= FP_ARG_MAX_REG \
5078 && TARGET_HARD_FLOAT && TARGET_FPRS)
5080 /* Nonzero if we can use an AltiVec register to pass this arg. */
5081 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
5082 (ALTIVEC_VECTOR_MODE (MODE) \
5083 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
5084 && TARGET_ALTIVEC_ABI \
5087 /* Return a nonzero value to say to return the function value in
5088 memory, just as large structures are always returned. TYPE will be
5089 the data type of the value, and FNTYPE will be the type of the
5090 function doing the returning, or @code{NULL} for libcalls.
5092 The AIX ABI for the RS/6000 specifies that all structures are
5093 returned in memory. The Darwin ABI does the same. The SVR4 ABI
5094 specifies that structures <= 8 bytes are returned in r3/r4, but a
5095 draft put them in memory, and GCC used to implement the draft
5096 instead of the final standard. Therefore, aix_struct_return
5097 controls this instead of DEFAULT_ABI; V.4 targets needing backward
5098 compatibility can change DRAFT_V4_STRUCT_RET to override the
5099 default, and -m switches get the final word. See
5100 rs6000_override_options for more details.
5102 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
5103 long double support is enabled. These values are returned in memory.
5105 int_size_in_bytes returns -1 for variable size objects, which go in
5106 memory always. The cast to unsigned makes -1 > 8. */
5109 rs6000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
5111 /* In the darwin64 abi, try to use registers for larger structs
5113 if (rs6000_darwin64_abi
5114 && TREE_CODE (type
) == RECORD_TYPE
5115 && int_size_in_bytes (type
) > 0)
5117 CUMULATIVE_ARGS valcum
;
5121 valcum
.fregno
= FP_ARG_MIN_REG
;
5122 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
5123 /* Do a trial code generation as if this were going to be passed
5124 as an argument; if any part goes in memory, we return NULL. */
5125 valret
= rs6000_darwin64_record_arg (&valcum
, type
, 1, true);
5128 /* Otherwise fall through to more conventional ABI rules. */
5131 if (AGGREGATE_TYPE_P (type
)
5132 && (aix_struct_return
5133 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
5136 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5137 modes only exist for GCC vector types if -maltivec. */
5138 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
5139 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
5142 /* Return synthetic vectors in memory. */
5143 if (TREE_CODE (type
) == VECTOR_TYPE
5144 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
5146 static bool warned_for_return_big_vectors
= false;
5147 if (!warned_for_return_big_vectors
)
5149 warning (0, "GCC vector returned by reference: "
5150 "non-standard ABI extension with no compatibility guarantee");
5151 warned_for_return_big_vectors
= true;
5156 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& TYPE_MODE (type
) == TFmode
)
5162 /* Initialize a variable CUM of type CUMULATIVE_ARGS
5163 for a call to a function whose data type is FNTYPE.
5164 For a library call, FNTYPE is 0.
5166 For incoming args we set the number of arguments in the prototype large
5167 so we never return a PARALLEL. */
5170 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
5171 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
5172 int libcall
, int n_named_args
)
5174 static CUMULATIVE_ARGS zero_cumulative
;
5176 *cum
= zero_cumulative
;
5178 cum
->fregno
= FP_ARG_MIN_REG
;
5179 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
5180 cum
->prototype
= (fntype
&& TYPE_ARG_TYPES (fntype
));
5181 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
5182 ? CALL_LIBCALL
: CALL_NORMAL
);
5183 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
5184 cum
->stdarg
= fntype
5185 && (TYPE_ARG_TYPES (fntype
) != 0
5186 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
5187 != void_type_node
));
5189 cum
->nargs_prototype
= 0;
5190 if (incoming
|| cum
->prototype
)
5191 cum
->nargs_prototype
= n_named_args
;
5193 /* Check for a longcall attribute. */
5194 if ((!fntype
&& rs6000_default_long_calls
)
5196 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
5197 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
5198 cum
->call_cookie
|= CALL_LONG
;
5200 if (TARGET_DEBUG_ARG
)
5202 fprintf (stderr
, "\ninit_cumulative_args:");
5205 tree ret_type
= TREE_TYPE (fntype
);
5206 fprintf (stderr
, " ret code = %s,",
5207 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
5210 if (cum
->call_cookie
& CALL_LONG
)
5211 fprintf (stderr
, " longcall,");
5213 fprintf (stderr
, " proto = %d, nargs = %d\n",
5214 cum
->prototype
, cum
->nargs_prototype
);
5219 && TARGET_ALTIVEC_ABI
5220 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
5222 error ("cannot return value in vector register because"
5223 " altivec instructions are disabled, use -maltivec"
5228 /* Return true if TYPE must be passed on the stack and not in registers. */
5231 rs6000_must_pass_in_stack (enum machine_mode mode
, const_tree type
)
5233 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
5234 return must_pass_in_stack_var_size (mode
, type
);
5236 return must_pass_in_stack_var_size_or_pad (mode
, type
);
5239 /* If defined, a C expression which determines whether, and in which
5240 direction, to pad out an argument with extra space. The value
5241 should be of type `enum direction': either `upward' to pad above
5242 the argument, `downward' to pad below, or `none' to inhibit
5245 For the AIX ABI structs are always stored left shifted in their
5249 function_arg_padding (enum machine_mode mode
, const_tree type
)
5251 #ifndef AGGREGATE_PADDING_FIXED
5252 #define AGGREGATE_PADDING_FIXED 0
5254 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
5255 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
5258 if (!AGGREGATE_PADDING_FIXED
)
5260 /* GCC used to pass structures of the same size as integer types as
5261 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
5262 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
5263 passed padded downward, except that -mstrict-align further
5264 muddied the water in that multi-component structures of 2 and 4
5265 bytes in size were passed padded upward.
5267 The following arranges for best compatibility with previous
5268 versions of gcc, but removes the -mstrict-align dependency. */
5269 if (BYTES_BIG_ENDIAN
)
5271 HOST_WIDE_INT size
= 0;
5273 if (mode
== BLKmode
)
5275 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
5276 size
= int_size_in_bytes (type
);
5279 size
= GET_MODE_SIZE (mode
);
5281 if (size
== 1 || size
== 2 || size
== 4)
5287 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
5289 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
5293 /* Fall back to the default. */
5294 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
5297 /* If defined, a C expression that gives the alignment boundary, in bits,
5298 of an argument with the specified mode and type. If it is not defined,
5299 PARM_BOUNDARY is used for all arguments.
5301 V.4 wants long longs and doubles to be double word aligned. Just
5302 testing the mode size is a boneheaded way to do this as it means
5303 that other types such as complex int are also double word aligned.
5304 However, we're stuck with this because changing the ABI might break
5305 existing library interfaces.
5307 Doubleword align SPE vectors.
5308 Quadword align Altivec vectors.
5309 Quadword align large synthetic vector types. */
5312 function_arg_boundary (enum machine_mode mode
, tree type
)
5314 if (DEFAULT_ABI
== ABI_V4
5315 && (GET_MODE_SIZE (mode
) == 8
5316 || (TARGET_HARD_FLOAT
5318 && (mode
== TFmode
|| mode
== TDmode
))))
5320 else if (SPE_VECTOR_MODE (mode
)
5321 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5322 && int_size_in_bytes (type
) >= 8
5323 && int_size_in_bytes (type
) < 16))
5325 else if (ALTIVEC_VECTOR_MODE (mode
)
5326 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5327 && int_size_in_bytes (type
) >= 16))
5329 else if (rs6000_darwin64_abi
&& mode
== BLKmode
5330 && type
&& TYPE_ALIGN (type
) > 64)
5333 return PARM_BOUNDARY
;
5336 /* For a function parm of MODE and TYPE, return the starting word in
5337 the parameter area. NWORDS of the parameter area are already used. */
5340 rs6000_parm_start (enum machine_mode mode
, tree type
, unsigned int nwords
)
5343 unsigned int parm_offset
;
5345 align
= function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
5346 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
5347 return nwords
+ (-(parm_offset
+ nwords
) & align
);
5350 /* Compute the size (in words) of a function argument. */
5352 static unsigned long
5353 rs6000_arg_size (enum machine_mode mode
, tree type
)
5357 if (mode
!= BLKmode
)
5358 size
= GET_MODE_SIZE (mode
);
5360 size
= int_size_in_bytes (type
);
5363 return (size
+ 3) >> 2;
5365 return (size
+ 7) >> 3;
5368 /* Use this to flush pending int fields. */
5371 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
5372 HOST_WIDE_INT bitpos
)
5374 unsigned int startbit
, endbit
;
5375 int intregs
, intoffset
;
5376 enum machine_mode mode
;
5378 if (cum
->intoffset
== -1)
5381 intoffset
= cum
->intoffset
;
5382 cum
->intoffset
= -1;
5384 if (intoffset
% BITS_PER_WORD
!= 0)
5386 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
5388 if (mode
== BLKmode
)
5390 /* We couldn't find an appropriate mode, which happens,
5391 e.g., in packed structs when there are 3 bytes to load.
5392 Back intoffset back to the beginning of the word in this
5394 intoffset
= intoffset
& -BITS_PER_WORD
;
5398 startbit
= intoffset
& -BITS_PER_WORD
;
5399 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
5400 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
5401 cum
->words
+= intregs
;
5404 /* The darwin64 ABI calls for us to recurse down through structs,
5405 looking for elements passed in registers. Unfortunately, we have
5406 to track int register count here also because of misalignments
5407 in powerpc alignment mode. */
5410 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
5412 HOST_WIDE_INT startbitpos
)
5416 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
5417 if (TREE_CODE (f
) == FIELD_DECL
)
5419 HOST_WIDE_INT bitpos
= startbitpos
;
5420 tree ftype
= TREE_TYPE (f
);
5421 enum machine_mode mode
;
5422 if (ftype
== error_mark_node
)
5424 mode
= TYPE_MODE (ftype
);
5426 if (DECL_SIZE (f
) != 0
5427 && host_integerp (bit_position (f
), 1))
5428 bitpos
+= int_bit_position (f
);
5430 /* ??? FIXME: else assume zero offset. */
5432 if (TREE_CODE (ftype
) == RECORD_TYPE
)
5433 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
5434 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
5436 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
5437 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5438 cum
->words
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5440 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
5442 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
5446 else if (cum
->intoffset
== -1)
5447 cum
->intoffset
= bitpos
;
5451 /* Update the data in CUM to advance over an argument
5452 of mode MODE and data type TYPE.
5453 (TYPE is null for libcalls where that information may not be available.)
5455 Note that for args passed by reference, function_arg will be called
5456 with MODE and TYPE set to that of the pointer to the arg, not the arg
5460 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5461 tree type
, int named
, int depth
)
5465 /* Only tick off an argument if we're not recursing. */
5467 cum
->nargs_prototype
--;
5469 if (TARGET_ALTIVEC_ABI
5470 && (ALTIVEC_VECTOR_MODE (mode
)
5471 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5472 && int_size_in_bytes (type
) == 16)))
5476 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
5479 if (!TARGET_ALTIVEC
)
5480 error ("cannot pass argument in vector register because"
5481 " altivec instructions are disabled, use -maltivec"
5484 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
5485 even if it is going to be passed in a vector register.
5486 Darwin does the same for variable-argument functions. */
5487 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
5488 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
5498 /* Vector parameters must be 16-byte aligned. This places
5499 them at 2 mod 4 in terms of words in 32-bit mode, since
5500 the parameter save area starts at offset 24 from the
5501 stack. In 64-bit mode, they just have to start on an
5502 even word, since the parameter save area is 16-byte
5503 aligned. Space for GPRs is reserved even if the argument
5504 will be passed in memory. */
5506 align
= (2 - cum
->words
) & 3;
5508 align
= cum
->words
& 1;
5509 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
5511 if (TARGET_DEBUG_ARG
)
5513 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
5515 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
5516 cum
->nargs_prototype
, cum
->prototype
,
5517 GET_MODE_NAME (mode
));
5521 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
5523 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
5526 else if (rs6000_darwin64_abi
5528 && TREE_CODE (type
) == RECORD_TYPE
5529 && (size
= int_size_in_bytes (type
)) > 0)
5531 /* Variable sized types have size == -1 and are
5532 treated as if consisting entirely of ints.
5533 Pad to 16 byte boundary if needed. */
5534 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
5535 && (cum
->words
% 2) != 0)
5537 /* For varargs, we can just go up by the size of the struct. */
5539 cum
->words
+= (size
+ 7) / 8;
5542 /* It is tempting to say int register count just goes up by
5543 sizeof(type)/8, but this is wrong in a case such as
5544 { int; double; int; } [powerpc alignment]. We have to
5545 grovel through the fields for these too. */
5547 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
5548 rs6000_darwin64_record_arg_advance_flush (cum
,
5549 size
* BITS_PER_UNIT
);
5552 else if (DEFAULT_ABI
== ABI_V4
)
5554 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5555 && (mode
== SFmode
|| mode
== DFmode
5556 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
5557 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)))
5559 /* _Decimal128 must use an even/odd register pair. This assumes
5560 that the register number is odd when fregno is odd. */
5561 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
5564 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
5565 <= FP_ARG_V4_MAX_REG
)
5566 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5569 cum
->fregno
= FP_ARG_V4_MAX_REG
+ 1;
5570 if (mode
== DFmode
|| mode
== TFmode
5571 || mode
== DDmode
|| mode
== TDmode
)
5572 cum
->words
+= cum
->words
& 1;
5573 cum
->words
+= rs6000_arg_size (mode
, type
);
5578 int n_words
= rs6000_arg_size (mode
, type
);
5579 int gregno
= cum
->sysv_gregno
;
5581 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5582 (r7,r8) or (r9,r10). As does any other 2 word item such
5583 as complex int due to a historical mistake. */
5585 gregno
+= (1 - gregno
) & 1;
5587 /* Multi-reg args are not split between registers and stack. */
5588 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5590 /* Long long and SPE vectors are aligned on the stack.
5591 So are other 2 word items such as complex int due to
5592 a historical mistake. */
5594 cum
->words
+= cum
->words
& 1;
5595 cum
->words
+= n_words
;
5598 /* Note: continuing to accumulate gregno past when we've started
5599 spilling to the stack indicates the fact that we've started
5600 spilling to the stack to expand_builtin_saveregs. */
5601 cum
->sysv_gregno
= gregno
+ n_words
;
5604 if (TARGET_DEBUG_ARG
)
5606 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
5607 cum
->words
, cum
->fregno
);
5608 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
5609 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
5610 fprintf (stderr
, "mode = %4s, named = %d\n",
5611 GET_MODE_NAME (mode
), named
);
5616 int n_words
= rs6000_arg_size (mode
, type
);
5617 int start_words
= cum
->words
;
5618 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
5620 cum
->words
= align_words
+ n_words
;
5622 if (SCALAR_FLOAT_MODE_P (mode
)
5623 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
5625 /* _Decimal128 must be passed in an even/odd float register pair.
5626 This assumes that the register number is odd when fregno is
5628 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
5630 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5633 if (TARGET_DEBUG_ARG
)
5635 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
5636 cum
->words
, cum
->fregno
);
5637 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
5638 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
5639 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
5640 named
, align_words
- start_words
, depth
);
5646 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
5654 r1
= gen_rtx_REG (DImode
, gregno
);
5655 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5656 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
5661 r1
= gen_rtx_REG (DImode
, gregno
);
5662 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5663 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
5664 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
5665 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
5668 r1
= gen_rtx_REG (DImode
, gregno
);
5669 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5670 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
5671 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
5672 r5
= gen_rtx_REG (DImode
, gregno
+ 4);
5673 r5
= gen_rtx_EXPR_LIST (VOIDmode
, r5
, GEN_INT (16));
5674 r7
= gen_rtx_REG (DImode
, gregno
+ 6);
5675 r7
= gen_rtx_EXPR_LIST (VOIDmode
, r7
, GEN_INT (24));
5676 return gen_rtx_PARALLEL (mode
, gen_rtvec (4, r1
, r3
, r5
, r7
));
5683 /* Determine where to put a SIMD argument on the SPE. */
5685 rs6000_spe_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5688 int gregno
= cum
->sysv_gregno
;
5690 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
5691 are passed and returned in a pair of GPRs for ABI compatibility. */
5692 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5693 || mode
== DDmode
|| mode
== TDmode
5694 || mode
== DCmode
|| mode
== TCmode
))
5696 int n_words
= rs6000_arg_size (mode
, type
);
5698 /* Doubles go in an odd/even register pair (r5/r6, etc). */
5699 if (mode
== DFmode
|| mode
== DDmode
)
5700 gregno
+= (1 - gregno
) & 1;
5702 /* Multi-reg args are not split between registers and stack. */
5703 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5706 return spe_build_register_parallel (mode
, gregno
);
5710 int n_words
= rs6000_arg_size (mode
, type
);
5712 /* SPE vectors are put in odd registers. */
5713 if (n_words
== 2 && (gregno
& 1) == 0)
5716 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
5719 enum machine_mode m
= SImode
;
5721 r1
= gen_rtx_REG (m
, gregno
);
5722 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
5723 r2
= gen_rtx_REG (m
, gregno
+ 1);
5724 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
5725 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
5732 if (gregno
<= GP_ARG_MAX_REG
)
5733 return gen_rtx_REG (mode
, gregno
);
5739 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
5740 structure between cum->intoffset and bitpos to integer registers. */
5743 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
5744 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
5746 enum machine_mode mode
;
5748 unsigned int startbit
, endbit
;
5749 int this_regno
, intregs
, intoffset
;
5752 if (cum
->intoffset
== -1)
5755 intoffset
= cum
->intoffset
;
5756 cum
->intoffset
= -1;
5758 /* If this is the trailing part of a word, try to only load that
5759 much into the register. Otherwise load the whole register. Note
5760 that in the latter case we may pick up unwanted bits. It's not a
5761 problem at the moment but may wish to revisit. */
5763 if (intoffset
% BITS_PER_WORD
!= 0)
5765 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
5767 if (mode
== BLKmode
)
5769 /* We couldn't find an appropriate mode, which happens,
5770 e.g., in packed structs when there are 3 bytes to load.
5771 Back intoffset back to the beginning of the word in this
5773 intoffset
= intoffset
& -BITS_PER_WORD
;
5780 startbit
= intoffset
& -BITS_PER_WORD
;
5781 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
5782 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
5783 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
5785 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
5788 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
5792 intoffset
/= BITS_PER_UNIT
;
5795 regno
= GP_ARG_MIN_REG
+ this_regno
;
5796 reg
= gen_rtx_REG (mode
, regno
);
5798 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
5801 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
5805 while (intregs
> 0);
5808 /* Recursive workhorse for the following. */
5811 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, const_tree type
,
5812 HOST_WIDE_INT startbitpos
, rtx rvec
[],
5817 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
5818 if (TREE_CODE (f
) == FIELD_DECL
)
5820 HOST_WIDE_INT bitpos
= startbitpos
;
5821 tree ftype
= TREE_TYPE (f
);
5822 enum machine_mode mode
;
5823 if (ftype
== error_mark_node
)
5825 mode
= TYPE_MODE (ftype
);
5827 if (DECL_SIZE (f
) != 0
5828 && host_integerp (bit_position (f
), 1))
5829 bitpos
+= int_bit_position (f
);
5831 /* ??? FIXME: else assume zero offset. */
5833 if (TREE_CODE (ftype
) == RECORD_TYPE
)
5834 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
5835 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
5840 case SCmode
: mode
= SFmode
; break;
5841 case DCmode
: mode
= DFmode
; break;
5842 case TCmode
: mode
= TFmode
; break;
5846 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
5848 = gen_rtx_EXPR_LIST (VOIDmode
,
5849 gen_rtx_REG (mode
, cum
->fregno
++),
5850 GEN_INT (bitpos
/ BITS_PER_UNIT
));
5851 if (mode
== TFmode
|| mode
== TDmode
)
5854 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
5856 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
5858 = gen_rtx_EXPR_LIST (VOIDmode
,
5859 gen_rtx_REG (mode
, cum
->vregno
++),
5860 GEN_INT (bitpos
/ BITS_PER_UNIT
));
5862 else if (cum
->intoffset
== -1)
5863 cum
->intoffset
= bitpos
;
5867 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
5868 the register(s) to be used for each field and subfield of a struct
5869 being passed by value, along with the offset of where the
5870 register's value may be found in the block. FP fields go in FP
5871 register, vector fields go in vector registers, and everything
5872 else goes in int registers, packed as in memory.
5874 This code is also used for function return values. RETVAL indicates
5875 whether this is the case.
5877 Much of this is taken from the SPARC V9 port, which has a similar
5878 calling convention. */
5881 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, const_tree type
,
5882 int named
, bool retval
)
5884 rtx rvec
[FIRST_PSEUDO_REGISTER
];
5885 int k
= 1, kbase
= 1;
5886 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
5887 /* This is a copy; modifications are not visible to our caller. */
5888 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
5889 CUMULATIVE_ARGS
*cum
= ©_cum
;
5891 /* Pad to 16 byte boundary if needed. */
5892 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
5893 && (cum
->words
% 2) != 0)
5900 /* Put entries into rvec[] for individual FP and vector fields, and
5901 for the chunks of memory that go in int regs. Note we start at
5902 element 1; 0 is reserved for an indication of using memory, and
5903 may or may not be filled in below. */
5904 rs6000_darwin64_record_arg_recurse (cum
, type
, 0, rvec
, &k
);
5905 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
5907 /* If any part of the struct went on the stack put all of it there.
5908 This hack is because the generic code for
5909 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
5910 parts of the struct are not at the beginning. */
5914 return NULL_RTX
; /* doesn't go in registers at all */
5916 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
5918 if (k
> 1 || cum
->use_stack
)
5919 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
5924 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
5927 rs6000_mixed_function_arg (enum machine_mode mode
, tree type
, int align_words
)
5931 rtx rvec
[GP_ARG_NUM_REG
+ 1];
5933 if (align_words
>= GP_ARG_NUM_REG
)
5936 n_units
= rs6000_arg_size (mode
, type
);
5938 /* Optimize the simple case where the arg fits in one gpr, except in
5939 the case of BLKmode due to assign_parms assuming that registers are
5940 BITS_PER_WORD wide. */
5942 || (n_units
== 1 && mode
!= BLKmode
))
5943 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5946 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
5947 /* Not all of the arg fits in gprs. Say that it goes in memory too,
5948 using a magic NULL_RTX component.
5949 This is not strictly correct. Only some of the arg belongs in
5950 memory, not all of it. However, the normal scheme using
5951 function_arg_partial_nregs can result in unusual subregs, eg.
5952 (subreg:SI (reg:DF) 4), which are not handled well. The code to
5953 store the whole arg to memory is often more efficient than code
5954 to store pieces, and we know that space is available in the right
5955 place for the whole arg. */
5956 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
5961 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
5962 rtx off
= GEN_INT (i
++ * 4);
5963 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
5965 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
5967 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
5970 /* Determine where to put an argument to a function.
5971 Value is zero to push the argument on the stack,
5972 or a hard register in which to store the argument.
5974 MODE is the argument's machine mode.
5975 TYPE is the data type of the argument (as a tree).
5976 This is null for libcalls where that information may
5978 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5979 the preceding args and about the function being called. It is
5980 not modified in this routine.
5981 NAMED is nonzero if this argument is a named parameter
5982 (otherwise it is an extra parameter matching an ellipsis).
5984 On RS/6000 the first eight words of non-FP are normally in registers
5985 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
5986 Under V.4, the first 8 FP args are in registers.
5988 If this is floating-point and no prototype is specified, we use
5989 both an FP and integer register (or possibly FP reg and stack). Library
5990 functions (when CALL_LIBCALL is set) always have the proper types for args,
5991 so we can pass the FP value just in one register. emit_library_function
5992 doesn't support PARALLEL anyway.
5994 Note that for args passed by reference, function_arg will be called
5995 with MODE and TYPE set to that of the pointer to the arg, not the arg
5999 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6000 tree type
, int named
)
6002 enum rs6000_abi abi
= DEFAULT_ABI
;
6004 /* Return a marker to indicate whether CR1 needs to set or clear the
6005 bit that V.4 uses to say fp args were passed in registers.
6006 Assume that we don't need the marker for software floating point,
6007 or compiler generated library calls. */
6008 if (mode
== VOIDmode
)
6011 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
6013 || (cum
->nargs_prototype
< 0
6014 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))))
6016 /* For the SPE, we need to crxor CR6 always. */
6018 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
6019 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
6020 return GEN_INT (cum
->call_cookie
6021 | ((cum
->fregno
== FP_ARG_MIN_REG
)
6022 ? CALL_V4_SET_FP_ARGS
6023 : CALL_V4_CLEAR_FP_ARGS
));
6026 return GEN_INT (cum
->call_cookie
);
6029 if (rs6000_darwin64_abi
&& mode
== BLKmode
6030 && TREE_CODE (type
) == RECORD_TYPE
)
6032 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, false);
6033 if (rslt
!= NULL_RTX
)
6035 /* Else fall through to usual handling. */
6038 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
6039 if (TARGET_64BIT
&& ! cum
->prototype
)
6041 /* Vector parameters get passed in vector register
6042 and also in GPRs or memory, in absence of prototype. */
6045 align_words
= (cum
->words
+ 1) & ~1;
6047 if (align_words
>= GP_ARG_NUM_REG
)
6053 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6055 return gen_rtx_PARALLEL (mode
,
6057 gen_rtx_EXPR_LIST (VOIDmode
,
6059 gen_rtx_EXPR_LIST (VOIDmode
,
6060 gen_rtx_REG (mode
, cum
->vregno
),
6064 return gen_rtx_REG (mode
, cum
->vregno
);
6065 else if (TARGET_ALTIVEC_ABI
6066 && (ALTIVEC_VECTOR_MODE (mode
)
6067 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
6068 && int_size_in_bytes (type
) == 16)))
6070 if (named
|| abi
== ABI_V4
)
6074 /* Vector parameters to varargs functions under AIX or Darwin
6075 get passed in memory and possibly also in GPRs. */
6076 int align
, align_words
, n_words
;
6077 enum machine_mode part_mode
;
6079 /* Vector parameters must be 16-byte aligned. This places them at
6080 2 mod 4 in terms of words in 32-bit mode, since the parameter
6081 save area starts at offset 24 from the stack. In 64-bit mode,
6082 they just have to start on an even word, since the parameter
6083 save area is 16-byte aligned. */
6085 align
= (2 - cum
->words
) & 3;
6087 align
= cum
->words
& 1;
6088 align_words
= cum
->words
+ align
;
6090 /* Out of registers? Memory, then. */
6091 if (align_words
>= GP_ARG_NUM_REG
)
6094 if (TARGET_32BIT
&& TARGET_POWERPC64
)
6095 return rs6000_mixed_function_arg (mode
, type
, align_words
);
6097 /* The vector value goes in GPRs. Only the part of the
6098 value in GPRs is reported here. */
6100 n_words
= rs6000_arg_size (mode
, type
);
6101 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
6102 /* Fortunately, there are only two possibilities, the value
6103 is either wholly in GPRs or half in GPRs and half not. */
6106 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
6109 else if (TARGET_SPE_ABI
&& TARGET_SPE
6110 && (SPE_VECTOR_MODE (mode
)
6111 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
6116 || mode
== TCmode
))))
6117 return rs6000_spe_function_arg (cum
, mode
, type
);
6119 else if (abi
== ABI_V4
)
6121 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
6122 && (mode
== SFmode
|| mode
== DFmode
6123 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
6124 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
6126 /* _Decimal128 must use an even/odd register pair. This assumes
6127 that the register number is odd when fregno is odd. */
6128 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
6131 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
6132 <= FP_ARG_V4_MAX_REG
)
6133 return gen_rtx_REG (mode
, cum
->fregno
);
6139 int n_words
= rs6000_arg_size (mode
, type
);
6140 int gregno
= cum
->sysv_gregno
;
6142 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
6143 (r7,r8) or (r9,r10). As does any other 2 word item such
6144 as complex int due to a historical mistake. */
6146 gregno
+= (1 - gregno
) & 1;
6148 /* Multi-reg args are not split between registers and stack. */
6149 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
6152 if (TARGET_32BIT
&& TARGET_POWERPC64
)
6153 return rs6000_mixed_function_arg (mode
, type
,
6154 gregno
- GP_ARG_MIN_REG
);
6155 return gen_rtx_REG (mode
, gregno
);
6160 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
6162 /* _Decimal128 must be passed in an even/odd float register pair.
6163 This assumes that the register number is odd when fregno is odd. */
6164 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
6167 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
6169 rtx rvec
[GP_ARG_NUM_REG
+ 1];
6173 enum machine_mode fmode
= mode
;
6174 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
6176 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
6178 /* Currently, we only ever need one reg here because complex
6179 doubles are split. */
6180 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
6181 && (fmode
== TFmode
|| fmode
== TDmode
));
6183 /* Long double or _Decimal128 split over regs and memory. */
6184 fmode
= DECIMAL_FLOAT_MODE_P (fmode
) ? DDmode
: DFmode
;
6187 /* Do we also need to pass this arg in the parameter save
6190 && (cum
->nargs_prototype
<= 0
6191 || (DEFAULT_ABI
== ABI_AIX
6193 && align_words
>= GP_ARG_NUM_REG
)));
6195 if (!needs_psave
&& mode
== fmode
)
6196 return gen_rtx_REG (fmode
, cum
->fregno
);
6201 /* Describe the part that goes in gprs or the stack.
6202 This piece must come first, before the fprs. */
6203 if (align_words
< GP_ARG_NUM_REG
)
6205 unsigned long n_words
= rs6000_arg_size (mode
, type
);
6207 if (align_words
+ n_words
> GP_ARG_NUM_REG
6208 || (TARGET_32BIT
&& TARGET_POWERPC64
))
6210 /* If this is partially on the stack, then we only
6211 include the portion actually in registers here. */
6212 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
6215 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
6216 /* Not all of the arg fits in gprs. Say that it
6217 goes in memory too, using a magic NULL_RTX
6218 component. Also see comment in
6219 rs6000_mixed_function_arg for why the normal
6220 function_arg_partial_nregs scheme doesn't work
6222 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
6226 r
= gen_rtx_REG (rmode
,
6227 GP_ARG_MIN_REG
+ align_words
);
6228 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
6229 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
6231 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
6235 /* The whole arg fits in gprs. */
6236 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6237 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
6241 /* It's entirely in memory. */
6242 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
6245 /* Describe where this piece goes in the fprs. */
6246 r
= gen_rtx_REG (fmode
, cum
->fregno
);
6247 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
6249 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
6251 else if (align_words
< GP_ARG_NUM_REG
)
6253 if (TARGET_32BIT
&& TARGET_POWERPC64
)
6254 return rs6000_mixed_function_arg (mode
, type
, align_words
);
6256 if (mode
== BLKmode
)
6259 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6266 /* For an arg passed partly in registers and partly in memory, this is
6267 the number of bytes passed in registers. For args passed entirely in
6268 registers or entirely in memory, zero. When an arg is described by a
6269 PARALLEL, perhaps using more than one register type, this function
6270 returns the number of bytes used by the first element of the PARALLEL. */
6273 rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6274 tree type
, bool named
)
6279 if (DEFAULT_ABI
== ABI_V4
)
6282 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
6283 && cum
->nargs_prototype
>= 0)
6286 /* In this complicated case we just disable the partial_nregs code. */
6287 if (rs6000_darwin64_abi
&& mode
== BLKmode
6288 && TREE_CODE (type
) == RECORD_TYPE
6289 && int_size_in_bytes (type
) > 0)
6292 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
6294 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
6296 /* If we are passing this arg in the fixed parameter save area
6297 (gprs or memory) as well as fprs, then this function should
6298 return the number of partial bytes passed in the parameter
6299 save area rather than partial bytes passed in fprs. */
6301 && (cum
->nargs_prototype
<= 0
6302 || (DEFAULT_ABI
== ABI_AIX
6304 && align_words
>= GP_ARG_NUM_REG
)))
6306 else if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3)
6307 > FP_ARG_MAX_REG
+ 1)
6308 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
6309 else if (cum
->nargs_prototype
>= 0)
6313 if (align_words
< GP_ARG_NUM_REG
6314 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
6315 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
6317 if (ret
!= 0 && TARGET_DEBUG_ARG
)
6318 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
6323 /* A C expression that indicates when an argument must be passed by
6324 reference. If nonzero for an argument, a copy of that argument is
6325 made in memory and a pointer to the argument is passed instead of
6326 the argument itself. The pointer is passed in whatever way is
6327 appropriate for passing a pointer to that type.
6329 Under V.4, aggregates and long double are passed by reference.
6331 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
6332 reference unless the AltiVec vector extension ABI is in force.
6334 As an extension to all ABIs, variable sized types are passed by
6338 rs6000_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
6339 enum machine_mode mode
, const_tree type
,
6340 bool named ATTRIBUTE_UNUSED
)
6342 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& mode
== TFmode
)
6344 if (TARGET_DEBUG_ARG
)
6345 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
6352 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
6354 if (TARGET_DEBUG_ARG
)
6355 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
6359 if (int_size_in_bytes (type
) < 0)
6361 if (TARGET_DEBUG_ARG
)
6362 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
6366 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6367 modes only exist for GCC vector types if -maltivec. */
6368 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
6370 if (TARGET_DEBUG_ARG
)
6371 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
6375 /* Pass synthetic vectors in memory. */
6376 if (TREE_CODE (type
) == VECTOR_TYPE
6377 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
6379 static bool warned_for_pass_big_vectors
= false;
6380 if (TARGET_DEBUG_ARG
)
6381 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
6382 if (!warned_for_pass_big_vectors
)
6384 warning (0, "GCC vector passed by reference: "
6385 "non-standard ABI extension with no compatibility guarantee");
6386 warned_for_pass_big_vectors
= true;
6395 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
6398 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
6403 for (i
= 0; i
< nregs
; i
++)
6405 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
6406 if (reload_completed
)
6408 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
6411 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
6412 i
* GET_MODE_SIZE (reg_mode
));
6415 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
6419 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
6423 /* Perform any needed actions needed for a function that is receiving a
6424 variable number of arguments.
6428 MODE and TYPE are the mode and type of the current parameter.
6430 PRETEND_SIZE is a variable that should be set to the amount of stack
6431 that must be pushed by the prolog to pretend that our caller pushed
6434 Normally, this macro will push all remaining incoming registers on the
6435 stack and set PRETEND_SIZE to the length of the registers pushed. */
6438 setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6439 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
6442 CUMULATIVE_ARGS next_cum
;
6443 int reg_size
= TARGET_32BIT
? 4 : 8;
6444 rtx save_area
= NULL_RTX
, mem
;
6445 int first_reg_offset
;
6448 /* Skip the last named argument. */
6450 function_arg_advance (&next_cum
, mode
, type
, 1, 0);
6452 if (DEFAULT_ABI
== ABI_V4
)
6454 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
6458 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
6459 HOST_WIDE_INT offset
= 0;
6461 /* Try to optimize the size of the varargs save area.
6462 The ABI requires that ap.reg_save_area is doubleword
6463 aligned, but we don't need to allocate space for all
6464 the bytes, only those to which we actually will save
6466 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
6467 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
6468 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
6469 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
6470 && cfun
->va_list_fpr_size
)
6473 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
6474 * UNITS_PER_FP_WORD
;
6475 if (cfun
->va_list_fpr_size
6476 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
6477 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
6479 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
6480 * UNITS_PER_FP_WORD
;
6484 offset
= -((first_reg_offset
* reg_size
) & ~7);
6485 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
6487 gpr_reg_num
= cfun
->va_list_gpr_size
;
6488 if (reg_size
== 4 && (first_reg_offset
& 1))
6491 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
6494 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
6496 - (int) (GP_ARG_NUM_REG
* reg_size
);
6498 if (gpr_size
+ fpr_size
)
6501 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
6502 gcc_assert (GET_CODE (reg_save_area
) == MEM
);
6503 reg_save_area
= XEXP (reg_save_area
, 0);
6504 if (GET_CODE (reg_save_area
) == PLUS
)
6506 gcc_assert (XEXP (reg_save_area
, 0)
6507 == virtual_stack_vars_rtx
);
6508 gcc_assert (GET_CODE (XEXP (reg_save_area
, 1)) == CONST_INT
);
6509 offset
+= INTVAL (XEXP (reg_save_area
, 1));
6512 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
6515 cfun
->machine
->varargs_save_offset
= offset
;
6516 save_area
= plus_constant (virtual_stack_vars_rtx
, offset
);
6521 first_reg_offset
= next_cum
.words
;
6522 save_area
= virtual_incoming_args_rtx
;
6524 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
6525 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
6528 set
= get_varargs_alias_set ();
6529 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
6530 && cfun
->va_list_gpr_size
)
6532 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
6534 if (va_list_gpr_counter_field
)
6536 /* V4 va_list_gpr_size counts number of registers needed. */
6537 if (nregs
> cfun
->va_list_gpr_size
)
6538 nregs
= cfun
->va_list_gpr_size
;
6542 /* char * va_list instead counts number of bytes needed. */
6543 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
6544 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
6547 mem
= gen_rtx_MEM (BLKmode
,
6548 plus_constant (save_area
,
6549 first_reg_offset
* reg_size
));
6550 MEM_NOTRAP_P (mem
) = 1;
6551 set_mem_alias_set (mem
, set
);
6552 set_mem_align (mem
, BITS_PER_WORD
);
6554 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
6558 /* Save FP registers if needed. */
6559 if (DEFAULT_ABI
== ABI_V4
6560 && TARGET_HARD_FLOAT
&& TARGET_FPRS
6562 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
6563 && cfun
->va_list_fpr_size
)
6565 int fregno
= next_cum
.fregno
, nregs
;
6566 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
6567 rtx lab
= gen_label_rtx ();
6568 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
6569 * UNITS_PER_FP_WORD
);
6572 (gen_rtx_SET (VOIDmode
,
6574 gen_rtx_IF_THEN_ELSE (VOIDmode
,
6575 gen_rtx_NE (VOIDmode
, cr1
,
6577 gen_rtx_LABEL_REF (VOIDmode
, lab
),
6581 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
6582 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
6584 mem
= gen_rtx_MEM (DFmode
, plus_constant (save_area
, off
));
6585 MEM_NOTRAP_P (mem
) = 1;
6586 set_mem_alias_set (mem
, set
);
6587 set_mem_align (mem
, GET_MODE_ALIGNMENT (DFmode
));
6588 emit_move_insn (mem
, gen_rtx_REG (DFmode
, fregno
));
6595 /* Create the va_list data type. */
6598 rs6000_build_builtin_va_list (void)
6600 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
6602 /* For AIX, prefer 'char *' because that's what the system
6603 header files like. */
6604 if (DEFAULT_ABI
!= ABI_V4
)
6605 return build_pointer_type (char_type_node
);
6607 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
6608 type_decl
= build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
6610 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("gpr"),
6611 unsigned_char_type_node
);
6612 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("fpr"),
6613 unsigned_char_type_node
);
6614 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
6616 f_res
= build_decl (FIELD_DECL
, get_identifier ("reserved"),
6617 short_unsigned_type_node
);
6618 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("overflow_arg_area"),
6620 f_sav
= build_decl (FIELD_DECL
, get_identifier ("reg_save_area"),
6623 va_list_gpr_counter_field
= f_gpr
;
6624 va_list_fpr_counter_field
= f_fpr
;
6626 DECL_FIELD_CONTEXT (f_gpr
) = record
;
6627 DECL_FIELD_CONTEXT (f_fpr
) = record
;
6628 DECL_FIELD_CONTEXT (f_res
) = record
;
6629 DECL_FIELD_CONTEXT (f_ovf
) = record
;
6630 DECL_FIELD_CONTEXT (f_sav
) = record
;
6632 TREE_CHAIN (record
) = type_decl
;
6633 TYPE_NAME (record
) = type_decl
;
6634 TYPE_FIELDS (record
) = f_gpr
;
6635 TREE_CHAIN (f_gpr
) = f_fpr
;
6636 TREE_CHAIN (f_fpr
) = f_res
;
6637 TREE_CHAIN (f_res
) = f_ovf
;
6638 TREE_CHAIN (f_ovf
) = f_sav
;
6640 layout_type (record
);
6642 /* The correct type is an array type of one element. */
6643 return build_array_type (record
, build_index_type (size_zero_node
));
6646 /* Implement va_start. */
6649 rs6000_va_start (tree valist
, rtx nextarg
)
6651 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
6652 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
6653 tree gpr
, fpr
, ovf
, sav
, t
;
6655 /* Only SVR4 needs something special. */
6656 if (DEFAULT_ABI
!= ABI_V4
)
6658 std_expand_builtin_va_start (valist
, nextarg
);
6662 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6663 f_fpr
= TREE_CHAIN (f_gpr
);
6664 f_res
= TREE_CHAIN (f_fpr
);
6665 f_ovf
= TREE_CHAIN (f_res
);
6666 f_sav
= TREE_CHAIN (f_ovf
);
6668 valist
= build_va_arg_indirect_ref (valist
);
6669 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6670 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
6671 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
6672 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
6674 /* Count number of gp and fp argument registers used. */
6675 words
= crtl
->args
.info
.words
;
6676 n_gpr
= MIN (crtl
->args
.info
.sysv_gregno
- GP_ARG_MIN_REG
,
6678 n_fpr
= MIN (crtl
->args
.info
.fregno
- FP_ARG_MIN_REG
,
6681 if (TARGET_DEBUG_ARG
)
6682 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
6683 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
6684 words
, n_gpr
, n_fpr
);
6686 if (cfun
->va_list_gpr_size
)
6688 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (gpr
), gpr
,
6689 build_int_cst (NULL_TREE
, n_gpr
));
6690 TREE_SIDE_EFFECTS (t
) = 1;
6691 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6694 if (cfun
->va_list_fpr_size
)
6696 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (fpr
), fpr
,
6697 build_int_cst (NULL_TREE
, n_fpr
));
6698 TREE_SIDE_EFFECTS (t
) = 1;
6699 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6702 /* Find the overflow area. */
6703 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
6705 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ovf
), t
,
6706 size_int (words
* UNITS_PER_WORD
));
6707 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (ovf
), ovf
, t
);
6708 TREE_SIDE_EFFECTS (t
) = 1;
6709 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6711 /* If there were no va_arg invocations, don't set up the register
6713 if (!cfun
->va_list_gpr_size
6714 && !cfun
->va_list_fpr_size
6715 && n_gpr
< GP_ARG_NUM_REG
6716 && n_fpr
< FP_ARG_V4_MAX_REG
)
6719 /* Find the register save area. */
6720 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
6721 if (cfun
->machine
->varargs_save_offset
)
6722 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (sav
), t
,
6723 size_int (cfun
->machine
->varargs_save_offset
));
6724 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (sav
), sav
, t
);
6725 TREE_SIDE_EFFECTS (t
) = 1;
6726 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6729 /* Implement va_arg. */
6732 rs6000_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
6734 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
6735 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
6736 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
6737 tree lab_false
, lab_over
, addr
;
6739 tree ptrtype
= build_pointer_type (type
);
6742 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
6744 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
6745 return build_va_arg_indirect_ref (t
);
6748 if (DEFAULT_ABI
!= ABI_V4
)
6750 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
6752 tree elem_type
= TREE_TYPE (type
);
6753 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
6754 int elem_size
= GET_MODE_SIZE (elem_mode
);
6756 if (elem_size
< UNITS_PER_WORD
)
6758 tree real_part
, imag_part
;
6759 tree post
= NULL_TREE
;
6761 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
6763 /* Copy the value into a temporary, lest the formal temporary
6764 be reused out from under us. */
6765 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
6766 append_to_statement_list (post
, pre_p
);
6768 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
6771 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
6775 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
6778 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6779 f_fpr
= TREE_CHAIN (f_gpr
);
6780 f_res
= TREE_CHAIN (f_fpr
);
6781 f_ovf
= TREE_CHAIN (f_res
);
6782 f_sav
= TREE_CHAIN (f_ovf
);
6784 valist
= build_va_arg_indirect_ref (valist
);
6785 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6786 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
6787 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
6788 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
6790 size
= int_size_in_bytes (type
);
6791 rsize
= (size
+ 3) / 4;
6794 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
6795 && (TYPE_MODE (type
) == SFmode
6796 || TYPE_MODE (type
) == DFmode
6797 || TYPE_MODE (type
) == TFmode
6798 || TYPE_MODE (type
) == SDmode
6799 || TYPE_MODE (type
) == DDmode
6800 || TYPE_MODE (type
) == TDmode
))
6802 /* FP args go in FP registers, if present. */
6804 n_reg
= (size
+ 7) / 8;
6807 if (TYPE_MODE (type
) != SFmode
&& TYPE_MODE (type
) != SDmode
)
6812 /* Otherwise into GP registers. */
6821 /* Pull the value out of the saved registers.... */
6824 addr
= create_tmp_var (ptr_type_node
, "addr");
6825 DECL_POINTER_ALIAS_SET (addr
) = get_varargs_alias_set ();
6827 /* AltiVec vectors never go in registers when -mabi=altivec. */
6828 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
6832 lab_false
= create_artificial_label ();
6833 lab_over
= create_artificial_label ();
6835 /* Long long and SPE vectors are aligned in the registers.
6836 As are any other 2 gpr item such as complex int due to a
6837 historical mistake. */
6839 if (n_reg
== 2 && reg
== gpr
)
6842 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), reg
,
6843 build_int_cst (TREE_TYPE (reg
), n_reg
- 1));
6844 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), reg
, u
);
6846 /* _Decimal128 is passed in even/odd fpr pairs; the stored
6847 reg number is 0 for f1, so we want to make it odd. */
6848 else if (reg
== fpr
&& TYPE_MODE (type
) == TDmode
)
6851 t
= build2 (BIT_IOR_EXPR
, TREE_TYPE (reg
), reg
,
6852 build_int_cst (TREE_TYPE (reg
), 1));
6853 u
= build2 (MODIFY_EXPR
, void_type_node
, reg
, t
);
6856 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
6857 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
6858 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
6859 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
6860 gimplify_and_add (t
, pre_p
);
6864 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, sav
, size_int (sav_ofs
));
6866 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), reg
,
6867 build_int_cst (TREE_TYPE (reg
), n_reg
));
6868 u
= fold_convert (sizetype
, u
);
6869 u
= build2 (MULT_EXPR
, sizetype
, u
, size_int (sav_scale
));
6870 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
, u
);
6872 /* _Decimal32 varargs are located in the second word of the 64-bit
6873 FP register for 32-bit binaries. */
6874 if (!TARGET_POWERPC64
&& TYPE_MODE (type
) == SDmode
)
6875 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
6877 t
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, addr
, t
);
6878 gimplify_and_add (t
, pre_p
);
6880 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
6881 gimplify_and_add (t
, pre_p
);
6883 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
6884 append_to_statement_list (t
, pre_p
);
6886 if ((n_reg
== 2 && !regalign
) || n_reg
> 2)
6888 /* Ensure that we don't find any more args in regs.
6889 Alignment has taken care of for special cases. */
6890 t
= build_gimple_modify_stmt (reg
,
6891 build_int_cst (TREE_TYPE (reg
), 8));
6892 gimplify_and_add (t
, pre_p
);
6896 /* ... otherwise out of the overflow area. */
6898 /* Care for on-stack alignment if needed. */
6902 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (align
- 1));
6903 t
= fold_convert (sizetype
, t
);
6904 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
6906 t
= fold_convert (TREE_TYPE (ovf
), t
);
6908 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
6910 u
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, addr
, t
);
6911 gimplify_and_add (u
, pre_p
);
6913 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
6914 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (ovf
), ovf
, t
);
6915 gimplify_and_add (t
, pre_p
);
6919 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
6920 append_to_statement_list (t
, pre_p
);
6923 if (STRICT_ALIGNMENT
6924 && (TYPE_ALIGN (type
)
6925 > (unsigned) BITS_PER_UNIT
* (align
< 4 ? 4 : align
)))
6927 /* The value (of type complex double, for example) may not be
6928 aligned in memory in the saved registers, so copy via a
6929 temporary. (This is the same code as used for SPARC.) */
6930 tree tmp
= create_tmp_var (type
, "va_arg_tmp");
6931 tree dest_addr
= build_fold_addr_expr (tmp
);
6933 tree copy
= build_call_expr (implicit_built_in_decls
[BUILT_IN_MEMCPY
],
6934 3, dest_addr
, addr
, size_int (rsize
* 4));
6936 gimplify_and_add (copy
, pre_p
);
6940 addr
= fold_convert (ptrtype
, addr
);
6941 return build_va_arg_indirect_ref (addr
);
6947 def_builtin (int mask
, const char *name
, tree type
, int code
)
6949 if ((mask
& target_flags
) || TARGET_PAIRED_FLOAT
)
6951 if (rs6000_builtin_decls
[code
])
6954 rs6000_builtin_decls
[code
] =
6955 add_builtin_function (name
, type
, code
, BUILT_IN_MD
,
6960 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
6962 static const struct builtin_description bdesc_3arg
[] =
6964 { MASK_ALTIVEC
, CODE_FOR_altivec_vmaddfp
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
6965 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
6966 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
6967 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
6968 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
6969 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
6970 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
6971 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
6972 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
6973 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
6974 { MASK_ALTIVEC
, CODE_FOR_altivec_vnmsubfp
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
6975 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
6976 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
6977 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
6978 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
6979 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
6980 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
6981 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
6982 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
6983 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
6984 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
6985 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
6986 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
6988 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
6989 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
6990 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
6991 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
6992 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
6993 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
6994 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
6995 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
6996 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
6997 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
6998 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
6999 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
7000 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
7001 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
7002 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
7004 { 0, CODE_FOR_paired_msub
, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB
},
7005 { 0, CODE_FOR_paired_madd
, "__builtin_paired_madd", PAIRED_BUILTIN_MADD
},
7006 { 0, CODE_FOR_paired_madds0
, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0
},
7007 { 0, CODE_FOR_paired_madds1
, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1
},
7008 { 0, CODE_FOR_paired_nmsub
, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB
},
7009 { 0, CODE_FOR_paired_nmadd
, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD
},
7010 { 0, CODE_FOR_paired_sum0
, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0
},
7011 { 0, CODE_FOR_paired_sum1
, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1
},
7012 { 0, CODE_FOR_selv2sf4
, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4
},
7015 /* DST operations: void foo (void *, const int, const char). */
7017 static const struct builtin_description bdesc_dst
[] =
7019 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
7020 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
7021 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
7022 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
7024 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
7025 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
7026 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
7027 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
7030 /* Simple binary operations: VECc = foo (VECa, VECb). */
7032 static struct builtin_description bdesc_2arg
[] =
7034 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
7035 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
7036 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
7037 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
7038 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
7039 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
7040 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
7041 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
7042 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
7043 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
7044 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
7045 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
7046 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
7047 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
7048 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
7049 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
7050 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
7051 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
7052 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
7053 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
7054 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
7055 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
7056 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequb
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
7057 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequh
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
7058 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequw
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
7059 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpeqfp
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
7060 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgefp
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
7061 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtub
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
7062 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsb
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
7063 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuh
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
7064 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsh
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
7065 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuw
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
7066 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsw
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
7067 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtfp
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
7068 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
7069 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
7070 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
7071 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
7072 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
7073 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
7074 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
7075 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
7076 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
7077 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
7078 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
7079 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
7080 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
7081 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
7082 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
7083 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
7084 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
7085 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
7086 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
7087 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
7088 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
7089 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
7090 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
7091 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
7092 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
7093 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
7094 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
7095 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
7096 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
7097 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
7098 { MASK_ALTIVEC
, CODE_FOR_altivec_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
7099 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
7100 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
7101 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
7102 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
7103 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
7104 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
7105 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
7106 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
7107 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
7108 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
7109 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlb
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
7110 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlh
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
7111 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlw
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
7112 { MASK_ALTIVEC
, CODE_FOR_ashlv16qi3
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
7113 { MASK_ALTIVEC
, CODE_FOR_ashlv8hi3
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
7114 { MASK_ALTIVEC
, CODE_FOR_ashlv4si3
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
7115 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
7116 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
7117 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
7118 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
7119 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
7120 { MASK_ALTIVEC
, CODE_FOR_lshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
7121 { MASK_ALTIVEC
, CODE_FOR_lshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
7122 { MASK_ALTIVEC
, CODE_FOR_lshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
7123 { MASK_ALTIVEC
, CODE_FOR_ashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
7124 { MASK_ALTIVEC
, CODE_FOR_ashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
7125 { MASK_ALTIVEC
, CODE_FOR_ashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
7126 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
7127 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
7128 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
7129 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
7130 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
7131 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
7132 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
7133 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
7134 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
7135 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
7136 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
7137 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
7138 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
7139 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
7140 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
7141 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
7142 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
7143 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
7144 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
7146 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
7147 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
7148 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
7149 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
7150 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
7151 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
7152 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
7153 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
7154 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
7155 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
7156 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
7157 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
7158 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
7159 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
7160 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
7161 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
7162 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
7163 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
7164 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
7165 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
7166 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
7167 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
7168 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
7169 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
7170 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
7171 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
7172 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
7173 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
7174 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
7175 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
7176 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
7177 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
7178 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
7179 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
7180 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
7181 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
7182 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
7183 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
7184 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
7185 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
7186 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
7187 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
7188 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
7189 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
7190 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
7191 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
7192 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
7193 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
7194 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
7195 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
7196 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
7197 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
7198 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
7199 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
7200 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
7201 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
7202 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
7203 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
7204 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
7205 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
7206 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
7207 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
7208 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
7209 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
7210 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
7211 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
7212 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
7213 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
7214 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
7215 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
7216 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
7217 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
7218 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
7219 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
7220 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
7221 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
7222 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
7223 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
7224 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
7225 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
7226 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
7227 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
7228 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
7229 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
7230 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
7231 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
7232 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
7233 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
7234 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
7235 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
7236 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
7237 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
7238 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
7239 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
7240 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
7241 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
7242 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
7243 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
7244 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
7245 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
7246 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
7247 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
7248 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
7249 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
7250 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
7251 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
7252 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
7253 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
7254 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
7255 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
7256 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
7257 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
7258 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
7259 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
7260 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
7261 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
7262 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
7263 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
7264 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
7265 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
7266 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
7267 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
7268 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
7269 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
7270 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
7271 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
7272 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
7274 { 0, CODE_FOR_divv2sf3
, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3
},
7275 { 0, CODE_FOR_addv2sf3
, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3
},
7276 { 0, CODE_FOR_subv2sf3
, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3
},
7277 { 0, CODE_FOR_mulv2sf3
, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3
},
7278 { 0, CODE_FOR_paired_muls0
, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0
},
7279 { 0, CODE_FOR_paired_muls1
, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1
},
7280 { 0, CODE_FOR_paired_merge00
, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00
},
7281 { 0, CODE_FOR_paired_merge01
, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01
},
7282 { 0, CODE_FOR_paired_merge10
, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10
},
7283 { 0, CODE_FOR_paired_merge11
, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11
},
7285 /* Place holder, leave as first spe builtin. */
7286 { 0, CODE_FOR_spe_evaddw
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
7287 { 0, CODE_FOR_spe_evand
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
7288 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
7289 { 0, CODE_FOR_spe_evdivws
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
7290 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
7291 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
7292 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
7293 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
7294 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
7295 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
7296 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
7297 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
7298 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
7299 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
7300 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
7301 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
7302 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
7303 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
7304 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
7305 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
7306 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
7307 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
7308 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
7309 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
7310 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
7311 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
7312 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
7313 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
7314 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
7315 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
7316 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
7317 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
7318 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
7319 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
7320 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
7321 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
7322 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
7323 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
7324 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
7325 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
7326 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
7327 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
7328 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
7329 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
7330 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
7331 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
7332 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
7333 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
7334 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
7335 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
7336 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
7337 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
7338 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
7339 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
7340 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
7341 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
7342 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
7343 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
7344 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
7345 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
7346 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
7347 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
7348 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
7349 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
7350 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
7351 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
7352 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
7353 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
7354 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
7355 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
7356 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
7357 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
7358 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
7359 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
7360 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
7361 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
7362 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
7363 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
7364 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
7365 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
7366 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
7367 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
7368 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
7369 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
7370 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
7371 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
7372 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
7373 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
7374 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
7375 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
7376 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
7377 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
7378 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
7379 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
7380 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
7381 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
7382 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
7383 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
7384 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
7385 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
7386 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
7387 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
7388 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
7389 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
7390 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
7391 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
7392 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
7393 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
7394 { 0, CODE_FOR_spe_evsubfw
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
7396 /* SPE binary operations expecting a 5-bit unsigned literal. */
7397 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
7399 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
7400 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
7401 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
7402 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
7403 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
7404 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
7405 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
7406 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
7407 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
7408 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
7409 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
7410 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
7411 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
7412 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
7413 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
7414 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
7415 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
7416 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
7417 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
7418 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
7419 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
7420 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
7421 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
7422 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
7423 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
7424 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
7426 /* Place-holder. Leave as last binary SPE builtin. */
7427 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
7430 /* AltiVec predicates. */
7432 struct builtin_description_predicates
7434 const unsigned int mask
;
7435 const enum insn_code icode
;
7437 const char *const name
;
7438 const enum rs6000_builtins code
;
7441 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
7443 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P
},
7444 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
7445 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
7446 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
7447 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P
},
7448 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P
},
7449 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P
},
7450 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P
},
7451 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P
},
7452 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P
},
7453 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P
},
7454 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P
},
7455 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P
},
7457 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P
},
7458 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P
},
7459 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P
}
7462 /* SPE predicates. */
7463 static struct builtin_description bdesc_spe_predicates
[] =
7465 /* Place-holder. Leave as first. */
7466 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
7467 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
7468 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
7469 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
7470 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
7471 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
7472 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
7473 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
7474 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
7475 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
7476 /* Place-holder. Leave as last. */
7477 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
7480 /* SPE evsel predicates. */
7481 static struct builtin_description bdesc_spe_evsel
[] =
7483 /* Place-holder. Leave as first. */
7484 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
7485 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
7486 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
7487 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
7488 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
7489 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
7490 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
7491 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
7492 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
7493 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
7494 /* Place-holder. Leave as last. */
7495 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
7498 /* PAIRED predicates. */
7499 static const struct builtin_description bdesc_paired_preds
[] =
7501 /* Place-holder. Leave as first. */
7502 { 0, CODE_FOR_paired_cmpu0
, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0
},
7503 /* Place-holder. Leave as last. */
7504 { 0, CODE_FOR_paired_cmpu1
, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1
},
7507 /* ABS* operations. */
7509 static const struct builtin_description bdesc_abs
[] =
7511 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
7512 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
7513 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
7514 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
7515 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
7516 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
7517 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
}
7520 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
7523 static struct builtin_description bdesc_1arg
[] =
7525 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
7526 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
7527 { MASK_ALTIVEC
, CODE_FOR_altivec_vrefp
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
7528 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfim
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
7529 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
7530 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfip
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
7531 { MASK_ALTIVEC
, CODE_FOR_ftruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
7532 { MASK_ALTIVEC
, CODE_FOR_altivec_vrsqrtefp
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
7533 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
7534 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
7535 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
7536 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
7537 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
7538 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
7539 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
7540 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
7541 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
7543 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
7544 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
7545 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
7546 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
7547 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
7548 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
7549 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
7550 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
7551 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
7552 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
7553 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
7554 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
7555 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
7556 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
7557 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
7558 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
7559 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
7560 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
7561 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
7563 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
7564 end with SPE_BUILTIN_EVSUBFUSIAAW. */
7565 { 0, CODE_FOR_spe_evabs
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
7566 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
7567 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
7568 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
7569 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
7570 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
7571 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
7572 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
7573 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
7574 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
7575 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
7576 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
7577 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
7578 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
7579 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
7580 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
7581 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
7582 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
7583 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
7584 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
7585 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
7586 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
7587 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
7588 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
7589 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
7590 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
7591 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
7592 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
7594 /* Place-holder. Leave as last unary SPE builtin. */
7595 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
},
7597 { 0, CODE_FOR_absv2sf2
, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2
},
7598 { 0, CODE_FOR_nabsv2sf2
, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2
},
7599 { 0, CODE_FOR_negv2sf2
, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2
},
7600 { 0, CODE_FOR_sqrtv2sf2
, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2
},
7601 { 0, CODE_FOR_resv2sf2
, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2
}
7605 rs6000_expand_unop_builtin (enum insn_code icode
, tree exp
, rtx target
)
7608 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7609 rtx op0
= expand_normal (arg0
);
7610 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7611 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7613 if (icode
== CODE_FOR_nothing
)
7614 /* Builtin not supported on this processor. */
7617 /* If we got invalid arguments bail out before generating bad rtl. */
7618 if (arg0
== error_mark_node
)
7621 if (icode
== CODE_FOR_altivec_vspltisb
7622 || icode
== CODE_FOR_altivec_vspltish
7623 || icode
== CODE_FOR_altivec_vspltisw
7624 || icode
== CODE_FOR_spe_evsplatfi
7625 || icode
== CODE_FOR_spe_evsplati
)
7627 /* Only allow 5-bit *signed* literals. */
7628 if (GET_CODE (op0
) != CONST_INT
7629 || INTVAL (op0
) > 15
7630 || INTVAL (op0
) < -16)
7632 error ("argument 1 must be a 5-bit signed literal");
7638 || GET_MODE (target
) != tmode
7639 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7640 target
= gen_reg_rtx (tmode
);
7642 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7643 op0
= copy_to_mode_reg (mode0
, op0
);
7645 pat
= GEN_FCN (icode
) (target
, op0
);
7654 altivec_expand_abs_builtin (enum insn_code icode
, tree exp
, rtx target
)
7656 rtx pat
, scratch1
, scratch2
;
7657 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7658 rtx op0
= expand_normal (arg0
);
7659 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7660 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7662 /* If we have invalid arguments, bail out before generating bad rtl. */
7663 if (arg0
== error_mark_node
)
7667 || GET_MODE (target
) != tmode
7668 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7669 target
= gen_reg_rtx (tmode
);
7671 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7672 op0
= copy_to_mode_reg (mode0
, op0
);
7674 scratch1
= gen_reg_rtx (mode0
);
7675 scratch2
= gen_reg_rtx (mode0
);
7677 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
7686 rs6000_expand_binop_builtin (enum insn_code icode
, tree exp
, rtx target
)
7689 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7690 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7691 rtx op0
= expand_normal (arg0
);
7692 rtx op1
= expand_normal (arg1
);
7693 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7694 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7695 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7697 if (icode
== CODE_FOR_nothing
)
7698 /* Builtin not supported on this processor. */
7701 /* If we got invalid arguments bail out before generating bad rtl. */
7702 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7705 if (icode
== CODE_FOR_altivec_vcfux
7706 || icode
== CODE_FOR_altivec_vcfsx
7707 || icode
== CODE_FOR_altivec_vctsxs
7708 || icode
== CODE_FOR_altivec_vctuxs
7709 || icode
== CODE_FOR_altivec_vspltb
7710 || icode
== CODE_FOR_altivec_vsplth
7711 || icode
== CODE_FOR_altivec_vspltw
7712 || icode
== CODE_FOR_spe_evaddiw
7713 || icode
== CODE_FOR_spe_evldd
7714 || icode
== CODE_FOR_spe_evldh
7715 || icode
== CODE_FOR_spe_evldw
7716 || icode
== CODE_FOR_spe_evlhhesplat
7717 || icode
== CODE_FOR_spe_evlhhossplat
7718 || icode
== CODE_FOR_spe_evlhhousplat
7719 || icode
== CODE_FOR_spe_evlwhe
7720 || icode
== CODE_FOR_spe_evlwhos
7721 || icode
== CODE_FOR_spe_evlwhou
7722 || icode
== CODE_FOR_spe_evlwhsplat
7723 || icode
== CODE_FOR_spe_evlwwsplat
7724 || icode
== CODE_FOR_spe_evrlwi
7725 || icode
== CODE_FOR_spe_evslwi
7726 || icode
== CODE_FOR_spe_evsrwis
7727 || icode
== CODE_FOR_spe_evsubifw
7728 || icode
== CODE_FOR_spe_evsrwiu
)
7730 /* Only allow 5-bit unsigned literals. */
7732 if (TREE_CODE (arg1
) != INTEGER_CST
7733 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
7735 error ("argument 2 must be a 5-bit unsigned literal");
7741 || GET_MODE (target
) != tmode
7742 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7743 target
= gen_reg_rtx (tmode
);
7745 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7746 op0
= copy_to_mode_reg (mode0
, op0
);
7747 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7748 op1
= copy_to_mode_reg (mode1
, op1
);
7750 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
7759 altivec_expand_predicate_builtin (enum insn_code icode
, const char *opcode
,
7760 tree exp
, rtx target
)
7763 tree cr6_form
= CALL_EXPR_ARG (exp
, 0);
7764 tree arg0
= CALL_EXPR_ARG (exp
, 1);
7765 tree arg1
= CALL_EXPR_ARG (exp
, 2);
7766 rtx op0
= expand_normal (arg0
);
7767 rtx op1
= expand_normal (arg1
);
7768 enum machine_mode tmode
= SImode
;
7769 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7770 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7773 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
7775 error ("argument 1 of __builtin_altivec_predicate must be a constant");
7779 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
7781 gcc_assert (mode0
== mode1
);
7783 /* If we have invalid arguments, bail out before generating bad rtl. */
7784 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7788 || GET_MODE (target
) != tmode
7789 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7790 target
= gen_reg_rtx (tmode
);
7792 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7793 op0
= copy_to_mode_reg (mode0
, op0
);
7794 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7795 op1
= copy_to_mode_reg (mode1
, op1
);
7797 scratch
= gen_reg_rtx (mode0
);
7799 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
,
7800 gen_rtx_SYMBOL_REF (Pmode
, opcode
));
7805 /* The vec_any* and vec_all* predicates use the same opcodes for two
7806 different operations, but the bits in CR6 will be different
7807 depending on what information we want. So we have to play tricks
7808 with CR6 to get the right bits out.
7810 If you think this is disgusting, look at the specs for the
7811 AltiVec predicates. */
7813 switch (cr6_form_int
)
7816 emit_insn (gen_cr6_test_for_zero (target
));
7819 emit_insn (gen_cr6_test_for_zero_reverse (target
));
7822 emit_insn (gen_cr6_test_for_lt (target
));
7825 emit_insn (gen_cr6_test_for_lt_reverse (target
));
7828 error ("argument 1 of __builtin_altivec_predicate is out of range");
7836 paired_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
)
7839 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7840 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7841 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7842 enum machine_mode mode0
= Pmode
;
7843 enum machine_mode mode1
= Pmode
;
7844 rtx op0
= expand_normal (arg0
);
7845 rtx op1
= expand_normal (arg1
);
7847 if (icode
== CODE_FOR_nothing
)
7848 /* Builtin not supported on this processor. */
7851 /* If we got invalid arguments bail out before generating bad rtl. */
7852 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7856 || GET_MODE (target
) != tmode
7857 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7858 target
= gen_reg_rtx (tmode
);
7860 op1
= copy_to_mode_reg (mode1
, op1
);
7862 if (op0
== const0_rtx
)
7864 addr
= gen_rtx_MEM (tmode
, op1
);
7868 op0
= copy_to_mode_reg (mode0
, op0
);
7869 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
7872 pat
= GEN_FCN (icode
) (target
, addr
);
7882 altivec_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
)
7885 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7886 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7887 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7888 enum machine_mode mode0
= Pmode
;
7889 enum machine_mode mode1
= Pmode
;
7890 rtx op0
= expand_normal (arg0
);
7891 rtx op1
= expand_normal (arg1
);
7893 if (icode
== CODE_FOR_nothing
)
7894 /* Builtin not supported on this processor. */
7897 /* If we got invalid arguments bail out before generating bad rtl. */
7898 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7902 || GET_MODE (target
) != tmode
7903 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7904 target
= gen_reg_rtx (tmode
);
7906 op1
= copy_to_mode_reg (mode1
, op1
);
7908 if (op0
== const0_rtx
)
7910 addr
= gen_rtx_MEM (tmode
, op1
);
7914 op0
= copy_to_mode_reg (mode0
, op0
);
7915 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
7918 pat
= GEN_FCN (icode
) (target
, addr
);
7928 spe_expand_stv_builtin (enum insn_code icode
, tree exp
)
7930 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7931 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7932 tree arg2
= CALL_EXPR_ARG (exp
, 2);
7933 rtx op0
= expand_normal (arg0
);
7934 rtx op1
= expand_normal (arg1
);
7935 rtx op2
= expand_normal (arg2
);
7937 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
7938 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
7939 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
7941 /* Invalid arguments. Bail before doing anything stoopid! */
7942 if (arg0
== error_mark_node
7943 || arg1
== error_mark_node
7944 || arg2
== error_mark_node
)
7947 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
7948 op0
= copy_to_mode_reg (mode2
, op0
);
7949 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
7950 op1
= copy_to_mode_reg (mode0
, op1
);
7951 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
7952 op2
= copy_to_mode_reg (mode1
, op2
);
7954 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
7961 paired_expand_stv_builtin (enum insn_code icode
, tree exp
)
7963 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7964 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7965 tree arg2
= CALL_EXPR_ARG (exp
, 2);
7966 rtx op0
= expand_normal (arg0
);
7967 rtx op1
= expand_normal (arg1
);
7968 rtx op2
= expand_normal (arg2
);
7970 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7971 enum machine_mode mode1
= Pmode
;
7972 enum machine_mode mode2
= Pmode
;
7974 /* Invalid arguments. Bail before doing anything stoopid! */
7975 if (arg0
== error_mark_node
7976 || arg1
== error_mark_node
7977 || arg2
== error_mark_node
)
7980 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
7981 op0
= copy_to_mode_reg (tmode
, op0
);
7983 op2
= copy_to_mode_reg (mode2
, op2
);
7985 if (op1
== const0_rtx
)
7987 addr
= gen_rtx_MEM (tmode
, op2
);
7991 op1
= copy_to_mode_reg (mode1
, op1
);
7992 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
7995 pat
= GEN_FCN (icode
) (addr
, op0
);
8002 altivec_expand_stv_builtin (enum insn_code icode
, tree exp
)
8004 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8005 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8006 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8007 rtx op0
= expand_normal (arg0
);
8008 rtx op1
= expand_normal (arg1
);
8009 rtx op2
= expand_normal (arg2
);
8011 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8012 enum machine_mode mode1
= Pmode
;
8013 enum machine_mode mode2
= Pmode
;
8015 /* Invalid arguments. Bail before doing anything stoopid! */
8016 if (arg0
== error_mark_node
8017 || arg1
== error_mark_node
8018 || arg2
== error_mark_node
)
8021 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
8022 op0
= copy_to_mode_reg (tmode
, op0
);
8024 op2
= copy_to_mode_reg (mode2
, op2
);
8026 if (op1
== const0_rtx
)
8028 addr
= gen_rtx_MEM (tmode
, op2
);
8032 op1
= copy_to_mode_reg (mode1
, op1
);
8033 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
8036 pat
= GEN_FCN (icode
) (addr
, op0
);
8043 rs6000_expand_ternop_builtin (enum insn_code icode
, tree exp
, rtx target
)
8046 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8047 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8048 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8049 rtx op0
= expand_normal (arg0
);
8050 rtx op1
= expand_normal (arg1
);
8051 rtx op2
= expand_normal (arg2
);
8052 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8053 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8054 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8055 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
8057 if (icode
== CODE_FOR_nothing
)
8058 /* Builtin not supported on this processor. */
8061 /* If we got invalid arguments bail out before generating bad rtl. */
8062 if (arg0
== error_mark_node
8063 || arg1
== error_mark_node
8064 || arg2
== error_mark_node
)
8067 if (icode
== CODE_FOR_altivec_vsldoi_v4sf
8068 || icode
== CODE_FOR_altivec_vsldoi_v4si
8069 || icode
== CODE_FOR_altivec_vsldoi_v8hi
8070 || icode
== CODE_FOR_altivec_vsldoi_v16qi
)
8072 /* Only allow 4-bit unsigned literals. */
8074 if (TREE_CODE (arg2
) != INTEGER_CST
8075 || TREE_INT_CST_LOW (arg2
) & ~0xf)
8077 error ("argument 3 must be a 4-bit unsigned literal");
8083 || GET_MODE (target
) != tmode
8084 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8085 target
= gen_reg_rtx (tmode
);
8087 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8088 op0
= copy_to_mode_reg (mode0
, op0
);
8089 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
8090 op1
= copy_to_mode_reg (mode1
, op1
);
8091 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
8092 op2
= copy_to_mode_reg (mode2
, op2
);
8094 if (TARGET_PAIRED_FLOAT
&& icode
== CODE_FOR_selv2sf4
)
8095 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
, CONST0_RTX (SFmode
));
8097 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
8105 /* Expand the lvx builtins. */
8107 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
8109 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8110 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8112 enum machine_mode tmode
, mode0
;
8114 enum insn_code icode
;
8118 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
8119 icode
= CODE_FOR_altivec_lvx_v16qi
;
8121 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
8122 icode
= CODE_FOR_altivec_lvx_v8hi
;
8124 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
8125 icode
= CODE_FOR_altivec_lvx_v4si
;
8127 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
8128 icode
= CODE_FOR_altivec_lvx_v4sf
;
8137 arg0
= CALL_EXPR_ARG (exp
, 0);
8138 op0
= expand_normal (arg0
);
8139 tmode
= insn_data
[icode
].operand
[0].mode
;
8140 mode0
= insn_data
[icode
].operand
[1].mode
;
8143 || GET_MODE (target
) != tmode
8144 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8145 target
= gen_reg_rtx (tmode
);
8147 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8148 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
8150 pat
= GEN_FCN (icode
) (target
, op0
);
8157 /* Expand the stvx builtins. */
8159 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
8162 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8163 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8165 enum machine_mode mode0
, mode1
;
8167 enum insn_code icode
;
8171 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
8172 icode
= CODE_FOR_altivec_stvx_v16qi
;
8174 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
8175 icode
= CODE_FOR_altivec_stvx_v8hi
;
8177 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
8178 icode
= CODE_FOR_altivec_stvx_v4si
;
8180 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
8181 icode
= CODE_FOR_altivec_stvx_v4sf
;
8188 arg0
= CALL_EXPR_ARG (exp
, 0);
8189 arg1
= CALL_EXPR_ARG (exp
, 1);
8190 op0
= expand_normal (arg0
);
8191 op1
= expand_normal (arg1
);
8192 mode0
= insn_data
[icode
].operand
[0].mode
;
8193 mode1
= insn_data
[icode
].operand
[1].mode
;
8195 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8196 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
8197 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
8198 op1
= copy_to_mode_reg (mode1
, op1
);
8200 pat
= GEN_FCN (icode
) (op0
, op1
);
8208 /* Expand the dst builtins. */
8210 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
8213 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8214 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8215 tree arg0
, arg1
, arg2
;
8216 enum machine_mode mode0
, mode1
, mode2
;
8217 rtx pat
, op0
, op1
, op2
;
8218 const struct builtin_description
*d
;
8223 /* Handle DST variants. */
8225 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
8226 if (d
->code
== fcode
)
8228 arg0
= CALL_EXPR_ARG (exp
, 0);
8229 arg1
= CALL_EXPR_ARG (exp
, 1);
8230 arg2
= CALL_EXPR_ARG (exp
, 2);
8231 op0
= expand_normal (arg0
);
8232 op1
= expand_normal (arg1
);
8233 op2
= expand_normal (arg2
);
8234 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8235 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
8236 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
8238 /* Invalid arguments, bail out before generating bad rtl. */
8239 if (arg0
== error_mark_node
8240 || arg1
== error_mark_node
8241 || arg2
== error_mark_node
)
8246 if (TREE_CODE (arg2
) != INTEGER_CST
8247 || TREE_INT_CST_LOW (arg2
) & ~0x3)
8249 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
8253 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
8254 op0
= copy_to_mode_reg (Pmode
, op0
);
8255 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
8256 op1
= copy_to_mode_reg (mode1
, op1
);
8258 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
8268 /* Expand vec_init builtin. */
8270 altivec_expand_vec_init_builtin (tree type
, tree exp
, rtx target
)
8272 enum machine_mode tmode
= TYPE_MODE (type
);
8273 enum machine_mode inner_mode
= GET_MODE_INNER (tmode
);
8274 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
8275 rtvec v
= rtvec_alloc (n_elt
);
8277 gcc_assert (VECTOR_MODE_P (tmode
));
8278 gcc_assert (n_elt
== call_expr_nargs (exp
));
8280 for (i
= 0; i
< n_elt
; ++i
)
8282 rtx x
= expand_normal (CALL_EXPR_ARG (exp
, i
));
8283 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
8286 if (!target
|| !register_operand (target
, tmode
))
8287 target
= gen_reg_rtx (tmode
);
8289 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
8293 /* Return the integer constant in ARG. Constrain it to be in the range
8294 of the subparts of VEC_TYPE; issue an error if not. */
8297 get_element_number (tree vec_type
, tree arg
)
8299 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
8301 if (!host_integerp (arg
, 1)
8302 || (elt
= tree_low_cst (arg
, 1), elt
> max
))
8304 error ("selector must be an integer constant in the range 0..%wi", max
);
8311 /* Expand vec_set builtin. */
8313 altivec_expand_vec_set_builtin (tree exp
)
8315 enum machine_mode tmode
, mode1
;
8316 tree arg0
, arg1
, arg2
;
8320 arg0
= CALL_EXPR_ARG (exp
, 0);
8321 arg1
= CALL_EXPR_ARG (exp
, 1);
8322 arg2
= CALL_EXPR_ARG (exp
, 2);
8324 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
8325 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
8326 gcc_assert (VECTOR_MODE_P (tmode
));
8328 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, 0);
8329 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, 0);
8330 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
8332 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
8333 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
8335 op0
= force_reg (tmode
, op0
);
8336 op1
= force_reg (mode1
, op1
);
8338 rs6000_expand_vector_set (op0
, op1
, elt
);
8343 /* Expand vec_ext builtin. */
8345 altivec_expand_vec_ext_builtin (tree exp
, rtx target
)
8347 enum machine_mode tmode
, mode0
;
8352 arg0
= CALL_EXPR_ARG (exp
, 0);
8353 arg1
= CALL_EXPR_ARG (exp
, 1);
8355 op0
= expand_normal (arg0
);
8356 elt
= get_element_number (TREE_TYPE (arg0
), arg1
);
8358 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
8359 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
8360 gcc_assert (VECTOR_MODE_P (mode0
));
8362 op0
= force_reg (mode0
, op0
);
8364 if (optimize
|| !target
|| !register_operand (target
, tmode
))
8365 target
= gen_reg_rtx (tmode
);
8367 rs6000_expand_vector_extract (target
, op0
, elt
);
8372 /* Expand the builtin in EXP and store the result in TARGET. Store
8373 true in *EXPANDEDP if we found a builtin to expand. */
8375 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
8377 const struct builtin_description
*d
;
8378 const struct builtin_description_predicates
*dp
;
8380 enum insn_code icode
;
8381 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8384 enum machine_mode tmode
, mode0
;
8385 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8387 if (fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8388 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
8391 error ("unresolved overload for Altivec builtin %qF", fndecl
);
8395 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
8399 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
8403 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
8411 case ALTIVEC_BUILTIN_STVX
:
8412 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx
, exp
);
8413 case ALTIVEC_BUILTIN_STVEBX
:
8414 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, exp
);
8415 case ALTIVEC_BUILTIN_STVEHX
:
8416 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, exp
);
8417 case ALTIVEC_BUILTIN_STVEWX
:
8418 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, exp
);
8419 case ALTIVEC_BUILTIN_STVXL
:
8420 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, exp
);
8422 case ALTIVEC_BUILTIN_MFVSCR
:
8423 icode
= CODE_FOR_altivec_mfvscr
;
8424 tmode
= insn_data
[icode
].operand
[0].mode
;
8427 || GET_MODE (target
) != tmode
8428 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8429 target
= gen_reg_rtx (tmode
);
8431 pat
= GEN_FCN (icode
) (target
);
8437 case ALTIVEC_BUILTIN_MTVSCR
:
8438 icode
= CODE_FOR_altivec_mtvscr
;
8439 arg0
= CALL_EXPR_ARG (exp
, 0);
8440 op0
= expand_normal (arg0
);
8441 mode0
= insn_data
[icode
].operand
[0].mode
;
8443 /* If we got invalid arguments bail out before generating bad rtl. */
8444 if (arg0
== error_mark_node
)
8447 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8448 op0
= copy_to_mode_reg (mode0
, op0
);
8450 pat
= GEN_FCN (icode
) (op0
);
8455 case ALTIVEC_BUILTIN_DSSALL
:
8456 emit_insn (gen_altivec_dssall ());
8459 case ALTIVEC_BUILTIN_DSS
:
8460 icode
= CODE_FOR_altivec_dss
;
8461 arg0
= CALL_EXPR_ARG (exp
, 0);
8463 op0
= expand_normal (arg0
);
8464 mode0
= insn_data
[icode
].operand
[0].mode
;
8466 /* If we got invalid arguments bail out before generating bad rtl. */
8467 if (arg0
== error_mark_node
)
8470 if (TREE_CODE (arg0
) != INTEGER_CST
8471 || TREE_INT_CST_LOW (arg0
) & ~0x3)
8473 error ("argument to dss must be a 2-bit unsigned literal");
8477 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8478 op0
= copy_to_mode_reg (mode0
, op0
);
8480 emit_insn (gen_altivec_dss (op0
));
8483 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
8484 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
8485 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
8486 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
8487 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), exp
, target
);
8489 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
8490 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
8491 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
8492 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
8493 return altivec_expand_vec_set_builtin (exp
);
8495 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
8496 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
8497 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
8498 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
8499 return altivec_expand_vec_ext_builtin (exp
, target
);
8506 /* Expand abs* operations. */
8508 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
8509 if (d
->code
== fcode
)
8510 return altivec_expand_abs_builtin (d
->icode
, exp
, target
);
8512 /* Expand the AltiVec predicates. */
8513 dp
= bdesc_altivec_preds
;
8514 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
8515 if (dp
->code
== fcode
)
8516 return altivec_expand_predicate_builtin (dp
->icode
, dp
->opcode
,
8519 /* LV* are funky. We initialized them differently. */
8522 case ALTIVEC_BUILTIN_LVSL
:
8523 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
8525 case ALTIVEC_BUILTIN_LVSR
:
8526 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
8528 case ALTIVEC_BUILTIN_LVEBX
:
8529 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
8531 case ALTIVEC_BUILTIN_LVEHX
:
8532 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
8534 case ALTIVEC_BUILTIN_LVEWX
:
8535 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
8537 case ALTIVEC_BUILTIN_LVXL
:
8538 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
8540 case ALTIVEC_BUILTIN_LVX
:
8541 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx
,
8552 /* Expand the builtin in EXP and store the result in TARGET. Store
8553 true in *EXPANDEDP if we found a builtin to expand. */
8555 paired_expand_builtin (tree exp
, rtx target
, bool * expandedp
)
8557 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8558 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8559 const struct builtin_description
*d
;
8566 case PAIRED_BUILTIN_STX
:
8567 return paired_expand_stv_builtin (CODE_FOR_paired_stx
, exp
);
8568 case PAIRED_BUILTIN_LX
:
8569 return paired_expand_lv_builtin (CODE_FOR_paired_lx
, exp
, target
);
8575 /* Expand the paired predicates. */
8576 d
= bdesc_paired_preds
;
8577 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); i
++, d
++)
8578 if (d
->code
== fcode
)
8579 return paired_expand_predicate_builtin (d
->icode
, exp
, target
);
8585 /* Binops that need to be initialized manually, but can be expanded
8586 automagically by rs6000_expand_binop_builtin. */
8587 static struct builtin_description bdesc_2arg_spe
[] =
8589 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
8590 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
8591 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
8592 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
8593 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
8594 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
8595 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
8596 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
8597 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
8598 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
8599 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
8600 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
8601 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
8602 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
8603 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
8604 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
8605 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
8606 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
8607 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
8608 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
8609 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
8610 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
8613 /* Expand the builtin in EXP and store the result in TARGET. Store
8614 true in *EXPANDEDP if we found a builtin to expand.
8616 This expands the SPE builtins that are not simple unary and binary
8619 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
8621 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8623 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8624 enum insn_code icode
;
8625 enum machine_mode tmode
, mode0
;
8627 struct builtin_description
*d
;
8632 /* Syntax check for a 5-bit unsigned immediate. */
8635 case SPE_BUILTIN_EVSTDD
:
8636 case SPE_BUILTIN_EVSTDH
:
8637 case SPE_BUILTIN_EVSTDW
:
8638 case SPE_BUILTIN_EVSTWHE
:
8639 case SPE_BUILTIN_EVSTWHO
:
8640 case SPE_BUILTIN_EVSTWWE
:
8641 case SPE_BUILTIN_EVSTWWO
:
8642 arg1
= CALL_EXPR_ARG (exp
, 2);
8643 if (TREE_CODE (arg1
) != INTEGER_CST
8644 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
8646 error ("argument 2 must be a 5-bit unsigned literal");
8654 /* The evsplat*i instructions are not quite generic. */
8657 case SPE_BUILTIN_EVSPLATFI
:
8658 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
8660 case SPE_BUILTIN_EVSPLATI
:
8661 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
8667 d
= (struct builtin_description
*) bdesc_2arg_spe
;
8668 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
8669 if (d
->code
== fcode
)
8670 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
8672 d
= (struct builtin_description
*) bdesc_spe_predicates
;
8673 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
8674 if (d
->code
== fcode
)
8675 return spe_expand_predicate_builtin (d
->icode
, exp
, target
);
8677 d
= (struct builtin_description
*) bdesc_spe_evsel
;
8678 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
8679 if (d
->code
== fcode
)
8680 return spe_expand_evsel_builtin (d
->icode
, exp
, target
);
8684 case SPE_BUILTIN_EVSTDDX
:
8685 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, exp
);
8686 case SPE_BUILTIN_EVSTDHX
:
8687 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, exp
);
8688 case SPE_BUILTIN_EVSTDWX
:
8689 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, exp
);
8690 case SPE_BUILTIN_EVSTWHEX
:
8691 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, exp
);
8692 case SPE_BUILTIN_EVSTWHOX
:
8693 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, exp
);
8694 case SPE_BUILTIN_EVSTWWEX
:
8695 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, exp
);
8696 case SPE_BUILTIN_EVSTWWOX
:
8697 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, exp
);
8698 case SPE_BUILTIN_EVSTDD
:
8699 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, exp
);
8700 case SPE_BUILTIN_EVSTDH
:
8701 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, exp
);
8702 case SPE_BUILTIN_EVSTDW
:
8703 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, exp
);
8704 case SPE_BUILTIN_EVSTWHE
:
8705 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, exp
);
8706 case SPE_BUILTIN_EVSTWHO
:
8707 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, exp
);
8708 case SPE_BUILTIN_EVSTWWE
:
8709 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, exp
);
8710 case SPE_BUILTIN_EVSTWWO
:
8711 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, exp
);
8712 case SPE_BUILTIN_MFSPEFSCR
:
8713 icode
= CODE_FOR_spe_mfspefscr
;
8714 tmode
= insn_data
[icode
].operand
[0].mode
;
8717 || GET_MODE (target
) != tmode
8718 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8719 target
= gen_reg_rtx (tmode
);
8721 pat
= GEN_FCN (icode
) (target
);
8726 case SPE_BUILTIN_MTSPEFSCR
:
8727 icode
= CODE_FOR_spe_mtspefscr
;
8728 arg0
= CALL_EXPR_ARG (exp
, 0);
8729 op0
= expand_normal (arg0
);
8730 mode0
= insn_data
[icode
].operand
[0].mode
;
8732 if (arg0
== error_mark_node
)
8735 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8736 op0
= copy_to_mode_reg (mode0
, op0
);
8738 pat
= GEN_FCN (icode
) (op0
);
8751 paired_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
8753 rtx pat
, scratch
, tmp
;
8754 tree form
= CALL_EXPR_ARG (exp
, 0);
8755 tree arg0
= CALL_EXPR_ARG (exp
, 1);
8756 tree arg1
= CALL_EXPR_ARG (exp
, 2);
8757 rtx op0
= expand_normal (arg0
);
8758 rtx op1
= expand_normal (arg1
);
8759 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8760 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8764 if (TREE_CODE (form
) != INTEGER_CST
)
8766 error ("argument 1 of __builtin_paired_predicate must be a constant");
8770 form_int
= TREE_INT_CST_LOW (form
);
8772 gcc_assert (mode0
== mode1
);
8774 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
8778 || GET_MODE (target
) != SImode
8779 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
8780 target
= gen_reg_rtx (SImode
);
8781 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8782 op0
= copy_to_mode_reg (mode0
, op0
);
8783 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
8784 op1
= copy_to_mode_reg (mode1
, op1
);
8786 scratch
= gen_reg_rtx (CCFPmode
);
8788 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
8810 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
8813 error ("argument 1 of __builtin_paired_predicate is out of range");
8817 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
8818 emit_move_insn (target
, tmp
);
8823 spe_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
8825 rtx pat
, scratch
, tmp
;
8826 tree form
= CALL_EXPR_ARG (exp
, 0);
8827 tree arg0
= CALL_EXPR_ARG (exp
, 1);
8828 tree arg1
= CALL_EXPR_ARG (exp
, 2);
8829 rtx op0
= expand_normal (arg0
);
8830 rtx op1
= expand_normal (arg1
);
8831 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8832 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8836 if (TREE_CODE (form
) != INTEGER_CST
)
8838 error ("argument 1 of __builtin_spe_predicate must be a constant");
8842 form_int
= TREE_INT_CST_LOW (form
);
8844 gcc_assert (mode0
== mode1
);
8846 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
8850 || GET_MODE (target
) != SImode
8851 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
8852 target
= gen_reg_rtx (SImode
);
8854 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8855 op0
= copy_to_mode_reg (mode0
, op0
);
8856 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
8857 op1
= copy_to_mode_reg (mode1
, op1
);
8859 scratch
= gen_reg_rtx (CCmode
);
8861 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
8866 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
8867 _lower_. We use one compare, but look in different bits of the
8868 CR for each variant.
8870 There are 2 elements in each SPE simd type (upper/lower). The CR
8871 bits are set as follows:
8873 BIT0 | BIT 1 | BIT 2 | BIT 3
8874 U | L | (U | L) | (U & L)
8876 So, for an "all" relationship, BIT 3 would be set.
8877 For an "any" relationship, BIT 2 would be set. Etc.
8879 Following traditional nomenclature, these bits map to:
8881 BIT0 | BIT 1 | BIT 2 | BIT 3
8884 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
8889 /* All variant. OV bit. */
8891 /* We need to get to the OV bit, which is the ORDERED bit. We
8892 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
8893 that's ugly and will make validate_condition_mode die.
8894 So let's just use another pattern. */
8895 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
8897 /* Any variant. EQ bit. */
8901 /* Upper variant. LT bit. */
8905 /* Lower variant. GT bit. */
8910 error ("argument 1 of __builtin_spe_predicate is out of range");
8914 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
8915 emit_move_insn (target
, tmp
);
8920 /* The evsel builtins look like this:
8922 e = __builtin_spe_evsel_OP (a, b, c, d);
8926 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
8927 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
8931 spe_expand_evsel_builtin (enum insn_code icode
, tree exp
, rtx target
)
8934 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8935 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8936 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8937 tree arg3
= CALL_EXPR_ARG (exp
, 3);
8938 rtx op0
= expand_normal (arg0
);
8939 rtx op1
= expand_normal (arg1
);
8940 rtx op2
= expand_normal (arg2
);
8941 rtx op3
= expand_normal (arg3
);
8942 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8943 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8945 gcc_assert (mode0
== mode1
);
8947 if (arg0
== error_mark_node
|| arg1
== error_mark_node
8948 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
8952 || GET_MODE (target
) != mode0
8953 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
8954 target
= gen_reg_rtx (mode0
);
8956 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8957 op0
= copy_to_mode_reg (mode0
, op0
);
8958 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
8959 op1
= copy_to_mode_reg (mode0
, op1
);
8960 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
8961 op2
= copy_to_mode_reg (mode0
, op2
);
8962 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
8963 op3
= copy_to_mode_reg (mode0
, op3
);
8965 /* Generate the compare. */
8966 scratch
= gen_reg_rtx (CCmode
);
8967 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
8972 if (mode0
== V2SImode
)
8973 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
8975 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
8980 /* Expand an expression EXP that calls a built-in function,
8981 with result going to TARGET if that's convenient
8982 (and in mode MODE if that's convenient).
8983 SUBTARGET may be used as the target for computing one of EXP's operands.
8984 IGNORE is nonzero if the value is to be ignored. */
8987 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
8988 enum machine_mode mode ATTRIBUTE_UNUSED
,
8989 int ignore ATTRIBUTE_UNUSED
)
8991 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8992 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8993 const struct builtin_description
*d
;
8998 if (fcode
== RS6000_BUILTIN_RECIP
)
8999 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3
, exp
, target
);
9001 if (fcode
== RS6000_BUILTIN_RECIPF
)
9002 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3
, exp
, target
);
9004 if (fcode
== RS6000_BUILTIN_RSQRTF
)
9005 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2
, exp
, target
);
9007 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_LOAD
9008 || fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
9010 int icode
= (int) CODE_FOR_altivec_lvsr
;
9011 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
9012 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
9016 gcc_assert (TARGET_ALTIVEC
);
9018 arg
= CALL_EXPR_ARG (exp
, 0);
9019 gcc_assert (TREE_CODE (TREE_TYPE (arg
)) == POINTER_TYPE
);
9020 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
9021 addr
= memory_address (mode
, op
);
9022 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
9026 /* For the load case need to negate the address. */
9027 op
= gen_reg_rtx (GET_MODE (addr
));
9028 emit_insn (gen_rtx_SET (VOIDmode
, op
,
9029 gen_rtx_NEG (GET_MODE (addr
), addr
)));
9031 op
= gen_rtx_MEM (mode
, op
);
9034 || GET_MODE (target
) != tmode
9035 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
9036 target
= gen_reg_rtx (tmode
);
9038 /*pat = gen_altivec_lvsr (target, op);*/
9039 pat
= GEN_FCN (icode
) (target
, op
);
9047 /* FIXME: There's got to be a nicer way to handle this case than
9048 constructing a new CALL_EXPR. */
9049 if (fcode
== ALTIVEC_BUILTIN_VCFUX
9050 || fcode
== ALTIVEC_BUILTIN_VCFSX
)
9052 if (call_expr_nargs (exp
) == 1)
9053 exp
= build_call_nary (TREE_TYPE (exp
), CALL_EXPR_FN (exp
),
9054 2, CALL_EXPR_ARG (exp
, 0), integer_zero_node
);
9059 ret
= altivec_expand_builtin (exp
, target
, &success
);
9066 ret
= spe_expand_builtin (exp
, target
, &success
);
9071 if (TARGET_PAIRED_FLOAT
)
9073 ret
= paired_expand_builtin (exp
, target
, &success
);
9079 gcc_assert (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
);
9081 /* Handle simple unary operations. */
9082 d
= (struct builtin_description
*) bdesc_1arg
;
9083 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
9084 if (d
->code
== fcode
)
9085 return rs6000_expand_unop_builtin (d
->icode
, exp
, target
);
9087 /* Handle simple binary operations. */
9088 d
= (struct builtin_description
*) bdesc_2arg
;
9089 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
9090 if (d
->code
== fcode
)
9091 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
9093 /* Handle simple ternary operations. */
9095 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
9096 if (d
->code
== fcode
)
9097 return rs6000_expand_ternop_builtin (d
->icode
, exp
, target
);
9103 build_opaque_vector_type (tree node
, int nunits
)
9105 node
= copy_node (node
);
9106 TYPE_MAIN_VARIANT (node
) = node
;
9107 return build_vector_type (node
, nunits
);
9111 rs6000_init_builtins (void)
9113 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
9114 V2SF_type_node
= build_vector_type (float_type_node
, 2);
9115 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
9116 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
9117 V4SF_type_node
= build_vector_type (float_type_node
, 4);
9118 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
9119 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
9121 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
9122 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
9123 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
9125 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
9126 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
9127 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
9128 opaque_V4SI_type_node
= copy_node (V4SI_type_node
);
9130 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
9131 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
9132 'vector unsigned short'. */
9134 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
9135 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
9136 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
9137 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
9139 long_integer_type_internal_node
= long_integer_type_node
;
9140 long_unsigned_type_internal_node
= long_unsigned_type_node
;
9141 intQI_type_internal_node
= intQI_type_node
;
9142 uintQI_type_internal_node
= unsigned_intQI_type_node
;
9143 intHI_type_internal_node
= intHI_type_node
;
9144 uintHI_type_internal_node
= unsigned_intHI_type_node
;
9145 intSI_type_internal_node
= intSI_type_node
;
9146 uintSI_type_internal_node
= unsigned_intSI_type_node
;
9147 float_type_internal_node
= float_type_node
;
9148 void_type_internal_node
= void_type_node
;
9150 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9151 get_identifier ("__bool char"),
9152 bool_char_type_node
));
9153 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9154 get_identifier ("__bool short"),
9155 bool_short_type_node
));
9156 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9157 get_identifier ("__bool int"),
9158 bool_int_type_node
));
9159 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9160 get_identifier ("__pixel"),
9163 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
9164 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
9165 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
9166 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
9168 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9169 get_identifier ("__vector unsigned char"),
9170 unsigned_V16QI_type_node
));
9171 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9172 get_identifier ("__vector signed char"),
9174 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9175 get_identifier ("__vector __bool char"),
9176 bool_V16QI_type_node
));
9178 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9179 get_identifier ("__vector unsigned short"),
9180 unsigned_V8HI_type_node
));
9181 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9182 get_identifier ("__vector signed short"),
9184 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9185 get_identifier ("__vector __bool short"),
9186 bool_V8HI_type_node
));
9188 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9189 get_identifier ("__vector unsigned int"),
9190 unsigned_V4SI_type_node
));
9191 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9192 get_identifier ("__vector signed int"),
9194 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9195 get_identifier ("__vector __bool int"),
9196 bool_V4SI_type_node
));
9198 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9199 get_identifier ("__vector float"),
9201 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9202 get_identifier ("__vector __pixel"),
9203 pixel_V8HI_type_node
));
9205 if (TARGET_PAIRED_FLOAT
)
9206 paired_init_builtins ();
9208 spe_init_builtins ();
9210 altivec_init_builtins ();
9211 if (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
)
9212 rs6000_common_init_builtins ();
9213 if (TARGET_PPC_GFXOPT
)
9215 tree ftype
= build_function_type_list (float_type_node
,
9219 def_builtin (MASK_PPC_GFXOPT
, "__builtin_recipdivf", ftype
,
9220 RS6000_BUILTIN_RECIPF
);
9222 ftype
= build_function_type_list (float_type_node
,
9225 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrtf", ftype
,
9226 RS6000_BUILTIN_RSQRTF
);
9230 tree ftype
= build_function_type_list (double_type_node
,
9234 def_builtin (MASK_POPCNTB
, "__builtin_recipdiv", ftype
,
9235 RS6000_BUILTIN_RECIP
);
9240 /* AIX libm provides clog as __clog. */
9241 if (built_in_decls
[BUILT_IN_CLOG
])
9242 set_user_assembler_name (built_in_decls
[BUILT_IN_CLOG
], "__clog");
9245 #ifdef SUBTARGET_INIT_BUILTINS
9246 SUBTARGET_INIT_BUILTINS
;
9250 /* Search through a set of builtins and enable the mask bits.
9251 DESC is an array of builtins.
9252 SIZE is the total number of builtins.
9253 START is the builtin enum at which to start.
9254 END is the builtin enum at which to end. */
9256 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
9257 enum rs6000_builtins start
,
9258 enum rs6000_builtins end
)
9262 for (i
= 0; i
< size
; ++i
)
9263 if (desc
[i
].code
== start
)
9269 for (; i
< size
; ++i
)
9271 /* Flip all the bits on. */
9272 desc
[i
].mask
= target_flags
;
9273 if (desc
[i
].code
== end
)
9279 spe_init_builtins (void)
9281 tree endlink
= void_list_node
;
9282 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
9283 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
9284 struct builtin_description
*d
;
9287 tree v2si_ftype_4_v2si
9288 = build_function_type
9289 (opaque_V2SI_type_node
,
9290 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9291 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9292 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9293 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9296 tree v2sf_ftype_4_v2sf
9297 = build_function_type
9298 (opaque_V2SF_type_node
,
9299 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9300 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9301 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9302 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9305 tree int_ftype_int_v2si_v2si
9306 = build_function_type
9308 tree_cons (NULL_TREE
, integer_type_node
,
9309 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9310 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9313 tree int_ftype_int_v2sf_v2sf
9314 = build_function_type
9316 tree_cons (NULL_TREE
, integer_type_node
,
9317 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9318 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9321 tree void_ftype_v2si_puint_int
9322 = build_function_type (void_type_node
,
9323 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9324 tree_cons (NULL_TREE
, puint_type_node
,
9325 tree_cons (NULL_TREE
,
9329 tree void_ftype_v2si_puint_char
9330 = build_function_type (void_type_node
,
9331 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9332 tree_cons (NULL_TREE
, puint_type_node
,
9333 tree_cons (NULL_TREE
,
9337 tree void_ftype_v2si_pv2si_int
9338 = build_function_type (void_type_node
,
9339 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9340 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
9341 tree_cons (NULL_TREE
,
9345 tree void_ftype_v2si_pv2si_char
9346 = build_function_type (void_type_node
,
9347 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9348 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
9349 tree_cons (NULL_TREE
,
9354 = build_function_type (void_type_node
,
9355 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
9358 = build_function_type (integer_type_node
, endlink
);
9360 tree v2si_ftype_pv2si_int
9361 = build_function_type (opaque_V2SI_type_node
,
9362 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
9363 tree_cons (NULL_TREE
, integer_type_node
,
9366 tree v2si_ftype_puint_int
9367 = build_function_type (opaque_V2SI_type_node
,
9368 tree_cons (NULL_TREE
, puint_type_node
,
9369 tree_cons (NULL_TREE
, integer_type_node
,
9372 tree v2si_ftype_pushort_int
9373 = build_function_type (opaque_V2SI_type_node
,
9374 tree_cons (NULL_TREE
, pushort_type_node
,
9375 tree_cons (NULL_TREE
, integer_type_node
,
9378 tree v2si_ftype_signed_char
9379 = build_function_type (opaque_V2SI_type_node
,
9380 tree_cons (NULL_TREE
, signed_char_type_node
,
9383 /* The initialization of the simple binary and unary builtins is
9384 done in rs6000_common_init_builtins, but we have to enable the
9385 mask bits here manually because we have run out of `target_flags'
9386 bits. We really need to redesign this mask business. */
9388 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
9389 ARRAY_SIZE (bdesc_2arg
),
9392 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
9393 ARRAY_SIZE (bdesc_1arg
),
9395 SPE_BUILTIN_EVSUBFUSIAAW
);
9396 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
9397 ARRAY_SIZE (bdesc_spe_predicates
),
9398 SPE_BUILTIN_EVCMPEQ
,
9399 SPE_BUILTIN_EVFSTSTLT
);
9400 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
9401 ARRAY_SIZE (bdesc_spe_evsel
),
9402 SPE_BUILTIN_EVSEL_CMPGTS
,
9403 SPE_BUILTIN_EVSEL_FSTSTEQ
);
9405 (*lang_hooks
.decls
.pushdecl
)
9406 (build_decl (TYPE_DECL
, get_identifier ("__ev64_opaque__"),
9407 opaque_V2SI_type_node
));
9409 /* Initialize irregular SPE builtins. */
9411 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
9412 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
9413 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
9414 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
9415 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
9416 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
9417 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
9418 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
9419 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
9420 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
9421 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
9422 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
9423 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
9424 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
9425 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
9426 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
9427 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
9428 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
9431 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
9432 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
9433 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
9434 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
9435 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
9436 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
9437 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
9438 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
9439 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
9440 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
9441 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
9442 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
9443 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
9444 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
9445 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
9446 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
9447 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
9448 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
9449 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
9450 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
9451 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
9452 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
9455 d
= (struct builtin_description
*) bdesc_spe_predicates
;
9456 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
9460 switch (insn_data
[d
->icode
].operand
[1].mode
)
9463 type
= int_ftype_int_v2si_v2si
;
9466 type
= int_ftype_int_v2sf_v2sf
;
9472 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9475 /* Evsel predicates. */
9476 d
= (struct builtin_description
*) bdesc_spe_evsel
;
9477 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
9481 switch (insn_data
[d
->icode
].operand
[1].mode
)
9484 type
= v2si_ftype_4_v2si
;
9487 type
= v2sf_ftype_4_v2sf
;
9493 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9498 paired_init_builtins (void)
9500 const struct builtin_description
*d
;
9502 tree endlink
= void_list_node
;
9504 tree int_ftype_int_v2sf_v2sf
9505 = build_function_type
9507 tree_cons (NULL_TREE
, integer_type_node
,
9508 tree_cons (NULL_TREE
, V2SF_type_node
,
9509 tree_cons (NULL_TREE
, V2SF_type_node
,
9511 tree pcfloat_type_node
=
9512 build_pointer_type (build_qualified_type
9513 (float_type_node
, TYPE_QUAL_CONST
));
9515 tree v2sf_ftype_long_pcfloat
= build_function_type_list (V2SF_type_node
,
9516 long_integer_type_node
,
9519 tree void_ftype_v2sf_long_pcfloat
=
9520 build_function_type_list (void_type_node
,
9522 long_integer_type_node
,
9527 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat
,
9531 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat
,
9532 PAIRED_BUILTIN_STX
);
9535 d
= bdesc_paired_preds
;
9536 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); ++i
, d
++)
9540 switch (insn_data
[d
->icode
].operand
[1].mode
)
9543 type
= int_ftype_int_v2sf_v2sf
;
9549 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9554 altivec_init_builtins (void)
9556 const struct builtin_description
*d
;
9557 const struct builtin_description_predicates
*dp
;
9561 tree pfloat_type_node
= build_pointer_type (float_type_node
);
9562 tree pint_type_node
= build_pointer_type (integer_type_node
);
9563 tree pshort_type_node
= build_pointer_type (short_integer_type_node
);
9564 tree pchar_type_node
= build_pointer_type (char_type_node
);
9566 tree pvoid_type_node
= build_pointer_type (void_type_node
);
9568 tree pcfloat_type_node
= build_pointer_type (build_qualified_type (float_type_node
, TYPE_QUAL_CONST
));
9569 tree pcint_type_node
= build_pointer_type (build_qualified_type (integer_type_node
, TYPE_QUAL_CONST
));
9570 tree pcshort_type_node
= build_pointer_type (build_qualified_type (short_integer_type_node
, TYPE_QUAL_CONST
));
9571 tree pcchar_type_node
= build_pointer_type (build_qualified_type (char_type_node
, TYPE_QUAL_CONST
));
9573 tree pcvoid_type_node
= build_pointer_type (build_qualified_type (void_type_node
, TYPE_QUAL_CONST
));
9575 tree int_ftype_opaque
9576 = build_function_type_list (integer_type_node
,
9577 opaque_V4SI_type_node
, NULL_TREE
);
9579 tree opaque_ftype_opaque_int
9580 = build_function_type_list (opaque_V4SI_type_node
,
9581 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
9582 tree opaque_ftype_opaque_opaque_int
9583 = build_function_type_list (opaque_V4SI_type_node
,
9584 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
9585 integer_type_node
, NULL_TREE
);
9586 tree int_ftype_int_opaque_opaque
9587 = build_function_type_list (integer_type_node
,
9588 integer_type_node
, opaque_V4SI_type_node
,
9589 opaque_V4SI_type_node
, NULL_TREE
);
9590 tree int_ftype_int_v4si_v4si
9591 = build_function_type_list (integer_type_node
,
9592 integer_type_node
, V4SI_type_node
,
9593 V4SI_type_node
, NULL_TREE
);
9594 tree v4sf_ftype_pcfloat
9595 = build_function_type_list (V4SF_type_node
, pcfloat_type_node
, NULL_TREE
);
9596 tree void_ftype_pfloat_v4sf
9597 = build_function_type_list (void_type_node
,
9598 pfloat_type_node
, V4SF_type_node
, NULL_TREE
);
9599 tree v4si_ftype_pcint
9600 = build_function_type_list (V4SI_type_node
, pcint_type_node
, NULL_TREE
);
9601 tree void_ftype_pint_v4si
9602 = build_function_type_list (void_type_node
,
9603 pint_type_node
, V4SI_type_node
, NULL_TREE
);
9604 tree v8hi_ftype_pcshort
9605 = build_function_type_list (V8HI_type_node
, pcshort_type_node
, NULL_TREE
);
9606 tree void_ftype_pshort_v8hi
9607 = build_function_type_list (void_type_node
,
9608 pshort_type_node
, V8HI_type_node
, NULL_TREE
);
9609 tree v16qi_ftype_pcchar
9610 = build_function_type_list (V16QI_type_node
, pcchar_type_node
, NULL_TREE
);
9611 tree void_ftype_pchar_v16qi
9612 = build_function_type_list (void_type_node
,
9613 pchar_type_node
, V16QI_type_node
, NULL_TREE
);
9614 tree void_ftype_v4si
9615 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
9616 tree v8hi_ftype_void
9617 = build_function_type (V8HI_type_node
, void_list_node
);
9618 tree void_ftype_void
9619 = build_function_type (void_type_node
, void_list_node
);
9621 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
9623 tree opaque_ftype_long_pcvoid
9624 = build_function_type_list (opaque_V4SI_type_node
,
9625 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9626 tree v16qi_ftype_long_pcvoid
9627 = build_function_type_list (V16QI_type_node
,
9628 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9629 tree v8hi_ftype_long_pcvoid
9630 = build_function_type_list (V8HI_type_node
,
9631 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9632 tree v4si_ftype_long_pcvoid
9633 = build_function_type_list (V4SI_type_node
,
9634 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9636 tree void_ftype_opaque_long_pvoid
9637 = build_function_type_list (void_type_node
,
9638 opaque_V4SI_type_node
, long_integer_type_node
,
9639 pvoid_type_node
, NULL_TREE
);
9640 tree void_ftype_v4si_long_pvoid
9641 = build_function_type_list (void_type_node
,
9642 V4SI_type_node
, long_integer_type_node
,
9643 pvoid_type_node
, NULL_TREE
);
9644 tree void_ftype_v16qi_long_pvoid
9645 = build_function_type_list (void_type_node
,
9646 V16QI_type_node
, long_integer_type_node
,
9647 pvoid_type_node
, NULL_TREE
);
9648 tree void_ftype_v8hi_long_pvoid
9649 = build_function_type_list (void_type_node
,
9650 V8HI_type_node
, long_integer_type_node
,
9651 pvoid_type_node
, NULL_TREE
);
9652 tree int_ftype_int_v8hi_v8hi
9653 = build_function_type_list (integer_type_node
,
9654 integer_type_node
, V8HI_type_node
,
9655 V8HI_type_node
, NULL_TREE
);
9656 tree int_ftype_int_v16qi_v16qi
9657 = build_function_type_list (integer_type_node
,
9658 integer_type_node
, V16QI_type_node
,
9659 V16QI_type_node
, NULL_TREE
);
9660 tree int_ftype_int_v4sf_v4sf
9661 = build_function_type_list (integer_type_node
,
9662 integer_type_node
, V4SF_type_node
,
9663 V4SF_type_node
, NULL_TREE
);
9664 tree v4si_ftype_v4si
9665 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
9666 tree v8hi_ftype_v8hi
9667 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
9668 tree v16qi_ftype_v16qi
9669 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
9670 tree v4sf_ftype_v4sf
9671 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
9672 tree void_ftype_pcvoid_int_int
9673 = build_function_type_list (void_type_node
,
9674 pcvoid_type_node
, integer_type_node
,
9675 integer_type_node
, NULL_TREE
);
9677 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat
,
9678 ALTIVEC_BUILTIN_LD_INTERNAL_4sf
);
9679 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf
,
9680 ALTIVEC_BUILTIN_ST_INTERNAL_4sf
);
9681 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint
,
9682 ALTIVEC_BUILTIN_LD_INTERNAL_4si
);
9683 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si
,
9684 ALTIVEC_BUILTIN_ST_INTERNAL_4si
);
9685 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort
,
9686 ALTIVEC_BUILTIN_LD_INTERNAL_8hi
);
9687 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi
,
9688 ALTIVEC_BUILTIN_ST_INTERNAL_8hi
);
9689 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar
,
9690 ALTIVEC_BUILTIN_LD_INTERNAL_16qi
);
9691 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi
,
9692 ALTIVEC_BUILTIN_ST_INTERNAL_16qi
);
9693 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
9694 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
9695 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
9696 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
9697 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
9698 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
9699 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
9700 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
9701 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
9702 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
9703 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
9704 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
9705 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
9706 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
9707 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
9708 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
9709 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
9710 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
9711 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
9712 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
9713 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
9714 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
9715 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
9716 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
9717 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
9718 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
9719 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
9720 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
9721 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
9722 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
9724 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
9726 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
9727 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
9728 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
9729 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
9730 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
9731 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
9732 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
9733 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
9734 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
9735 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
9737 /* Add the DST variants. */
9739 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
9740 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
9742 /* Initialize the predicates. */
9743 dp
= bdesc_altivec_preds
;
9744 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
9746 enum machine_mode mode1
;
9748 bool is_overloaded
= dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9749 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
9754 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
9759 type
= int_ftype_int_opaque_opaque
;
9762 type
= int_ftype_int_v4si_v4si
;
9765 type
= int_ftype_int_v8hi_v8hi
;
9768 type
= int_ftype_int_v16qi_v16qi
;
9771 type
= int_ftype_int_v4sf_v4sf
;
9777 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
9780 /* Initialize the abs* operators. */
9782 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
9784 enum machine_mode mode0
;
9787 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
9792 type
= v4si_ftype_v4si
;
9795 type
= v8hi_ftype_v8hi
;
9798 type
= v16qi_ftype_v16qi
;
9801 type
= v4sf_ftype_v4sf
;
9807 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9814 /* Initialize target builtin that implements
9815 targetm.vectorize.builtin_mask_for_load. */
9817 decl
= add_builtin_function ("__builtin_altivec_mask_for_load",
9818 v16qi_ftype_long_pcvoid
,
9819 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
9820 BUILT_IN_MD
, NULL
, NULL_TREE
);
9821 TREE_READONLY (decl
) = 1;
9822 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
9823 altivec_builtin_mask_for_load
= decl
;
9826 /* Access to the vec_init patterns. */
9827 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
9828 integer_type_node
, integer_type_node
,
9829 integer_type_node
, NULL_TREE
);
9830 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4si", ftype
,
9831 ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
9833 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
9834 short_integer_type_node
,
9835 short_integer_type_node
,
9836 short_integer_type_node
,
9837 short_integer_type_node
,
9838 short_integer_type_node
,
9839 short_integer_type_node
,
9840 short_integer_type_node
, NULL_TREE
);
9841 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v8hi", ftype
,
9842 ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
9844 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
9845 char_type_node
, char_type_node
,
9846 char_type_node
, char_type_node
,
9847 char_type_node
, char_type_node
,
9848 char_type_node
, char_type_node
,
9849 char_type_node
, char_type_node
,
9850 char_type_node
, char_type_node
,
9851 char_type_node
, char_type_node
,
9852 char_type_node
, NULL_TREE
);
9853 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v16qi", ftype
,
9854 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
9856 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
9857 float_type_node
, float_type_node
,
9858 float_type_node
, NULL_TREE
);
9859 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4sf", ftype
,
9860 ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
9862 /* Access to the vec_set patterns. */
9863 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
9865 integer_type_node
, NULL_TREE
);
9866 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4si", ftype
,
9867 ALTIVEC_BUILTIN_VEC_SET_V4SI
);
9869 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
9871 integer_type_node
, NULL_TREE
);
9872 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v8hi", ftype
,
9873 ALTIVEC_BUILTIN_VEC_SET_V8HI
);
9875 ftype
= build_function_type_list (V8HI_type_node
, V16QI_type_node
,
9877 integer_type_node
, NULL_TREE
);
9878 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v16qi", ftype
,
9879 ALTIVEC_BUILTIN_VEC_SET_V16QI
);
9881 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
9883 integer_type_node
, NULL_TREE
);
9884 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4sf", ftype
,
9885 ALTIVEC_BUILTIN_VEC_SET_V4SF
);
9887 /* Access to the vec_extract patterns. */
9888 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
9889 integer_type_node
, NULL_TREE
);
9890 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4si", ftype
,
9891 ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
9893 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
9894 integer_type_node
, NULL_TREE
);
9895 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v8hi", ftype
,
9896 ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
9898 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
9899 integer_type_node
, NULL_TREE
);
9900 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v16qi", ftype
,
9901 ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
9903 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
9904 integer_type_node
, NULL_TREE
);
9905 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4sf", ftype
,
9906 ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
9910 rs6000_common_init_builtins (void)
9912 const struct builtin_description
*d
;
9915 tree v2sf_ftype_v2sf_v2sf_v2sf
9916 = build_function_type_list (V2SF_type_node
,
9917 V2SF_type_node
, V2SF_type_node
,
9918 V2SF_type_node
, NULL_TREE
);
9920 tree v4sf_ftype_v4sf_v4sf_v16qi
9921 = build_function_type_list (V4SF_type_node
,
9922 V4SF_type_node
, V4SF_type_node
,
9923 V16QI_type_node
, NULL_TREE
);
9924 tree v4si_ftype_v4si_v4si_v16qi
9925 = build_function_type_list (V4SI_type_node
,
9926 V4SI_type_node
, V4SI_type_node
,
9927 V16QI_type_node
, NULL_TREE
);
9928 tree v8hi_ftype_v8hi_v8hi_v16qi
9929 = build_function_type_list (V8HI_type_node
,
9930 V8HI_type_node
, V8HI_type_node
,
9931 V16QI_type_node
, NULL_TREE
);
9932 tree v16qi_ftype_v16qi_v16qi_v16qi
9933 = build_function_type_list (V16QI_type_node
,
9934 V16QI_type_node
, V16QI_type_node
,
9935 V16QI_type_node
, NULL_TREE
);
9937 = build_function_type_list (V4SI_type_node
, integer_type_node
, NULL_TREE
);
9939 = build_function_type_list (V8HI_type_node
, integer_type_node
, NULL_TREE
);
9940 tree v16qi_ftype_int
9941 = build_function_type_list (V16QI_type_node
, integer_type_node
, NULL_TREE
);
9942 tree v8hi_ftype_v16qi
9943 = build_function_type_list (V8HI_type_node
, V16QI_type_node
, NULL_TREE
);
9944 tree v4sf_ftype_v4sf
9945 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
9947 tree v2si_ftype_v2si_v2si
9948 = build_function_type_list (opaque_V2SI_type_node
,
9949 opaque_V2SI_type_node
,
9950 opaque_V2SI_type_node
, NULL_TREE
);
9952 tree v2sf_ftype_v2sf_v2sf_spe
9953 = build_function_type_list (opaque_V2SF_type_node
,
9954 opaque_V2SF_type_node
,
9955 opaque_V2SF_type_node
, NULL_TREE
);
9957 tree v2sf_ftype_v2sf_v2sf
9958 = build_function_type_list (V2SF_type_node
,
9960 V2SF_type_node
, NULL_TREE
);
9963 tree v2si_ftype_int_int
9964 = build_function_type_list (opaque_V2SI_type_node
,
9965 integer_type_node
, integer_type_node
,
9968 tree opaque_ftype_opaque
9969 = build_function_type_list (opaque_V4SI_type_node
,
9970 opaque_V4SI_type_node
, NULL_TREE
);
9972 tree v2si_ftype_v2si
9973 = build_function_type_list (opaque_V2SI_type_node
,
9974 opaque_V2SI_type_node
, NULL_TREE
);
9976 tree v2sf_ftype_v2sf_spe
9977 = build_function_type_list (opaque_V2SF_type_node
,
9978 opaque_V2SF_type_node
, NULL_TREE
);
9980 tree v2sf_ftype_v2sf
9981 = build_function_type_list (V2SF_type_node
,
9982 V2SF_type_node
, NULL_TREE
);
9984 tree v2sf_ftype_v2si
9985 = build_function_type_list (opaque_V2SF_type_node
,
9986 opaque_V2SI_type_node
, NULL_TREE
);
9988 tree v2si_ftype_v2sf
9989 = build_function_type_list (opaque_V2SI_type_node
,
9990 opaque_V2SF_type_node
, NULL_TREE
);
9992 tree v2si_ftype_v2si_char
9993 = build_function_type_list (opaque_V2SI_type_node
,
9994 opaque_V2SI_type_node
,
9995 char_type_node
, NULL_TREE
);
9997 tree v2si_ftype_int_char
9998 = build_function_type_list (opaque_V2SI_type_node
,
9999 integer_type_node
, char_type_node
, NULL_TREE
);
10001 tree v2si_ftype_char
10002 = build_function_type_list (opaque_V2SI_type_node
,
10003 char_type_node
, NULL_TREE
);
10005 tree int_ftype_int_int
10006 = build_function_type_list (integer_type_node
,
10007 integer_type_node
, integer_type_node
,
10010 tree opaque_ftype_opaque_opaque
10011 = build_function_type_list (opaque_V4SI_type_node
,
10012 opaque_V4SI_type_node
, opaque_V4SI_type_node
, NULL_TREE
);
10013 tree v4si_ftype_v4si_v4si
10014 = build_function_type_list (V4SI_type_node
,
10015 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
10016 tree v4sf_ftype_v4si_int
10017 = build_function_type_list (V4SF_type_node
,
10018 V4SI_type_node
, integer_type_node
, NULL_TREE
);
10019 tree v4si_ftype_v4sf_int
10020 = build_function_type_list (V4SI_type_node
,
10021 V4SF_type_node
, integer_type_node
, NULL_TREE
);
10022 tree v4si_ftype_v4si_int
10023 = build_function_type_list (V4SI_type_node
,
10024 V4SI_type_node
, integer_type_node
, NULL_TREE
);
10025 tree v8hi_ftype_v8hi_int
10026 = build_function_type_list (V8HI_type_node
,
10027 V8HI_type_node
, integer_type_node
, NULL_TREE
);
10028 tree v16qi_ftype_v16qi_int
10029 = build_function_type_list (V16QI_type_node
,
10030 V16QI_type_node
, integer_type_node
, NULL_TREE
);
10031 tree v16qi_ftype_v16qi_v16qi_int
10032 = build_function_type_list (V16QI_type_node
,
10033 V16QI_type_node
, V16QI_type_node
,
10034 integer_type_node
, NULL_TREE
);
10035 tree v8hi_ftype_v8hi_v8hi_int
10036 = build_function_type_list (V8HI_type_node
,
10037 V8HI_type_node
, V8HI_type_node
,
10038 integer_type_node
, NULL_TREE
);
10039 tree v4si_ftype_v4si_v4si_int
10040 = build_function_type_list (V4SI_type_node
,
10041 V4SI_type_node
, V4SI_type_node
,
10042 integer_type_node
, NULL_TREE
);
10043 tree v4sf_ftype_v4sf_v4sf_int
10044 = build_function_type_list (V4SF_type_node
,
10045 V4SF_type_node
, V4SF_type_node
,
10046 integer_type_node
, NULL_TREE
);
10047 tree v4sf_ftype_v4sf_v4sf
10048 = build_function_type_list (V4SF_type_node
,
10049 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10050 tree opaque_ftype_opaque_opaque_opaque
10051 = build_function_type_list (opaque_V4SI_type_node
,
10052 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
10053 opaque_V4SI_type_node
, NULL_TREE
);
10054 tree v4sf_ftype_v4sf_v4sf_v4si
10055 = build_function_type_list (V4SF_type_node
,
10056 V4SF_type_node
, V4SF_type_node
,
10057 V4SI_type_node
, NULL_TREE
);
10058 tree v4sf_ftype_v4sf_v4sf_v4sf
10059 = build_function_type_list (V4SF_type_node
,
10060 V4SF_type_node
, V4SF_type_node
,
10061 V4SF_type_node
, NULL_TREE
);
10062 tree v4si_ftype_v4si_v4si_v4si
10063 = build_function_type_list (V4SI_type_node
,
10064 V4SI_type_node
, V4SI_type_node
,
10065 V4SI_type_node
, NULL_TREE
);
10066 tree v8hi_ftype_v8hi_v8hi
10067 = build_function_type_list (V8HI_type_node
,
10068 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10069 tree v8hi_ftype_v8hi_v8hi_v8hi
10070 = build_function_type_list (V8HI_type_node
,
10071 V8HI_type_node
, V8HI_type_node
,
10072 V8HI_type_node
, NULL_TREE
);
10073 tree v4si_ftype_v8hi_v8hi_v4si
10074 = build_function_type_list (V4SI_type_node
,
10075 V8HI_type_node
, V8HI_type_node
,
10076 V4SI_type_node
, NULL_TREE
);
10077 tree v4si_ftype_v16qi_v16qi_v4si
10078 = build_function_type_list (V4SI_type_node
,
10079 V16QI_type_node
, V16QI_type_node
,
10080 V4SI_type_node
, NULL_TREE
);
10081 tree v16qi_ftype_v16qi_v16qi
10082 = build_function_type_list (V16QI_type_node
,
10083 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10084 tree v4si_ftype_v4sf_v4sf
10085 = build_function_type_list (V4SI_type_node
,
10086 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10087 tree v8hi_ftype_v16qi_v16qi
10088 = build_function_type_list (V8HI_type_node
,
10089 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10090 tree v4si_ftype_v8hi_v8hi
10091 = build_function_type_list (V4SI_type_node
,
10092 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10093 tree v8hi_ftype_v4si_v4si
10094 = build_function_type_list (V8HI_type_node
,
10095 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
10096 tree v16qi_ftype_v8hi_v8hi
10097 = build_function_type_list (V16QI_type_node
,
10098 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10099 tree v4si_ftype_v16qi_v4si
10100 = build_function_type_list (V4SI_type_node
,
10101 V16QI_type_node
, V4SI_type_node
, NULL_TREE
);
10102 tree v4si_ftype_v16qi_v16qi
10103 = build_function_type_list (V4SI_type_node
,
10104 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10105 tree v4si_ftype_v8hi_v4si
10106 = build_function_type_list (V4SI_type_node
,
10107 V8HI_type_node
, V4SI_type_node
, NULL_TREE
);
10108 tree v4si_ftype_v8hi
10109 = build_function_type_list (V4SI_type_node
, V8HI_type_node
, NULL_TREE
);
10110 tree int_ftype_v4si_v4si
10111 = build_function_type_list (integer_type_node
,
10112 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
10113 tree int_ftype_v4sf_v4sf
10114 = build_function_type_list (integer_type_node
,
10115 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10116 tree int_ftype_v16qi_v16qi
10117 = build_function_type_list (integer_type_node
,
10118 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10119 tree int_ftype_v8hi_v8hi
10120 = build_function_type_list (integer_type_node
,
10121 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10123 /* Add the simple ternary operators. */
10125 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
10127 enum machine_mode mode0
, mode1
, mode2
, mode3
;
10129 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10130 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10141 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
10144 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10145 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10146 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
10147 mode3
= insn_data
[d
->icode
].operand
[3].mode
;
10150 /* When all four are of the same mode. */
10151 if (mode0
== mode1
&& mode1
== mode2
&& mode2
== mode3
)
10156 type
= opaque_ftype_opaque_opaque_opaque
;
10159 type
= v4si_ftype_v4si_v4si_v4si
;
10162 type
= v4sf_ftype_v4sf_v4sf_v4sf
;
10165 type
= v8hi_ftype_v8hi_v8hi_v8hi
;
10168 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
10171 type
= v2sf_ftype_v2sf_v2sf_v2sf
;
10174 gcc_unreachable ();
10177 else if (mode0
== mode1
&& mode1
== mode2
&& mode3
== V16QImode
)
10182 type
= v4si_ftype_v4si_v4si_v16qi
;
10185 type
= v4sf_ftype_v4sf_v4sf_v16qi
;
10188 type
= v8hi_ftype_v8hi_v8hi_v16qi
;
10191 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
10194 gcc_unreachable ();
10197 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
10198 && mode3
== V4SImode
)
10199 type
= v4si_ftype_v16qi_v16qi_v4si
;
10200 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
10201 && mode3
== V4SImode
)
10202 type
= v4si_ftype_v8hi_v8hi_v4si
;
10203 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
10204 && mode3
== V4SImode
)
10205 type
= v4sf_ftype_v4sf_v4sf_v4si
;
10207 /* vchar, vchar, vchar, 4-bit literal. */
10208 else if (mode0
== V16QImode
&& mode1
== mode0
&& mode2
== mode0
10209 && mode3
== QImode
)
10210 type
= v16qi_ftype_v16qi_v16qi_int
;
10212 /* vshort, vshort, vshort, 4-bit literal. */
10213 else if (mode0
== V8HImode
&& mode1
== mode0
&& mode2
== mode0
10214 && mode3
== QImode
)
10215 type
= v8hi_ftype_v8hi_v8hi_int
;
10217 /* vint, vint, vint, 4-bit literal. */
10218 else if (mode0
== V4SImode
&& mode1
== mode0
&& mode2
== mode0
10219 && mode3
== QImode
)
10220 type
= v4si_ftype_v4si_v4si_int
;
10222 /* vfloat, vfloat, vfloat, 4-bit literal. */
10223 else if (mode0
== V4SFmode
&& mode1
== mode0
&& mode2
== mode0
10224 && mode3
== QImode
)
10225 type
= v4sf_ftype_v4sf_v4sf_int
;
10228 gcc_unreachable ();
10230 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10233 /* Add the simple binary operators. */
10234 d
= (struct builtin_description
*) bdesc_2arg
;
10235 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
10237 enum machine_mode mode0
, mode1
, mode2
;
10239 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10240 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10250 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
10253 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10254 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10255 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
10258 /* When all three operands are of the same mode. */
10259 if (mode0
== mode1
&& mode1
== mode2
)
10264 type
= opaque_ftype_opaque_opaque
;
10267 type
= v4sf_ftype_v4sf_v4sf
;
10270 type
= v4si_ftype_v4si_v4si
;
10273 type
= v16qi_ftype_v16qi_v16qi
;
10276 type
= v8hi_ftype_v8hi_v8hi
;
10279 type
= v2si_ftype_v2si_v2si
;
10282 if (TARGET_PAIRED_FLOAT
)
10283 type
= v2sf_ftype_v2sf_v2sf
;
10285 type
= v2sf_ftype_v2sf_v2sf_spe
;
10288 type
= int_ftype_int_int
;
10291 gcc_unreachable ();
10295 /* A few other combos we really don't want to do manually. */
10297 /* vint, vfloat, vfloat. */
10298 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
)
10299 type
= v4si_ftype_v4sf_v4sf
;
10301 /* vshort, vchar, vchar. */
10302 else if (mode0
== V8HImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
10303 type
= v8hi_ftype_v16qi_v16qi
;
10305 /* vint, vshort, vshort. */
10306 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
10307 type
= v4si_ftype_v8hi_v8hi
;
10309 /* vshort, vint, vint. */
10310 else if (mode0
== V8HImode
&& mode1
== V4SImode
&& mode2
== V4SImode
)
10311 type
= v8hi_ftype_v4si_v4si
;
10313 /* vchar, vshort, vshort. */
10314 else if (mode0
== V16QImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
10315 type
= v16qi_ftype_v8hi_v8hi
;
10317 /* vint, vchar, vint. */
10318 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V4SImode
)
10319 type
= v4si_ftype_v16qi_v4si
;
10321 /* vint, vchar, vchar. */
10322 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
10323 type
= v4si_ftype_v16qi_v16qi
;
10325 /* vint, vshort, vint. */
10326 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V4SImode
)
10327 type
= v4si_ftype_v8hi_v4si
;
10329 /* vint, vint, 5-bit literal. */
10330 else if (mode0
== V4SImode
&& mode1
== V4SImode
&& mode2
== QImode
)
10331 type
= v4si_ftype_v4si_int
;
10333 /* vshort, vshort, 5-bit literal. */
10334 else if (mode0
== V8HImode
&& mode1
== V8HImode
&& mode2
== QImode
)
10335 type
= v8hi_ftype_v8hi_int
;
10337 /* vchar, vchar, 5-bit literal. */
10338 else if (mode0
== V16QImode
&& mode1
== V16QImode
&& mode2
== QImode
)
10339 type
= v16qi_ftype_v16qi_int
;
10341 /* vfloat, vint, 5-bit literal. */
10342 else if (mode0
== V4SFmode
&& mode1
== V4SImode
&& mode2
== QImode
)
10343 type
= v4sf_ftype_v4si_int
;
10345 /* vint, vfloat, 5-bit literal. */
10346 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== QImode
)
10347 type
= v4si_ftype_v4sf_int
;
10349 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== SImode
)
10350 type
= v2si_ftype_int_int
;
10352 else if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
10353 type
= v2si_ftype_v2si_char
;
10355 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== QImode
)
10356 type
= v2si_ftype_int_char
;
10361 gcc_assert (mode0
== SImode
);
10365 type
= int_ftype_v4si_v4si
;
10368 type
= int_ftype_v4sf_v4sf
;
10371 type
= int_ftype_v16qi_v16qi
;
10374 type
= int_ftype_v8hi_v8hi
;
10377 gcc_unreachable ();
10381 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10384 /* Add the simple unary operators. */
10385 d
= (struct builtin_description
*) bdesc_1arg
;
10386 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
10388 enum machine_mode mode0
, mode1
;
10390 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10391 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10400 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
10403 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10404 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10407 if (mode0
== V4SImode
&& mode1
== QImode
)
10408 type
= v4si_ftype_int
;
10409 else if (mode0
== V8HImode
&& mode1
== QImode
)
10410 type
= v8hi_ftype_int
;
10411 else if (mode0
== V16QImode
&& mode1
== QImode
)
10412 type
= v16qi_ftype_int
;
10413 else if (mode0
== VOIDmode
&& mode1
== VOIDmode
)
10414 type
= opaque_ftype_opaque
;
10415 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
)
10416 type
= v4sf_ftype_v4sf
;
10417 else if (mode0
== V8HImode
&& mode1
== V16QImode
)
10418 type
= v8hi_ftype_v16qi
;
10419 else if (mode0
== V4SImode
&& mode1
== V8HImode
)
10420 type
= v4si_ftype_v8hi
;
10421 else if (mode0
== V2SImode
&& mode1
== V2SImode
)
10422 type
= v2si_ftype_v2si
;
10423 else if (mode0
== V2SFmode
&& mode1
== V2SFmode
)
10425 if (TARGET_PAIRED_FLOAT
)
10426 type
= v2sf_ftype_v2sf
;
10428 type
= v2sf_ftype_v2sf_spe
;
10430 else if (mode0
== V2SFmode
&& mode1
== V2SImode
)
10431 type
= v2sf_ftype_v2si
;
10432 else if (mode0
== V2SImode
&& mode1
== V2SFmode
)
10433 type
= v2si_ftype_v2sf
;
10434 else if (mode0
== V2SImode
&& mode1
== QImode
)
10435 type
= v2si_ftype_char
;
10437 gcc_unreachable ();
10439 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10444 rs6000_init_libfuncs (void)
10446 if (DEFAULT_ABI
!= ABI_V4
&& TARGET_XCOFF
10447 && !TARGET_POWER2
&& !TARGET_POWERPC
)
10449 /* AIX library routines for float->int conversion. */
10450 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
10451 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
10452 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
10453 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
10456 if (!TARGET_IEEEQUAD
)
10457 /* AIX/Darwin/64-bit Linux quad floating point routines. */
10458 if (!TARGET_XL_COMPAT
)
10460 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
10461 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
10462 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
10463 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
10465 if (!(TARGET_HARD_FLOAT
&& (TARGET_FPRS
|| TARGET_E500_DOUBLE
)))
10467 set_optab_libfunc (neg_optab
, TFmode
, "__gcc_qneg");
10468 set_optab_libfunc (eq_optab
, TFmode
, "__gcc_qeq");
10469 set_optab_libfunc (ne_optab
, TFmode
, "__gcc_qne");
10470 set_optab_libfunc (gt_optab
, TFmode
, "__gcc_qgt");
10471 set_optab_libfunc (ge_optab
, TFmode
, "__gcc_qge");
10472 set_optab_libfunc (lt_optab
, TFmode
, "__gcc_qlt");
10473 set_optab_libfunc (le_optab
, TFmode
, "__gcc_qle");
10475 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "__gcc_stoq");
10476 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "__gcc_dtoq");
10477 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "__gcc_qtos");
10478 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "__gcc_qtod");
10479 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "__gcc_qtoi");
10480 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "__gcc_qtou");
10481 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "__gcc_itoq");
10482 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "__gcc_utoq");
10485 if (!(TARGET_HARD_FLOAT
&& TARGET_FPRS
))
10486 set_optab_libfunc (unord_optab
, TFmode
, "__gcc_qunord");
10490 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
10491 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
10492 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
10493 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
10497 /* 32-bit SVR4 quad floating point routines. */
10499 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
10500 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
10501 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
10502 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
10503 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
10504 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
10505 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
10507 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
10508 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
10509 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
10510 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
10511 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
10512 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
10514 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
10515 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
10516 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
10517 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
10518 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
10519 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
10520 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
10521 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "_q_utoq");
10526 /* Expand a block clear operation, and return 1 if successful. Return 0
10527 if we should let the compiler generate normal code.
10529 operands[0] is the destination
10530 operands[1] is the length
10531 operands[3] is the alignment */
10534 expand_block_clear (rtx operands
[])
10536 rtx orig_dest
= operands
[0];
10537 rtx bytes_rtx
= operands
[1];
10538 rtx align_rtx
= operands
[3];
10539 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
10540 HOST_WIDE_INT align
;
10541 HOST_WIDE_INT bytes
;
10546 /* If this is not a fixed size move, just call memcpy */
10550 /* This must be a fixed size alignment */
10551 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
10552 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
10554 /* Anything to clear? */
10555 bytes
= INTVAL (bytes_rtx
);
10559 /* Use the builtin memset after a point, to avoid huge code bloat.
10560 When optimize_size, avoid any significant code bloat; calling
10561 memset is about 4 instructions, so allow for one instruction to
10562 load zero and three to do clearing. */
10563 if (TARGET_ALTIVEC
&& align
>= 128)
10565 else if (TARGET_POWERPC64
&& align
>= 32)
10567 else if (TARGET_SPE
&& align
>= 64)
10572 if (optimize_size
&& bytes
> 3 * clear_step
)
10574 if (! optimize_size
&& bytes
> 8 * clear_step
)
10577 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
10579 enum machine_mode mode
= BLKmode
;
10582 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
10587 else if (bytes
>= 8 && TARGET_SPE
&& align
>= 64)
10592 else if (bytes
>= 8 && TARGET_POWERPC64
10593 /* 64-bit loads and stores require word-aligned
10595 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
10600 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
10601 { /* move 4 bytes */
10605 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
10606 { /* move 2 bytes */
10610 else /* move 1 byte at a time */
10616 dest
= adjust_address (orig_dest
, mode
, offset
);
10618 emit_move_insn (dest
, CONST0_RTX (mode
));
10625 /* Expand a block move operation, and return 1 if successful. Return 0
10626 if we should let the compiler generate normal code.
10628 operands[0] is the destination
10629 operands[1] is the source
10630 operands[2] is the length
10631 operands[3] is the alignment */
10633 #define MAX_MOVE_REG 4
10636 expand_block_move (rtx operands
[])
10638 rtx orig_dest
= operands
[0];
10639 rtx orig_src
= operands
[1];
10640 rtx bytes_rtx
= operands
[2];
10641 rtx align_rtx
= operands
[3];
10642 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
10647 rtx stores
[MAX_MOVE_REG
];
10650 /* If this is not a fixed size move, just call memcpy */
10654 /* This must be a fixed size alignment */
10655 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
10656 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
10658 /* Anything to move? */
10659 bytes
= INTVAL (bytes_rtx
);
10663 /* store_one_arg depends on expand_block_move to handle at least the size of
10664 reg_parm_stack_space. */
10665 if (bytes
> (TARGET_POWERPC64
? 64 : 32))
10668 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
10671 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
10672 rtx (*mov
) (rtx
, rtx
);
10674 enum machine_mode mode
= BLKmode
;
10677 /* Altivec first, since it will be faster than a string move
10678 when it applies, and usually not significantly larger. */
10679 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
10683 gen_func
.mov
= gen_movv4si
;
10685 else if (TARGET_SPE
&& bytes
>= 8 && align
>= 64)
10689 gen_func
.mov
= gen_movv2si
;
10691 else if (TARGET_STRING
10692 && bytes
> 24 /* move up to 32 bytes at a time */
10698 && ! fixed_regs
[10]
10699 && ! fixed_regs
[11]
10700 && ! fixed_regs
[12])
10702 move_bytes
= (bytes
> 32) ? 32 : bytes
;
10703 gen_func
.movmemsi
= gen_movmemsi_8reg
;
10705 else if (TARGET_STRING
10706 && bytes
> 16 /* move up to 24 bytes at a time */
10712 && ! fixed_regs
[10])
10714 move_bytes
= (bytes
> 24) ? 24 : bytes
;
10715 gen_func
.movmemsi
= gen_movmemsi_6reg
;
10717 else if (TARGET_STRING
10718 && bytes
> 8 /* move up to 16 bytes at a time */
10722 && ! fixed_regs
[8])
10724 move_bytes
= (bytes
> 16) ? 16 : bytes
;
10725 gen_func
.movmemsi
= gen_movmemsi_4reg
;
10727 else if (bytes
>= 8 && TARGET_POWERPC64
10728 /* 64-bit loads and stores require word-aligned
10730 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
10734 gen_func
.mov
= gen_movdi
;
10736 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
10737 { /* move up to 8 bytes at a time */
10738 move_bytes
= (bytes
> 8) ? 8 : bytes
;
10739 gen_func
.movmemsi
= gen_movmemsi_2reg
;
10741 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
10742 { /* move 4 bytes */
10745 gen_func
.mov
= gen_movsi
;
10747 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
10748 { /* move 2 bytes */
10751 gen_func
.mov
= gen_movhi
;
10753 else if (TARGET_STRING
&& bytes
> 1)
10754 { /* move up to 4 bytes at a time */
10755 move_bytes
= (bytes
> 4) ? 4 : bytes
;
10756 gen_func
.movmemsi
= gen_movmemsi_1reg
;
10758 else /* move 1 byte at a time */
10762 gen_func
.mov
= gen_movqi
;
10765 src
= adjust_address (orig_src
, mode
, offset
);
10766 dest
= adjust_address (orig_dest
, mode
, offset
);
10768 if (mode
!= BLKmode
)
10770 rtx tmp_reg
= gen_reg_rtx (mode
);
10772 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
10773 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
10776 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
10779 for (i
= 0; i
< num_reg
; i
++)
10780 emit_insn (stores
[i
]);
10784 if (mode
== BLKmode
)
10786 /* Move the address into scratch registers. The movmemsi
10787 patterns require zero offset. */
10788 if (!REG_P (XEXP (src
, 0)))
10790 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
10791 src
= replace_equiv_address (src
, src_reg
);
10793 set_mem_size (src
, GEN_INT (move_bytes
));
10795 if (!REG_P (XEXP (dest
, 0)))
10797 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
10798 dest
= replace_equiv_address (dest
, dest_reg
);
10800 set_mem_size (dest
, GEN_INT (move_bytes
));
10802 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
10803 GEN_INT (move_bytes
& 31),
10812 /* Return a string to perform a load_multiple operation.
10813 operands[0] is the vector.
10814 operands[1] is the source address.
10815 operands[2] is the first destination register. */
10818 rs6000_output_load_multiple (rtx operands
[3])
10820 /* We have to handle the case where the pseudo used to contain the address
10821 is assigned to one of the output registers. */
10823 int words
= XVECLEN (operands
[0], 0);
10826 if (XVECLEN (operands
[0], 0) == 1)
10827 return "{l|lwz} %2,0(%1)";
10829 for (i
= 0; i
< words
; i
++)
10830 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
10831 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
10835 xop
[0] = GEN_INT (4 * (words
-1));
10836 xop
[1] = operands
[1];
10837 xop
[2] = operands
[2];
10838 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
10843 xop
[0] = GEN_INT (4 * (words
-1));
10844 xop
[1] = operands
[1];
10845 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
10846 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
);
10851 for (j
= 0; j
< words
; j
++)
10854 xop
[0] = GEN_INT (j
* 4);
10855 xop
[1] = operands
[1];
10856 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
10857 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
10859 xop
[0] = GEN_INT (i
* 4);
10860 xop
[1] = operands
[1];
10861 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
10866 return "{lsi|lswi} %2,%1,%N0";
10870 /* A validation routine: say whether CODE, a condition code, and MODE
10871 match. The other alternatives either don't make sense or should
10872 never be generated. */
10875 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
10877 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
10878 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
10879 && GET_MODE_CLASS (mode
) == MODE_CC
);
10881 /* These don't make sense. */
10882 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
10883 || mode
!= CCUNSmode
);
10885 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
10886 || mode
== CCUNSmode
);
10888 gcc_assert (mode
== CCFPmode
10889 || (code
!= ORDERED
&& code
!= UNORDERED
10890 && code
!= UNEQ
&& code
!= LTGT
10891 && code
!= UNGT
&& code
!= UNLT
10892 && code
!= UNGE
&& code
!= UNLE
));
10894 /* These should never be generated except for
10895 flag_finite_math_only. */
10896 gcc_assert (mode
!= CCFPmode
10897 || flag_finite_math_only
10898 || (code
!= LE
&& code
!= GE
10899 && code
!= UNEQ
&& code
!= LTGT
10900 && code
!= UNGT
&& code
!= UNLT
));
10902 /* These are invalid; the information is not there. */
10903 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
10907 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
10908 mask required to convert the result of a rotate insn into a shift
10909 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
10912 includes_lshift_p (rtx shiftop
, rtx andop
)
10914 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
10916 shift_mask
<<= INTVAL (shiftop
);
10918 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
10921 /* Similar, but for right shift. */
10924 includes_rshift_p (rtx shiftop
, rtx andop
)
10926 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
10928 shift_mask
>>= INTVAL (shiftop
);
10930 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
10933 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
10934 to perform a left shift. It must have exactly SHIFTOP least
10935 significant 0's, then one or more 1's, then zero or more 0's. */
10938 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
10940 if (GET_CODE (andop
) == CONST_INT
)
10942 HOST_WIDE_INT c
, lsb
, shift_mask
;
10944 c
= INTVAL (andop
);
10945 if (c
== 0 || c
== ~0)
10949 shift_mask
<<= INTVAL (shiftop
);
10951 /* Find the least significant one bit. */
10954 /* It must coincide with the LSB of the shift mask. */
10955 if (-lsb
!= shift_mask
)
10958 /* Invert to look for the next transition (if any). */
10961 /* Remove the low group of ones (originally low group of zeros). */
10964 /* Again find the lsb, and check we have all 1's above. */
10968 else if (GET_CODE (andop
) == CONST_DOUBLE
10969 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
10971 HOST_WIDE_INT low
, high
, lsb
;
10972 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
10974 low
= CONST_DOUBLE_LOW (andop
);
10975 if (HOST_BITS_PER_WIDE_INT
< 64)
10976 high
= CONST_DOUBLE_HIGH (andop
);
10978 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
10979 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
10982 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
10984 shift_mask_high
= ~0;
10985 if (INTVAL (shiftop
) > 32)
10986 shift_mask_high
<<= INTVAL (shiftop
) - 32;
10988 lsb
= high
& -high
;
10990 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
10996 lsb
= high
& -high
;
10997 return high
== -lsb
;
11000 shift_mask_low
= ~0;
11001 shift_mask_low
<<= INTVAL (shiftop
);
11005 if (-lsb
!= shift_mask_low
)
11008 if (HOST_BITS_PER_WIDE_INT
< 64)
11013 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
11015 lsb
= high
& -high
;
11016 return high
== -lsb
;
11020 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
11026 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
11027 to perform a left shift. It must have SHIFTOP or more least
11028 significant 0's, with the remainder of the word 1's. */
11031 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
11033 if (GET_CODE (andop
) == CONST_INT
)
11035 HOST_WIDE_INT c
, lsb
, shift_mask
;
11038 shift_mask
<<= INTVAL (shiftop
);
11039 c
= INTVAL (andop
);
11041 /* Find the least significant one bit. */
11044 /* It must be covered by the shift mask.
11045 This test also rejects c == 0. */
11046 if ((lsb
& shift_mask
) == 0)
11049 /* Check we have all 1's above the transition, and reject all 1's. */
11050 return c
== -lsb
&& lsb
!= 1;
11052 else if (GET_CODE (andop
) == CONST_DOUBLE
11053 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
11055 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
11057 low
= CONST_DOUBLE_LOW (andop
);
11059 if (HOST_BITS_PER_WIDE_INT
< 64)
11061 HOST_WIDE_INT high
, shift_mask_high
;
11063 high
= CONST_DOUBLE_HIGH (andop
);
11067 shift_mask_high
= ~0;
11068 if (INTVAL (shiftop
) > 32)
11069 shift_mask_high
<<= INTVAL (shiftop
) - 32;
11071 lsb
= high
& -high
;
11073 if ((lsb
& shift_mask_high
) == 0)
11076 return high
== -lsb
;
11082 shift_mask_low
= ~0;
11083 shift_mask_low
<<= INTVAL (shiftop
);
11087 if ((lsb
& shift_mask_low
) == 0)
11090 return low
== -lsb
&& lsb
!= 1;
11096 /* Return 1 if operands will generate a valid arguments to rlwimi
11097 instruction for insert with right shift in 64-bit mode. The mask may
11098 not start on the first bit or stop on the last bit because wrap-around
11099 effects of instruction do not correspond to semantics of RTL insn. */
11102 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
11104 if (INTVAL (startop
) > 32
11105 && INTVAL (startop
) < 64
11106 && INTVAL (sizeop
) > 1
11107 && INTVAL (sizeop
) + INTVAL (startop
) < 64
11108 && INTVAL (shiftop
) > 0
11109 && INTVAL (sizeop
) + INTVAL (shiftop
) < 32
11110 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
11116 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
11117 for lfq and stfq insns iff the registers are hard registers. */
11120 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
11122 /* We might have been passed a SUBREG. */
11123 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
11126 /* We might have been passed non floating point registers. */
11127 if (!FP_REGNO_P (REGNO (reg1
))
11128 || !FP_REGNO_P (REGNO (reg2
)))
11131 return (REGNO (reg1
) == REGNO (reg2
) - 1);
11134 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
11135 addr1 and addr2 must be in consecutive memory locations
11136 (addr2 == addr1 + 8). */
11139 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
11142 unsigned int reg1
, reg2
;
11143 int offset1
, offset2
;
11145 /* The mems cannot be volatile. */
11146 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
11149 addr1
= XEXP (mem1
, 0);
11150 addr2
= XEXP (mem2
, 0);
11152 /* Extract an offset (if used) from the first addr. */
11153 if (GET_CODE (addr1
) == PLUS
)
11155 /* If not a REG, return zero. */
11156 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
11160 reg1
= REGNO (XEXP (addr1
, 0));
11161 /* The offset must be constant! */
11162 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
11164 offset1
= INTVAL (XEXP (addr1
, 1));
11167 else if (GET_CODE (addr1
) != REG
)
11171 reg1
= REGNO (addr1
);
11172 /* This was a simple (mem (reg)) expression. Offset is 0. */
11176 /* And now for the second addr. */
11177 if (GET_CODE (addr2
) == PLUS
)
11179 /* If not a REG, return zero. */
11180 if (GET_CODE (XEXP (addr2
, 0)) != REG
)
11184 reg2
= REGNO (XEXP (addr2
, 0));
11185 /* The offset must be constant. */
11186 if (GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
11188 offset2
= INTVAL (XEXP (addr2
, 1));
11191 else if (GET_CODE (addr2
) != REG
)
11195 reg2
= REGNO (addr2
);
11196 /* This was a simple (mem (reg)) expression. Offset is 0. */
11200 /* Both of these must have the same base register. */
11204 /* The offset for the second addr must be 8 more than the first addr. */
11205 if (offset2
!= offset1
+ 8)
11208 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
11215 rs6000_secondary_memory_needed_rtx (enum machine_mode mode
)
11217 static bool eliminated
= false;
11218 if (mode
!= SDmode
)
11219 return assign_stack_local (mode
, GET_MODE_SIZE (mode
), 0);
11222 rtx mem
= cfun
->machine
->sdmode_stack_slot
;
11223 gcc_assert (mem
!= NULL_RTX
);
11227 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
11228 cfun
->machine
->sdmode_stack_slot
= mem
;
11236 rs6000_check_sdmode (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
11238 /* Don't walk into types. */
11239 if (*tp
== NULL_TREE
|| *tp
== error_mark_node
|| TYPE_P (*tp
))
11241 *walk_subtrees
= 0;
11245 switch (TREE_CODE (*tp
))
11253 case ALIGN_INDIRECT_REF
:
11254 case MISALIGNED_INDIRECT_REF
:
11255 case VIEW_CONVERT_EXPR
:
11256 if (TYPE_MODE (TREE_TYPE (*tp
)) == SDmode
)
11267 /* Allocate a 64-bit stack slot to be used for copying SDmode
11268 values through if this function has any SDmode references. */
11271 rs6000_alloc_sdmode_stack_slot (void)
11275 block_stmt_iterator bsi
;
11277 gcc_assert (cfun
->machine
->sdmode_stack_slot
== NULL_RTX
);
11280 for (bsi
= bsi_start (bb
); !bsi_end_p (bsi
); bsi_next (&bsi
))
11282 tree ret
= walk_tree_without_duplicates (bsi_stmt_ptr (bsi
),
11283 rs6000_check_sdmode
, NULL
);
11286 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
11287 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
11293 /* Check for any SDmode parameters of the function. */
11294 for (t
= DECL_ARGUMENTS (cfun
->decl
); t
; t
= TREE_CHAIN (t
))
11296 if (TREE_TYPE (t
) == error_mark_node
)
11299 if (TYPE_MODE (TREE_TYPE (t
)) == SDmode
11300 || TYPE_MODE (DECL_ARG_TYPE (t
)) == SDmode
)
11302 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
11303 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
11311 rs6000_instantiate_decls (void)
11313 if (cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
11314 instantiate_decl_rtl (cfun
->machine
->sdmode_stack_slot
);
11317 /* Return the register class of a scratch register needed to copy IN into
11318 or out of a register in CLASS in MODE. If it can be done directly,
11319 NO_REGS is returned. */
11322 rs6000_secondary_reload_class (enum reg_class
class,
11323 enum machine_mode mode ATTRIBUTE_UNUSED
,
11328 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
11330 && MACHOPIC_INDIRECT
11334 /* We cannot copy a symbolic operand directly into anything
11335 other than BASE_REGS for TARGET_ELF. So indicate that a
11336 register from BASE_REGS is needed as an intermediate
11339 On Darwin, pic addresses require a load from memory, which
11340 needs a base register. */
11341 if (class != BASE_REGS
11342 && (GET_CODE (in
) == SYMBOL_REF
11343 || GET_CODE (in
) == HIGH
11344 || GET_CODE (in
) == LABEL_REF
11345 || GET_CODE (in
) == CONST
))
11349 if (GET_CODE (in
) == REG
)
11351 regno
= REGNO (in
);
11352 if (regno
>= FIRST_PSEUDO_REGISTER
)
11354 regno
= true_regnum (in
);
11355 if (regno
>= FIRST_PSEUDO_REGISTER
)
11359 else if (GET_CODE (in
) == SUBREG
)
11361 regno
= true_regnum (in
);
11362 if (regno
>= FIRST_PSEUDO_REGISTER
)
11368 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
11370 if (class == GENERAL_REGS
|| class == BASE_REGS
11371 || (regno
>= 0 && INT_REGNO_P (regno
)))
11374 /* Constants, memory, and FP registers can go into FP registers. */
11375 if ((regno
== -1 || FP_REGNO_P (regno
))
11376 && (class == FLOAT_REGS
|| class == NON_SPECIAL_REGS
))
11377 return (mode
!= SDmode
) ? NO_REGS
: GENERAL_REGS
;
11379 /* Memory, and AltiVec registers can go into AltiVec registers. */
11380 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
11381 && class == ALTIVEC_REGS
)
11384 /* We can copy among the CR registers. */
11385 if ((class == CR_REGS
|| class == CR0_REGS
)
11386 && regno
>= 0 && CR_REGNO_P (regno
))
11389 /* Otherwise, we need GENERAL_REGS. */
11390 return GENERAL_REGS
;
11393 /* Given a comparison operation, return the bit number in CCR to test. We
11394 know this is a valid comparison.
11396 SCC_P is 1 if this is for an scc. That means that %D will have been
11397 used instead of %C, so the bits will be in different places.
11399 Return -1 if OP isn't a valid comparison for some reason. */
11402 ccr_bit (rtx op
, int scc_p
)
11404 enum rtx_code code
= GET_CODE (op
);
11405 enum machine_mode cc_mode
;
11410 if (!COMPARISON_P (op
))
11413 reg
= XEXP (op
, 0);
11415 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
11417 cc_mode
= GET_MODE (reg
);
11418 cc_regnum
= REGNO (reg
);
11419 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
11421 validate_condition_mode (code
, cc_mode
);
11423 /* When generating a sCOND operation, only positive conditions are
11426 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
11427 || code
== GTU
|| code
== LTU
);
11432 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
11434 return base_bit
+ 2;
11435 case GT
: case GTU
: case UNLE
:
11436 return base_bit
+ 1;
11437 case LT
: case LTU
: case UNGE
:
11439 case ORDERED
: case UNORDERED
:
11440 return base_bit
+ 3;
11443 /* If scc, we will have done a cror to put the bit in the
11444 unordered position. So test that bit. For integer, this is ! LT
11445 unless this is an scc insn. */
11446 return scc_p
? base_bit
+ 3 : base_bit
;
11449 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
11452 gcc_unreachable ();
11456 /* Return the GOT register. */
11459 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
11461 /* The second flow pass currently (June 1999) can't update
11462 regs_ever_live without disturbing other parts of the compiler, so
11463 update it here to make the prolog/epilogue code happy. */
11464 if (!can_create_pseudo_p ()
11465 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
))
11466 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM
, true);
11468 current_function_uses_pic_offset_table
= 1;
11470 return pic_offset_table_rtx
;
11473 /* Function to init struct machine_function.
11474 This will be called, via a pointer variable,
11475 from push_function_context. */
11477 static struct machine_function
*
11478 rs6000_init_machine_status (void)
11480 return ggc_alloc_cleared (sizeof (machine_function
));
11483 /* These macros test for integers and extract the low-order bits. */
11485 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
11486 && GET_MODE (X) == VOIDmode)
11488 #define INT_LOWPART(X) \
11489 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
11492 extract_MB (rtx op
)
11495 unsigned long val
= INT_LOWPART (op
);
11497 /* If the high bit is zero, the value is the first 1 bit we find
11499 if ((val
& 0x80000000) == 0)
11501 gcc_assert (val
& 0xffffffff);
11504 while (((val
<<= 1) & 0x80000000) == 0)
11509 /* If the high bit is set and the low bit is not, or the mask is all
11510 1's, the value is zero. */
11511 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
11514 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11517 while (((val
>>= 1) & 1) != 0)
11524 extract_ME (rtx op
)
11527 unsigned long val
= INT_LOWPART (op
);
11529 /* If the low bit is zero, the value is the first 1 bit we find from
11531 if ((val
& 1) == 0)
11533 gcc_assert (val
& 0xffffffff);
11536 while (((val
>>= 1) & 1) == 0)
11542 /* If the low bit is set and the high bit is not, or the mask is all
11543 1's, the value is 31. */
11544 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
11547 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11550 while (((val
<<= 1) & 0x80000000) != 0)
11556 /* Locate some local-dynamic symbol still in use by this function
11557 so that we can print its name in some tls_ld pattern. */
11559 static const char *
11560 rs6000_get_some_local_dynamic_name (void)
11564 if (cfun
->machine
->some_ld_name
)
11565 return cfun
->machine
->some_ld_name
;
11567 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
11569 && for_each_rtx (&PATTERN (insn
),
11570 rs6000_get_some_local_dynamic_name_1
, 0))
11571 return cfun
->machine
->some_ld_name
;
11573 gcc_unreachable ();
11576 /* Helper function for rs6000_get_some_local_dynamic_name. */
11579 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
11583 if (GET_CODE (x
) == SYMBOL_REF
)
11585 const char *str
= XSTR (x
, 0);
11586 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
11588 cfun
->machine
->some_ld_name
= str
;
11596 /* Write out a function code label. */
11599 rs6000_output_function_entry (FILE *file
, const char *fname
)
11601 if (fname
[0] != '.')
11603 switch (DEFAULT_ABI
)
11606 gcc_unreachable ();
11612 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
11621 RS6000_OUTPUT_BASENAME (file
, fname
);
11623 assemble_name (file
, fname
);
11626 /* Print an operand. Recognize special options, documented below. */
11629 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
11630 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
11632 #define SMALL_DATA_RELOC "sda21"
11633 #define SMALL_DATA_REG 0
11637 print_operand (FILE *file
, rtx x
, int code
)
11641 unsigned HOST_WIDE_INT uval
;
11646 /* Write out an instruction after the call which may be replaced
11647 with glue code by the loader. This depends on the AIX version. */
11648 asm_fprintf (file
, RS6000_CALL_GLUE
);
11651 /* %a is output_address. */
11654 /* If X is a constant integer whose low-order 5 bits are zero,
11655 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
11656 in the AIX assembler where "sri" with a zero shift count
11657 writes a trash instruction. */
11658 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
11665 /* If constant, low-order 16 bits of constant, unsigned.
11666 Otherwise, write normally. */
11668 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
11670 print_operand (file
, x
, 0);
11674 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
11675 for 64-bit mask direction. */
11676 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
11679 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
11683 /* X is a CR register. Print the number of the GT bit of the CR. */
11684 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
11685 output_operand_lossage ("invalid %%E value");
11687 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
11691 /* Like 'J' but get to the GT bit only. */
11692 gcc_assert (GET_CODE (x
) == REG
);
11694 /* Bit 1 is GT bit. */
11695 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 1;
11697 /* Add one for shift count in rlinm for scc. */
11698 fprintf (file
, "%d", i
+ 1);
11702 /* X is a CR register. Print the number of the EQ bit of the CR */
11703 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
11704 output_operand_lossage ("invalid %%E value");
11706 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
11710 /* X is a CR register. Print the shift count needed to move it
11711 to the high-order four bits. */
11712 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
11713 output_operand_lossage ("invalid %%f value");
11715 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
11719 /* Similar, but print the count for the rotate in the opposite
11721 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
11722 output_operand_lossage ("invalid %%F value");
11724 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
11728 /* X is a constant integer. If it is negative, print "m",
11729 otherwise print "z". This is to make an aze or ame insn. */
11730 if (GET_CODE (x
) != CONST_INT
)
11731 output_operand_lossage ("invalid %%G value");
11732 else if (INTVAL (x
) >= 0)
11739 /* If constant, output low-order five bits. Otherwise, write
11742 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
11744 print_operand (file
, x
, 0);
11748 /* If constant, output low-order six bits. Otherwise, write
11751 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
11753 print_operand (file
, x
, 0);
11757 /* Print `i' if this is a constant, else nothing. */
11763 /* Write the bit number in CCR for jump. */
11764 i
= ccr_bit (x
, 0);
11766 output_operand_lossage ("invalid %%j code");
11768 fprintf (file
, "%d", i
);
11772 /* Similar, but add one for shift count in rlinm for scc and pass
11773 scc flag to `ccr_bit'. */
11774 i
= ccr_bit (x
, 1);
11776 output_operand_lossage ("invalid %%J code");
11778 /* If we want bit 31, write a shift count of zero, not 32. */
11779 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
11783 /* X must be a constant. Write the 1's complement of the
11786 output_operand_lossage ("invalid %%k value");
11788 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
11792 /* X must be a symbolic constant on ELF. Write an
11793 expression suitable for an 'addi' that adds in the low 16
11794 bits of the MEM. */
11795 if (GET_CODE (x
) != CONST
)
11797 print_operand_address (file
, x
);
11798 fputs ("@l", file
);
11802 if (GET_CODE (XEXP (x
, 0)) != PLUS
11803 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
11804 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
11805 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
11806 output_operand_lossage ("invalid %%K value");
11807 print_operand_address (file
, XEXP (XEXP (x
, 0), 0));
11808 fputs ("@l", file
);
11809 /* For GNU as, there must be a non-alphanumeric character
11810 between 'l' and the number. The '-' is added by
11811 print_operand() already. */
11812 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
11814 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
11818 /* %l is output_asm_label. */
11821 /* Write second word of DImode or DFmode reference. Works on register
11822 or non-indexed memory only. */
11823 if (GET_CODE (x
) == REG
)
11824 fputs (reg_names
[REGNO (x
) + 1], file
);
11825 else if (GET_CODE (x
) == MEM
)
11827 /* Handle possible auto-increment. Since it is pre-increment and
11828 we have already done it, we can just use an offset of word. */
11829 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
11830 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
11831 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
11833 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
11834 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
11837 output_address (XEXP (adjust_address_nv (x
, SImode
,
11841 if (small_data_operand (x
, GET_MODE (x
)))
11842 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
11843 reg_names
[SMALL_DATA_REG
]);
11848 /* MB value for a mask operand. */
11849 if (! mask_operand (x
, SImode
))
11850 output_operand_lossage ("invalid %%m value");
11852 fprintf (file
, "%d", extract_MB (x
));
11856 /* ME value for a mask operand. */
11857 if (! mask_operand (x
, SImode
))
11858 output_operand_lossage ("invalid %%M value");
11860 fprintf (file
, "%d", extract_ME (x
));
11863 /* %n outputs the negative of its operand. */
11866 /* Write the number of elements in the vector times 4. */
11867 if (GET_CODE (x
) != PARALLEL
)
11868 output_operand_lossage ("invalid %%N value");
11870 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
11874 /* Similar, but subtract 1 first. */
11875 if (GET_CODE (x
) != PARALLEL
)
11876 output_operand_lossage ("invalid %%O value");
11878 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
11882 /* X is a CONST_INT that is a power of two. Output the logarithm. */
11884 || INT_LOWPART (x
) < 0
11885 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
11886 output_operand_lossage ("invalid %%p value");
11888 fprintf (file
, "%d", i
);
11892 /* The operand must be an indirect memory reference. The result
11893 is the register name. */
11894 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
11895 || REGNO (XEXP (x
, 0)) >= 32)
11896 output_operand_lossage ("invalid %%P value");
11898 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
11902 /* This outputs the logical code corresponding to a boolean
11903 expression. The expression may have one or both operands
11904 negated (if one, only the first one). For condition register
11905 logical operations, it will also treat the negated
11906 CR codes as NOTs, but not handle NOTs of them. */
11908 const char *const *t
= 0;
11910 enum rtx_code code
= GET_CODE (x
);
11911 static const char * const tbl
[3][3] = {
11912 { "and", "andc", "nor" },
11913 { "or", "orc", "nand" },
11914 { "xor", "eqv", "xor" } };
11918 else if (code
== IOR
)
11920 else if (code
== XOR
)
11923 output_operand_lossage ("invalid %%q value");
11925 if (GET_CODE (XEXP (x
, 0)) != NOT
)
11929 if (GET_CODE (XEXP (x
, 1)) == NOT
)
11947 /* X is a CR register. Print the mask for `mtcrf'. */
11948 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
11949 output_operand_lossage ("invalid %%R value");
11951 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
11955 /* Low 5 bits of 32 - value */
11957 output_operand_lossage ("invalid %%s value");
11959 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
11963 /* PowerPC64 mask position. All 0's is excluded.
11964 CONST_INT 32-bit mask is considered sign-extended so any
11965 transition must occur within the CONST_INT, not on the boundary. */
11966 if (! mask64_operand (x
, DImode
))
11967 output_operand_lossage ("invalid %%S value");
11969 uval
= INT_LOWPART (x
);
11971 if (uval
& 1) /* Clear Left */
11973 #if HOST_BITS_PER_WIDE_INT > 64
11974 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
11978 else /* Clear Right */
11981 #if HOST_BITS_PER_WIDE_INT > 64
11982 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
11988 gcc_assert (i
>= 0);
11989 fprintf (file
, "%d", i
);
11993 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
11994 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
11996 /* Bit 3 is OV bit. */
11997 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
11999 /* If we want bit 31, write a shift count of zero, not 32. */
12000 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
12004 /* Print the symbolic name of a branch target register. */
12005 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LR_REGNO
12006 && REGNO (x
) != CTR_REGNO
))
12007 output_operand_lossage ("invalid %%T value");
12008 else if (REGNO (x
) == LR_REGNO
)
12009 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
12011 fputs ("ctr", file
);
12015 /* High-order 16 bits of constant for use in unsigned operand. */
12017 output_operand_lossage ("invalid %%u value");
12019 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
12020 (INT_LOWPART (x
) >> 16) & 0xffff);
12024 /* High-order 16 bits of constant for use in signed operand. */
12026 output_operand_lossage ("invalid %%v value");
12028 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
12029 (INT_LOWPART (x
) >> 16) & 0xffff);
12033 /* Print `u' if this has an auto-increment or auto-decrement. */
12034 if (GET_CODE (x
) == MEM
12035 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
12036 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
12037 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
))
12042 /* Print the trap code for this operand. */
12043 switch (GET_CODE (x
))
12046 fputs ("eq", file
); /* 4 */
12049 fputs ("ne", file
); /* 24 */
12052 fputs ("lt", file
); /* 16 */
12055 fputs ("le", file
); /* 20 */
12058 fputs ("gt", file
); /* 8 */
12061 fputs ("ge", file
); /* 12 */
12064 fputs ("llt", file
); /* 2 */
12067 fputs ("lle", file
); /* 6 */
12070 fputs ("lgt", file
); /* 1 */
12073 fputs ("lge", file
); /* 5 */
12076 gcc_unreachable ();
12081 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
12084 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
12085 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
12087 print_operand (file
, x
, 0);
12091 /* MB value for a PowerPC64 rldic operand. */
12092 val
= (GET_CODE (x
) == CONST_INT
12093 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
12098 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
12099 if ((val
<<= 1) < 0)
12102 #if HOST_BITS_PER_WIDE_INT == 32
12103 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
12104 i
+= 32; /* zero-extend high-part was all 0's */
12105 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
12107 val
= CONST_DOUBLE_LOW (x
);
12113 for ( ; i
< 64; i
++)
12114 if ((val
<<= 1) < 0)
12119 fprintf (file
, "%d", i
+ 1);
12123 if (GET_CODE (x
) == MEM
12124 && (legitimate_indexed_address_p (XEXP (x
, 0), 0)
12125 || (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
12126 && legitimate_indexed_address_p (XEXP (XEXP (x
, 0), 1), 0))))
12131 /* Like 'L', for third word of TImode */
12132 if (GET_CODE (x
) == REG
)
12133 fputs (reg_names
[REGNO (x
) + 2], file
);
12134 else if (GET_CODE (x
) == MEM
)
12136 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
12137 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12138 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
12139 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12140 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
12142 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
12143 if (small_data_operand (x
, GET_MODE (x
)))
12144 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12145 reg_names
[SMALL_DATA_REG
]);
12150 /* X is a SYMBOL_REF. Write out the name preceded by a
12151 period and without any trailing data in brackets. Used for function
12152 names. If we are configured for System V (or the embedded ABI) on
12153 the PowerPC, do not emit the period, since those systems do not use
12154 TOCs and the like. */
12155 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
12157 /* Mark the decl as referenced so that cgraph will output the
12159 if (SYMBOL_REF_DECL (x
))
12160 mark_decl_referenced (SYMBOL_REF_DECL (x
));
12162 /* For macho, check to see if we need a stub. */
12165 const char *name
= XSTR (x
, 0);
12167 if (MACHOPIC_INDIRECT
12168 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
12169 name
= machopic_indirection_name (x
, /*stub_p=*/true);
12171 assemble_name (file
, name
);
12173 else if (!DOT_SYMBOLS
)
12174 assemble_name (file
, XSTR (x
, 0));
12176 rs6000_output_function_entry (file
, XSTR (x
, 0));
12180 /* Like 'L', for last word of TImode. */
12181 if (GET_CODE (x
) == REG
)
12182 fputs (reg_names
[REGNO (x
) + 3], file
);
12183 else if (GET_CODE (x
) == MEM
)
12185 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
12186 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12187 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
12188 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12189 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
12191 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
12192 if (small_data_operand (x
, GET_MODE (x
)))
12193 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12194 reg_names
[SMALL_DATA_REG
]);
12198 /* Print AltiVec or SPE memory operand. */
12203 gcc_assert (GET_CODE (x
) == MEM
);
12207 /* Ugly hack because %y is overloaded. */
12208 if ((TARGET_SPE
|| TARGET_E500_DOUBLE
)
12209 && (GET_MODE_SIZE (GET_MODE (x
)) == 8
12210 || GET_MODE (x
) == TFmode
12211 || GET_MODE (x
) == TImode
))
12213 /* Handle [reg]. */
12214 if (GET_CODE (tmp
) == REG
)
12216 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
12219 /* Handle [reg+UIMM]. */
12220 else if (GET_CODE (tmp
) == PLUS
&&
12221 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
12225 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
12227 x
= INTVAL (XEXP (tmp
, 1));
12228 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
12232 /* Fall through. Must be [reg+reg]. */
12235 && GET_CODE (tmp
) == AND
12236 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
12237 && INTVAL (XEXP (tmp
, 1)) == -16)
12238 tmp
= XEXP (tmp
, 0);
12239 if (GET_CODE (tmp
) == REG
)
12240 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
12243 gcc_assert (GET_CODE (tmp
) == PLUS
12244 && REG_P (XEXP (tmp
, 0))
12245 && REG_P (XEXP (tmp
, 1)));
12247 if (REGNO (XEXP (tmp
, 0)) == 0)
12248 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
12249 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
12251 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
12252 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
12258 if (GET_CODE (x
) == REG
)
12259 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
12260 else if (GET_CODE (x
) == MEM
)
12262 /* We need to handle PRE_INC and PRE_DEC here, since we need to
12263 know the width from the mode. */
12264 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
12265 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
12266 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
12267 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12268 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
12269 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
12270 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12271 output_address (XEXP (XEXP (x
, 0), 1));
12273 output_address (XEXP (x
, 0));
12276 output_addr_const (file
, x
);
12280 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
12284 output_operand_lossage ("invalid %%xn code");
12288 /* Print the address of an operand. */
12291 print_operand_address (FILE *file
, rtx x
)
12293 if (GET_CODE (x
) == REG
)
12294 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
12295 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
12296 || GET_CODE (x
) == LABEL_REF
)
12298 output_addr_const (file
, x
);
12299 if (small_data_operand (x
, GET_MODE (x
)))
12300 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12301 reg_names
[SMALL_DATA_REG
]);
12303 gcc_assert (!TARGET_TOC
);
12305 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
12307 gcc_assert (REG_P (XEXP (x
, 0)));
12308 if (REGNO (XEXP (x
, 0)) == 0)
12309 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
12310 reg_names
[ REGNO (XEXP (x
, 0)) ]);
12312 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
12313 reg_names
[ REGNO (XEXP (x
, 1)) ]);
12315 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
12316 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
12317 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
12319 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
12320 && CONSTANT_P (XEXP (x
, 1)))
12322 output_addr_const (file
, XEXP (x
, 1));
12323 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
12327 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
12328 && CONSTANT_P (XEXP (x
, 1)))
12330 fprintf (file
, "lo16(");
12331 output_addr_const (file
, XEXP (x
, 1));
12332 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
12335 else if (legitimate_constant_pool_address_p (x
))
12337 if (TARGET_AIX
&& (!TARGET_ELF
|| !TARGET_MINIMAL_TOC
))
12339 rtx contains_minus
= XEXP (x
, 1);
12343 /* Find the (minus (sym) (toc)) buried in X, and temporarily
12344 turn it into (sym) for output_addr_const. */
12345 while (GET_CODE (XEXP (contains_minus
, 0)) != MINUS
)
12346 contains_minus
= XEXP (contains_minus
, 0);
12348 minus
= XEXP (contains_minus
, 0);
12349 symref
= XEXP (minus
, 0);
12350 XEXP (contains_minus
, 0) = symref
;
12355 name
= XSTR (symref
, 0);
12356 newname
= alloca (strlen (name
) + sizeof ("@toc"));
12357 strcpy (newname
, name
);
12358 strcat (newname
, "@toc");
12359 XSTR (symref
, 0) = newname
;
12361 output_addr_const (file
, XEXP (x
, 1));
12363 XSTR (symref
, 0) = name
;
12364 XEXP (contains_minus
, 0) = minus
;
12367 output_addr_const (file
, XEXP (x
, 1));
12369 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
12372 gcc_unreachable ();
12375 /* Target hook for assembling integer objects. The PowerPC version has
12376 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
12377 is defined. It also needs to handle DI-mode objects on 64-bit
12381 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
12383 #ifdef RELOCATABLE_NEEDS_FIXUP
12384 /* Special handling for SI values. */
12385 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
12387 static int recurse
= 0;
12389 /* For -mrelocatable, we mark all addresses that need to be fixed up
12390 in the .fixup section. */
12391 if (TARGET_RELOCATABLE
12392 && in_section
!= toc_section
12393 && in_section
!= text_section
12394 && !unlikely_text_section_p (in_section
)
12396 && GET_CODE (x
) != CONST_INT
12397 && GET_CODE (x
) != CONST_DOUBLE
12403 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
12405 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
12406 fprintf (asm_out_file
, "\t.long\t(");
12407 output_addr_const (asm_out_file
, x
);
12408 fprintf (asm_out_file
, ")@fixup\n");
12409 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
12410 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
12411 fprintf (asm_out_file
, "\t.long\t");
12412 assemble_name (asm_out_file
, buf
);
12413 fprintf (asm_out_file
, "\n\t.previous\n");
12417 /* Remove initial .'s to turn a -mcall-aixdesc function
12418 address into the address of the descriptor, not the function
12420 else if (GET_CODE (x
) == SYMBOL_REF
12421 && XSTR (x
, 0)[0] == '.'
12422 && DEFAULT_ABI
== ABI_AIX
)
12424 const char *name
= XSTR (x
, 0);
12425 while (*name
== '.')
12428 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
12432 #endif /* RELOCATABLE_NEEDS_FIXUP */
12433 return default_assemble_integer (x
, size
, aligned_p
);
12436 #ifdef HAVE_GAS_HIDDEN
12437 /* Emit an assembler directive to set symbol visibility for DECL to
12438 VISIBILITY_TYPE. */
12441 rs6000_assemble_visibility (tree decl
, int vis
)
12443 /* Functions need to have their entry point symbol visibility set as
12444 well as their descriptor symbol visibility. */
12445 if (DEFAULT_ABI
== ABI_AIX
12447 && TREE_CODE (decl
) == FUNCTION_DECL
)
12449 static const char * const visibility_types
[] = {
12450 NULL
, "internal", "hidden", "protected"
12453 const char *name
, *type
;
12455 name
= ((* targetm
.strip_name_encoding
)
12456 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
12457 type
= visibility_types
[vis
];
12459 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
12460 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
12463 default_assemble_visibility (decl
, vis
);
12468 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
12470 /* Reversal of FP compares takes care -- an ordered compare
12471 becomes an unordered compare and vice versa. */
12472 if (mode
== CCFPmode
12473 && (!flag_finite_math_only
12474 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
12475 || code
== UNEQ
|| code
== LTGT
))
12476 return reverse_condition_maybe_unordered (code
);
12478 return reverse_condition (code
);
12481 /* Generate a compare for CODE. Return a brand-new rtx that
12482 represents the result of the compare. */
12485 rs6000_generate_compare (enum rtx_code code
)
12487 enum machine_mode comp_mode
;
12488 rtx compare_result
;
12490 if (rs6000_compare_fp_p
)
12491 comp_mode
= CCFPmode
;
12492 else if (code
== GTU
|| code
== LTU
12493 || code
== GEU
|| code
== LEU
)
12494 comp_mode
= CCUNSmode
;
12495 else if ((code
== EQ
|| code
== NE
)
12496 && GET_CODE (rs6000_compare_op0
) == SUBREG
12497 && GET_CODE (rs6000_compare_op1
) == SUBREG
12498 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0
)
12499 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1
))
12500 /* These are unsigned values, perhaps there will be a later
12501 ordering compare that can be shared with this one.
12502 Unfortunately we cannot detect the signedness of the operands
12503 for non-subregs. */
12504 comp_mode
= CCUNSmode
;
12506 comp_mode
= CCmode
;
12508 /* First, the compare. */
12509 compare_result
= gen_reg_rtx (comp_mode
);
12511 /* E500 FP compare instructions on the GPRs. Yuck! */
12512 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
)
12513 && rs6000_compare_fp_p
)
12515 rtx cmp
, or_result
, compare_result2
;
12516 enum machine_mode op_mode
= GET_MODE (rs6000_compare_op0
);
12518 if (op_mode
== VOIDmode
)
12519 op_mode
= GET_MODE (rs6000_compare_op1
);
12521 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
12522 This explains the following mess. */
12526 case EQ
: case UNEQ
: case NE
: case LTGT
:
12530 cmp
= flag_unsafe_math_optimizations
12531 ? gen_tstsfeq_gpr (compare_result
, rs6000_compare_op0
,
12532 rs6000_compare_op1
)
12533 : gen_cmpsfeq_gpr (compare_result
, rs6000_compare_op0
,
12534 rs6000_compare_op1
);
12538 cmp
= flag_unsafe_math_optimizations
12539 ? gen_tstdfeq_gpr (compare_result
, rs6000_compare_op0
,
12540 rs6000_compare_op1
)
12541 : gen_cmpdfeq_gpr (compare_result
, rs6000_compare_op0
,
12542 rs6000_compare_op1
);
12546 cmp
= flag_unsafe_math_optimizations
12547 ? gen_tsttfeq_gpr (compare_result
, rs6000_compare_op0
,
12548 rs6000_compare_op1
)
12549 : gen_cmptfeq_gpr (compare_result
, rs6000_compare_op0
,
12550 rs6000_compare_op1
);
12554 gcc_unreachable ();
12558 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
12562 cmp
= flag_unsafe_math_optimizations
12563 ? gen_tstsfgt_gpr (compare_result
, rs6000_compare_op0
,
12564 rs6000_compare_op1
)
12565 : gen_cmpsfgt_gpr (compare_result
, rs6000_compare_op0
,
12566 rs6000_compare_op1
);
12570 cmp
= flag_unsafe_math_optimizations
12571 ? gen_tstdfgt_gpr (compare_result
, rs6000_compare_op0
,
12572 rs6000_compare_op1
)
12573 : gen_cmpdfgt_gpr (compare_result
, rs6000_compare_op0
,
12574 rs6000_compare_op1
);
12578 cmp
= flag_unsafe_math_optimizations
12579 ? gen_tsttfgt_gpr (compare_result
, rs6000_compare_op0
,
12580 rs6000_compare_op1
)
12581 : gen_cmptfgt_gpr (compare_result
, rs6000_compare_op0
,
12582 rs6000_compare_op1
);
12586 gcc_unreachable ();
12590 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
12594 cmp
= flag_unsafe_math_optimizations
12595 ? gen_tstsflt_gpr (compare_result
, rs6000_compare_op0
,
12596 rs6000_compare_op1
)
12597 : gen_cmpsflt_gpr (compare_result
, rs6000_compare_op0
,
12598 rs6000_compare_op1
);
12602 cmp
= flag_unsafe_math_optimizations
12603 ? gen_tstdflt_gpr (compare_result
, rs6000_compare_op0
,
12604 rs6000_compare_op1
)
12605 : gen_cmpdflt_gpr (compare_result
, rs6000_compare_op0
,
12606 rs6000_compare_op1
);
12610 cmp
= flag_unsafe_math_optimizations
12611 ? gen_tsttflt_gpr (compare_result
, rs6000_compare_op0
,
12612 rs6000_compare_op1
)
12613 : gen_cmptflt_gpr (compare_result
, rs6000_compare_op0
,
12614 rs6000_compare_op1
);
12618 gcc_unreachable ();
12622 gcc_unreachable ();
12625 /* Synthesize LE and GE from LT/GT || EQ. */
12626 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
12632 case LE
: code
= LT
; break;
12633 case GE
: code
= GT
; break;
12634 case LEU
: code
= LT
; break;
12635 case GEU
: code
= GT
; break;
12636 default: gcc_unreachable ();
12639 compare_result2
= gen_reg_rtx (CCFPmode
);
12645 cmp
= flag_unsafe_math_optimizations
12646 ? gen_tstsfeq_gpr (compare_result2
, rs6000_compare_op0
,
12647 rs6000_compare_op1
)
12648 : gen_cmpsfeq_gpr (compare_result2
, rs6000_compare_op0
,
12649 rs6000_compare_op1
);
12653 cmp
= flag_unsafe_math_optimizations
12654 ? gen_tstdfeq_gpr (compare_result2
, rs6000_compare_op0
,
12655 rs6000_compare_op1
)
12656 : gen_cmpdfeq_gpr (compare_result2
, rs6000_compare_op0
,
12657 rs6000_compare_op1
);
12661 cmp
= flag_unsafe_math_optimizations
12662 ? gen_tsttfeq_gpr (compare_result2
, rs6000_compare_op0
,
12663 rs6000_compare_op1
)
12664 : gen_cmptfeq_gpr (compare_result2
, rs6000_compare_op0
,
12665 rs6000_compare_op1
);
12669 gcc_unreachable ();
12673 /* OR them together. */
12674 or_result
= gen_reg_rtx (CCFPmode
);
12675 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
12677 compare_result
= or_result
;
12682 if (code
== NE
|| code
== LTGT
)
12692 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
12693 CLOBBERs to match cmptf_internal2 pattern. */
12694 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
12695 && GET_MODE (rs6000_compare_op0
) == TFmode
12696 && !TARGET_IEEEQUAD
12697 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
12698 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
12700 gen_rtx_SET (VOIDmode
,
12702 gen_rtx_COMPARE (comp_mode
,
12703 rs6000_compare_op0
,
12704 rs6000_compare_op1
)),
12705 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12706 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12707 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12708 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12709 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12710 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12711 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12712 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)))));
12713 else if (GET_CODE (rs6000_compare_op1
) == UNSPEC
12714 && XINT (rs6000_compare_op1
, 1) == UNSPEC_SP_TEST
)
12716 rtx op1
= XVECEXP (rs6000_compare_op1
, 0, 0);
12717 comp_mode
= CCEQmode
;
12718 compare_result
= gen_reg_rtx (CCEQmode
);
12720 emit_insn (gen_stack_protect_testdi (compare_result
,
12721 rs6000_compare_op0
, op1
));
12723 emit_insn (gen_stack_protect_testsi (compare_result
,
12724 rs6000_compare_op0
, op1
));
12727 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
12728 gen_rtx_COMPARE (comp_mode
,
12729 rs6000_compare_op0
,
12730 rs6000_compare_op1
)));
12733 /* Some kinds of FP comparisons need an OR operation;
12734 under flag_finite_math_only we don't bother. */
12735 if (rs6000_compare_fp_p
12736 && !flag_finite_math_only
12737 && !(TARGET_HARD_FLOAT
&& !TARGET_FPRS
)
12738 && (code
== LE
|| code
== GE
12739 || code
== UNEQ
|| code
== LTGT
12740 || code
== UNGT
|| code
== UNLT
))
12742 enum rtx_code or1
, or2
;
12743 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
12744 rtx or_result
= gen_reg_rtx (CCEQmode
);
12748 case LE
: or1
= LT
; or2
= EQ
; break;
12749 case GE
: or1
= GT
; or2
= EQ
; break;
12750 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
12751 case LTGT
: or1
= LT
; or2
= GT
; break;
12752 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
12753 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
12754 default: gcc_unreachable ();
12756 validate_condition_mode (or1
, comp_mode
);
12757 validate_condition_mode (or2
, comp_mode
);
12758 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
12759 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
12760 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
12761 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
12763 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
12765 compare_result
= or_result
;
12769 validate_condition_mode (code
, GET_MODE (compare_result
));
12771 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
12775 /* Emit the RTL for an sCOND pattern. */
12778 rs6000_emit_sCOND (enum rtx_code code
, rtx result
)
12781 enum machine_mode op_mode
;
12782 enum rtx_code cond_code
;
12784 condition_rtx
= rs6000_generate_compare (code
);
12785 cond_code
= GET_CODE (condition_rtx
);
12787 if (rs6000_compare_fp_p
12788 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
12792 PUT_MODE (condition_rtx
, SImode
);
12793 t
= XEXP (condition_rtx
, 0);
12795 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
12797 if (cond_code
== NE
)
12798 emit_insn (gen_e500_flip_gt_bit (t
, t
));
12800 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
12804 if (cond_code
== NE
12805 || cond_code
== GE
|| cond_code
== LE
12806 || cond_code
== GEU
|| cond_code
== LEU
12807 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
12809 rtx not_result
= gen_reg_rtx (CCEQmode
);
12810 rtx not_op
, rev_cond_rtx
;
12811 enum machine_mode cc_mode
;
12813 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
12815 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
12816 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
12817 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
12818 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
12819 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
12822 op_mode
= GET_MODE (rs6000_compare_op0
);
12823 if (op_mode
== VOIDmode
)
12824 op_mode
= GET_MODE (rs6000_compare_op1
);
12826 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| rs6000_compare_fp_p
))
12828 PUT_MODE (condition_rtx
, DImode
);
12829 convert_move (result
, condition_rtx
, 0);
12833 PUT_MODE (condition_rtx
, SImode
);
12834 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
12838 /* Emit a branch of kind CODE to location LOC. */
12841 rs6000_emit_cbranch (enum rtx_code code
, rtx loc
)
12843 rtx condition_rtx
, loc_ref
;
12845 condition_rtx
= rs6000_generate_compare (code
);
12846 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, loc
);
12847 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
12848 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
12849 loc_ref
, pc_rtx
)));
12852 /* Return the string to output a conditional branch to LABEL, which is
12853 the operand number of the label, or -1 if the branch is really a
12854 conditional return.
12856 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
12857 condition code register and its mode specifies what kind of
12858 comparison we made.
12860 REVERSED is nonzero if we should reverse the sense of the comparison.
12862 INSN is the insn. */
12865 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
12867 static char string
[64];
12868 enum rtx_code code
= GET_CODE (op
);
12869 rtx cc_reg
= XEXP (op
, 0);
12870 enum machine_mode mode
= GET_MODE (cc_reg
);
12871 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
12872 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
12873 int really_reversed
= reversed
^ need_longbranch
;
12879 validate_condition_mode (code
, mode
);
12881 /* Work out which way this really branches. We could use
12882 reverse_condition_maybe_unordered here always but this
12883 makes the resulting assembler clearer. */
12884 if (really_reversed
)
12886 /* Reversal of FP compares takes care -- an ordered compare
12887 becomes an unordered compare and vice versa. */
12888 if (mode
== CCFPmode
)
12889 code
= reverse_condition_maybe_unordered (code
);
12891 code
= reverse_condition (code
);
12894 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
12896 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
12901 /* Opposite of GT. */
12910 gcc_unreachable ();
12916 /* Not all of these are actually distinct opcodes, but
12917 we distinguish them for clarity of the resulting assembler. */
12918 case NE
: case LTGT
:
12919 ccode
= "ne"; break;
12920 case EQ
: case UNEQ
:
12921 ccode
= "eq"; break;
12923 ccode
= "ge"; break;
12924 case GT
: case GTU
: case UNGT
:
12925 ccode
= "gt"; break;
12927 ccode
= "le"; break;
12928 case LT
: case LTU
: case UNLT
:
12929 ccode
= "lt"; break;
12930 case UNORDERED
: ccode
= "un"; break;
12931 case ORDERED
: ccode
= "nu"; break;
12932 case UNGE
: ccode
= "nl"; break;
12933 case UNLE
: ccode
= "ng"; break;
12935 gcc_unreachable ();
12938 /* Maybe we have a guess as to how likely the branch is.
12939 The old mnemonics don't have a way to specify this information. */
12941 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
12942 if (note
!= NULL_RTX
)
12944 /* PROB is the difference from 50%. */
12945 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
12947 /* Only hint for highly probable/improbable branches on newer
12948 cpus as static prediction overrides processor dynamic
12949 prediction. For older cpus we may as well always hint, but
12950 assume not taken for branches that are very close to 50% as a
12951 mispredicted taken branch is more expensive than a
12952 mispredicted not-taken branch. */
12953 if (rs6000_always_hint
12954 || (abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48
12955 && br_prob_note_reliable_p (note
)))
12957 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
12958 && ((prob
> 0) ^ need_longbranch
))
12966 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
12968 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
12970 /* We need to escape any '%' characters in the reg_names string.
12971 Assume they'd only be the first character.... */
12972 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
12974 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
12978 /* If the branch distance was too far, we may have to use an
12979 unconditional branch to go the distance. */
12980 if (need_longbranch
)
12981 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
12983 s
+= sprintf (s
, ",%s", label
);
12989 /* Return the string to flip the GT bit on a CR. */
12991 output_e500_flip_gt_bit (rtx dst
, rtx src
)
12993 static char string
[64];
12996 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
12997 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
13000 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
13001 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
13003 sprintf (string
, "crnot %d,%d", a
, b
);
13007 /* Return insn index for the vector compare instruction for given CODE,
13008 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
13012 get_vec_cmp_insn (enum rtx_code code
,
13013 enum machine_mode dest_mode
,
13014 enum machine_mode op_mode
)
13016 if (!TARGET_ALTIVEC
)
13017 return INSN_NOT_AVAILABLE
;
13022 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
13023 return UNSPEC_VCMPEQUB
;
13024 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
13025 return UNSPEC_VCMPEQUH
;
13026 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
13027 return UNSPEC_VCMPEQUW
;
13028 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
13029 return UNSPEC_VCMPEQFP
;
13032 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
13033 return UNSPEC_VCMPGEFP
;
13035 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
13036 return UNSPEC_VCMPGTSB
;
13037 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
13038 return UNSPEC_VCMPGTSH
;
13039 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
13040 return UNSPEC_VCMPGTSW
;
13041 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
13042 return UNSPEC_VCMPGTFP
;
13045 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
13046 return UNSPEC_VCMPGTUB
;
13047 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
13048 return UNSPEC_VCMPGTUH
;
13049 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
13050 return UNSPEC_VCMPGTUW
;
13055 return INSN_NOT_AVAILABLE
;
13058 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
13059 DMODE is expected destination mode. This is a recursive function. */
13062 rs6000_emit_vector_compare (enum rtx_code rcode
,
13064 enum machine_mode dmode
)
13068 enum machine_mode dest_mode
;
13069 enum machine_mode op_mode
= GET_MODE (op1
);
13071 gcc_assert (TARGET_ALTIVEC
);
13072 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
13074 /* Floating point vector compare instructions uses destination V4SImode.
13075 Move destination to appropriate mode later. */
13076 if (dmode
== V4SFmode
)
13077 dest_mode
= V4SImode
;
13081 mask
= gen_reg_rtx (dest_mode
);
13082 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
13084 if (vec_cmp_insn
== INSN_NOT_AVAILABLE
)
13086 bool swap_operands
= false;
13087 bool try_again
= false;
13092 swap_operands
= true;
13097 swap_operands
= true;
13105 /* Invert condition and try again.
13106 e.g., A != B becomes ~(A==B). */
13108 enum rtx_code rev_code
;
13109 enum insn_code nor_code
;
13112 rev_code
= reverse_condition_maybe_unordered (rcode
);
13113 eq_rtx
= rs6000_emit_vector_compare (rev_code
, op0
, op1
,
13116 nor_code
= optab_handler (one_cmpl_optab
, (int)dest_mode
)->insn_code
;
13117 gcc_assert (nor_code
!= CODE_FOR_nothing
);
13118 emit_insn (GEN_FCN (nor_code
) (mask
, eq_rtx
));
13120 if (dmode
!= dest_mode
)
13122 rtx temp
= gen_reg_rtx (dest_mode
);
13123 convert_move (temp
, mask
, 0);
13133 /* Try GT/GTU/LT/LTU OR EQ */
13136 enum insn_code ior_code
;
13137 enum rtx_code new_code
;
13158 gcc_unreachable ();
13161 c_rtx
= rs6000_emit_vector_compare (new_code
,
13162 op0
, op1
, dest_mode
);
13163 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
,
13166 ior_code
= optab_handler (ior_optab
, (int)dest_mode
)->insn_code
;
13167 gcc_assert (ior_code
!= CODE_FOR_nothing
);
13168 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
13169 if (dmode
!= dest_mode
)
13171 rtx temp
= gen_reg_rtx (dest_mode
);
13172 convert_move (temp
, mask
, 0);
13179 gcc_unreachable ();
13184 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
13185 /* You only get two chances. */
13186 gcc_assert (vec_cmp_insn
!= INSN_NOT_AVAILABLE
);
13198 emit_insn (gen_rtx_SET (VOIDmode
, mask
,
13199 gen_rtx_UNSPEC (dest_mode
,
13200 gen_rtvec (2, op0
, op1
),
13202 if (dmode
!= dest_mode
)
13204 rtx temp
= gen_reg_rtx (dest_mode
);
13205 convert_move (temp
, mask
, 0);
13211 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
13212 valid insn doesn exist for given mode. */
13215 get_vsel_insn (enum machine_mode mode
)
13220 return UNSPEC_VSEL4SI
;
13223 return UNSPEC_VSEL4SF
;
13226 return UNSPEC_VSEL8HI
;
13229 return UNSPEC_VSEL16QI
;
13232 return INSN_NOT_AVAILABLE
;
13235 return INSN_NOT_AVAILABLE
;
13238 /* Emit vector select insn where DEST is destination using
13239 operands OP1, OP2 and MASK. */
13242 rs6000_emit_vector_select (rtx dest
, rtx op1
, rtx op2
, rtx mask
)
13245 enum machine_mode dest_mode
= GET_MODE (dest
);
13246 int vsel_insn_index
= get_vsel_insn (GET_MODE (dest
));
13248 temp
= gen_reg_rtx (dest_mode
);
13250 /* For each vector element, select op1 when mask is 1 otherwise
13252 t
= gen_rtx_SET (VOIDmode
, temp
,
13253 gen_rtx_UNSPEC (dest_mode
,
13254 gen_rtvec (3, op2
, op1
, mask
),
13257 emit_move_insn (dest
, temp
);
13261 /* Emit vector conditional expression.
13262 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
13263 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
13266 rs6000_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
13267 rtx cond
, rtx cc_op0
, rtx cc_op1
)
13269 enum machine_mode dest_mode
= GET_MODE (dest
);
13270 enum rtx_code rcode
= GET_CODE (cond
);
13273 if (!TARGET_ALTIVEC
)
13276 /* Get the vector mask for the given relational operations. */
13277 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
13279 rs6000_emit_vector_select (dest
, op1
, op2
, mask
);
13284 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
13285 operands of the last comparison is nonzero/true, FALSE_COND if it
13286 is zero/false. Return 0 if the hardware has no such operation. */
13289 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
13291 enum rtx_code code
= GET_CODE (op
);
13292 rtx op0
= rs6000_compare_op0
;
13293 rtx op1
= rs6000_compare_op1
;
13294 REAL_VALUE_TYPE c1
;
13295 enum machine_mode compare_mode
= GET_MODE (op0
);
13296 enum machine_mode result_mode
= GET_MODE (dest
);
13298 bool is_against_zero
;
13300 /* These modes should always match. */
13301 if (GET_MODE (op1
) != compare_mode
13302 /* In the isel case however, we can use a compare immediate, so
13303 op1 may be a small constant. */
13304 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
13306 if (GET_MODE (true_cond
) != result_mode
)
13308 if (GET_MODE (false_cond
) != result_mode
)
13311 /* First, work out if the hardware can do this at all, or
13312 if it's too slow.... */
13313 if (! rs6000_compare_fp_p
)
13316 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
13319 else if (TARGET_HARD_FLOAT
&& !TARGET_FPRS
13320 && SCALAR_FLOAT_MODE_P (compare_mode
))
13323 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
13325 /* A floating-point subtract might overflow, underflow, or produce
13326 an inexact result, thus changing the floating-point flags, so it
13327 can't be generated if we care about that. It's safe if one side
13328 of the construct is zero, since then no subtract will be
13330 if (SCALAR_FLOAT_MODE_P (compare_mode
)
13331 && flag_trapping_math
&& ! is_against_zero
)
13334 /* Eliminate half of the comparisons by switching operands, this
13335 makes the remaining code simpler. */
13336 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
13337 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
13339 code
= reverse_condition_maybe_unordered (code
);
13341 true_cond
= false_cond
;
13345 /* UNEQ and LTGT take four instructions for a comparison with zero,
13346 it'll probably be faster to use a branch here too. */
13347 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
13350 if (GET_CODE (op1
) == CONST_DOUBLE
)
13351 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
13353 /* We're going to try to implement comparisons by performing
13354 a subtract, then comparing against zero. Unfortunately,
13355 Inf - Inf is NaN which is not zero, and so if we don't
13356 know that the operand is finite and the comparison
13357 would treat EQ different to UNORDERED, we can't do it. */
13358 if (HONOR_INFINITIES (compare_mode
)
13359 && code
!= GT
&& code
!= UNGE
13360 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
13361 /* Constructs of the form (a OP b ? a : b) are safe. */
13362 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
13363 || (! rtx_equal_p (op0
, true_cond
)
13364 && ! rtx_equal_p (op1
, true_cond
))))
13367 /* At this point we know we can use fsel. */
13369 /* Reduce the comparison to a comparison against zero. */
13370 if (! is_against_zero
)
13372 temp
= gen_reg_rtx (compare_mode
);
13373 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13374 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
13376 op1
= CONST0_RTX (compare_mode
);
13379 /* If we don't care about NaNs we can reduce some of the comparisons
13380 down to faster ones. */
13381 if (! HONOR_NANS (compare_mode
))
13387 true_cond
= false_cond
;
13400 /* Now, reduce everything down to a GE. */
13407 temp
= gen_reg_rtx (compare_mode
);
13408 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
13413 temp
= gen_reg_rtx (compare_mode
);
13414 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
13419 temp
= gen_reg_rtx (compare_mode
);
13420 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13421 gen_rtx_NEG (compare_mode
,
13422 gen_rtx_ABS (compare_mode
, op0
))));
13427 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
13428 temp
= gen_reg_rtx (result_mode
);
13429 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13430 gen_rtx_IF_THEN_ELSE (result_mode
,
13431 gen_rtx_GE (VOIDmode
,
13433 true_cond
, false_cond
)));
13434 false_cond
= true_cond
;
13437 temp
= gen_reg_rtx (compare_mode
);
13438 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
13443 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
13444 temp
= gen_reg_rtx (result_mode
);
13445 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13446 gen_rtx_IF_THEN_ELSE (result_mode
,
13447 gen_rtx_GE (VOIDmode
,
13449 true_cond
, false_cond
)));
13450 true_cond
= false_cond
;
13453 temp
= gen_reg_rtx (compare_mode
);
13454 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
13459 gcc_unreachable ();
13462 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
13463 gen_rtx_IF_THEN_ELSE (result_mode
,
13464 gen_rtx_GE (VOIDmode
,
13466 true_cond
, false_cond
)));
13470 /* Same as above, but for ints (isel). */
13473 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
13475 rtx condition_rtx
, cr
;
13477 /* All isel implementations thus far are 32-bits. */
13478 if (GET_MODE (rs6000_compare_op0
) != SImode
)
13481 /* We still have to do the compare, because isel doesn't do a
13482 compare, it just looks at the CRx bits set by a previous compare
13484 condition_rtx
= rs6000_generate_compare (GET_CODE (op
));
13485 cr
= XEXP (condition_rtx
, 0);
13487 if (GET_MODE (cr
) == CCmode
)
13488 emit_insn (gen_isel_signed (dest
, condition_rtx
,
13489 true_cond
, false_cond
, cr
));
13491 emit_insn (gen_isel_unsigned (dest
, condition_rtx
,
13492 true_cond
, false_cond
, cr
));
13498 output_isel (rtx
*operands
)
13500 enum rtx_code code
;
13502 code
= GET_CODE (operands
[1]);
13503 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
13505 PUT_CODE (operands
[1], reverse_condition (code
));
13506 return "isel %0,%3,%2,%j1";
13509 return "isel %0,%2,%3,%j1";
13513 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
13515 enum machine_mode mode
= GET_MODE (op0
);
13519 if (code
== SMAX
|| code
== SMIN
)
13524 if (code
== SMAX
|| code
== UMAX
)
13525 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
13526 op0
, op1
, mode
, 0);
13528 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
13529 op1
, op0
, mode
, 0);
13530 gcc_assert (target
);
13531 if (target
!= dest
)
13532 emit_move_insn (dest
, target
);
13535 /* Emit instructions to perform a load-reserved/store-conditional operation.
13536 The operation performed is an atomic
13537 (set M (CODE:MODE M OP))
13538 If not NULL, BEFORE is atomically set to M before the operation, and
13539 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
13540 If SYNC_P then a memory barrier is emitted before the operation.
13541 Either OP or M may be wrapped in a NOT operation. */
13544 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
13545 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
13548 enum machine_mode used_mode
;
13549 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
13552 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
13553 rtx shift
= NULL_RTX
;
13556 emit_insn (gen_memory_barrier ());
13558 if (GET_CODE (m
) == NOT
)
13559 used_m
= XEXP (m
, 0);
13563 /* If this is smaller than SImode, we'll have to use SImode with
13565 if (mode
== QImode
|| mode
== HImode
)
13569 if (MEM_ALIGN (used_m
) >= 32)
13572 if (BYTES_BIG_ENDIAN
)
13573 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
13575 shift
= GEN_INT (ishift
);
13576 used_m
= change_address (used_m
, SImode
, 0);
13580 rtx addrSI
, aligned_addr
;
13581 int shift_mask
= mode
== QImode
? 0x18 : 0x10;
13583 addrSI
= gen_lowpart_common (SImode
,
13584 force_reg (Pmode
, XEXP (used_m
, 0)));
13585 addrSI
= force_reg (SImode
, addrSI
);
13586 shift
= gen_reg_rtx (SImode
);
13588 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
13589 GEN_INT (shift_mask
)));
13590 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
13592 aligned_addr
= expand_binop (Pmode
, and_optab
,
13594 GEN_INT (-4), NULL_RTX
,
13595 1, OPTAB_LIB_WIDEN
);
13596 used_m
= change_address (used_m
, SImode
, aligned_addr
);
13597 set_mem_align (used_m
, 32);
13599 /* It's safe to keep the old alias set of USED_M, because
13600 the operation is atomic and only affects the original
13602 if (GET_CODE (m
) == NOT
)
13603 m
= gen_rtx_NOT (SImode
, used_m
);
13607 if (GET_CODE (op
) == NOT
)
13609 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
13610 oldop
= gen_rtx_NOT (SImode
, oldop
);
13613 oldop
= lowpart_subreg (SImode
, op
, mode
);
13619 newop
= expand_binop (SImode
, and_optab
,
13620 oldop
, GEN_INT (imask
), NULL_RTX
,
13621 1, OPTAB_LIB_WIDEN
);
13622 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
13626 newop
= expand_binop (SImode
, ior_optab
,
13627 oldop
, GEN_INT (~imask
), NULL_RTX
,
13628 1, OPTAB_LIB_WIDEN
);
13629 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
13637 newop
= expand_binop (SImode
, and_optab
,
13638 oldop
, GEN_INT (imask
), NULL_RTX
,
13639 1, OPTAB_LIB_WIDEN
);
13640 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
13642 mask
= gen_reg_rtx (SImode
);
13643 emit_move_insn (mask
, GEN_INT (imask
));
13644 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
13647 newop
= gen_rtx_PLUS (SImode
, m
, newop
);
13649 newop
= gen_rtx_MINUS (SImode
, m
, newop
);
13650 newop
= gen_rtx_AND (SImode
, newop
, mask
);
13651 newop
= gen_rtx_IOR (SImode
, newop
,
13652 gen_rtx_AND (SImode
,
13653 gen_rtx_NOT (SImode
, mask
),
13659 gcc_unreachable ();
13662 if (GET_CODE (m
) == NOT
)
13666 mask
= gen_reg_rtx (SImode
);
13667 emit_move_insn (mask
, GEN_INT (imask
));
13668 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
13670 xorm
= gen_rtx_XOR (SImode
, used_m
, mask
);
13671 /* Depending on the value of 'op', the XOR or the operation might
13672 be able to be simplified away. */
13673 newop
= simplify_gen_binary (code
, SImode
, xorm
, newop
);
13676 used_mode
= SImode
;
13677 before
= gen_reg_rtx (used_mode
);
13678 after
= gen_reg_rtx (used_mode
);
13683 before
= before_param
;
13684 after
= after_param
;
13686 if (before
== NULL_RTX
)
13687 before
= gen_reg_rtx (used_mode
);
13688 if (after
== NULL_RTX
)
13689 after
= gen_reg_rtx (used_mode
);
13692 if ((code
== PLUS
|| code
== MINUS
|| GET_CODE (m
) == NOT
)
13693 && used_mode
!= mode
)
13694 the_op
= op
; /* Computed above. */
13695 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
13696 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
13698 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
13700 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
13701 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
13702 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
13703 gen_rtx_UNSPEC (used_mode
,
13704 gen_rtvec (1, the_op
),
13706 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
13708 if ((code
== PLUS
|| code
== MINUS
) && used_mode
!= mode
)
13709 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
13710 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
13712 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
13713 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
13715 /* Shift and mask the return values properly. */
13716 if (used_mode
!= mode
&& before_param
)
13718 emit_insn (gen_lshrsi3 (before
, before
, shift
));
13719 convert_move (before_param
, before
, 1);
13722 if (used_mode
!= mode
&& after_param
)
13724 emit_insn (gen_lshrsi3 (after
, after
, shift
));
13725 convert_move (after_param
, after
, 1);
13728 /* The previous sequence will end with a branch that's dependent on
13729 the conditional store, so placing an isync will ensure that no
13730 other instructions (especially, no load or store instructions)
13731 can start before the atomic operation completes. */
13733 emit_insn (gen_isync ());
13736 /* A subroutine of the atomic operation splitters. Jump to LABEL if
13737 COND is true. Mark the jump as unlikely to be taken. */
13740 emit_unlikely_jump (rtx cond
, rtx label
)
13742 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
13745 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
13746 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
13747 REG_NOTES (x
) = gen_rtx_EXPR_LIST (REG_BR_PROB
, very_unlikely
, NULL_RTX
);
13750 /* A subroutine of the atomic operation splitters. Emit a load-locked
13751 instruction in MODE. */
13754 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
13756 rtx (*fn
) (rtx
, rtx
) = NULL
;
13757 if (mode
== SImode
)
13758 fn
= gen_load_locked_si
;
13759 else if (mode
== DImode
)
13760 fn
= gen_load_locked_di
;
13761 emit_insn (fn (reg
, mem
));
13764 /* A subroutine of the atomic operation splitters. Emit a store-conditional
13765 instruction in MODE. */
13768 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
13770 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
13771 if (mode
== SImode
)
13772 fn
= gen_store_conditional_si
;
13773 else if (mode
== DImode
)
13774 fn
= gen_store_conditional_di
;
13776 /* Emit sync before stwcx. to address PPC405 Erratum. */
13777 if (PPC405_ERRATUM77
)
13778 emit_insn (gen_memory_barrier ());
13780 emit_insn (fn (res
, mem
, val
));
13783 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
13784 to perform. MEM is the memory on which to operate. VAL is the second
13785 operand of the binary operator. BEFORE and AFTER are optional locations to
13786 return the value of MEM either before of after the operation. SCRATCH is
13787 a scratch register. */
13790 rs6000_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
13791 rtx before
, rtx after
, rtx scratch
)
13793 enum machine_mode mode
= GET_MODE (mem
);
13794 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
13796 emit_insn (gen_memory_barrier ());
13798 label
= gen_label_rtx ();
13799 emit_label (label
);
13800 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
13802 if (before
== NULL_RTX
)
13804 emit_load_locked (mode
, before
, mem
);
13807 x
= gen_rtx_AND (mode
, gen_rtx_NOT (mode
, before
), val
);
13808 else if (code
== AND
)
13809 x
= gen_rtx_UNSPEC (mode
, gen_rtvec (2, before
, val
), UNSPEC_AND
);
13811 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
13813 if (after
!= NULL_RTX
)
13814 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
13815 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
13817 emit_store_conditional (mode
, cond
, mem
, scratch
);
13819 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
13820 emit_unlikely_jump (x
, label
);
13822 emit_insn (gen_isync ());
13825 /* Expand an atomic compare and swap operation. MEM is the memory on which
13826 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
13827 value to be stored. SCRATCH is a scratch GPR. */
13830 rs6000_split_compare_and_swap (rtx retval
, rtx mem
, rtx oldval
, rtx newval
,
13833 enum machine_mode mode
= GET_MODE (mem
);
13834 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
13836 emit_insn (gen_memory_barrier ());
13838 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
13839 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
13840 emit_label (XEXP (label1
, 0));
13842 emit_load_locked (mode
, retval
, mem
);
13844 x
= gen_rtx_COMPARE (CCmode
, retval
, oldval
);
13845 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
13847 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
13848 emit_unlikely_jump (x
, label2
);
13850 emit_move_insn (scratch
, newval
);
13851 emit_store_conditional (mode
, cond
, mem
, scratch
);
13853 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
13854 emit_unlikely_jump (x
, label1
);
13856 emit_insn (gen_isync ());
13857 emit_label (XEXP (label2
, 0));
13860 /* Expand an atomic test and set operation. MEM is the memory on which
13861 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
13864 rs6000_split_lock_test_and_set (rtx retval
, rtx mem
, rtx val
, rtx scratch
)
13866 enum machine_mode mode
= GET_MODE (mem
);
13867 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
13869 emit_insn (gen_memory_barrier ());
13871 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
13872 emit_label (XEXP (label
, 0));
13874 emit_load_locked (mode
, retval
, mem
);
13875 emit_move_insn (scratch
, val
);
13876 emit_store_conditional (mode
, cond
, mem
, scratch
);
13878 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
13879 emit_unlikely_jump (x
, label
);
13881 emit_insn (gen_isync ());
13885 rs6000_expand_compare_and_swapqhi (rtx dst
, rtx mem
, rtx oldval
, rtx newval
)
13887 enum machine_mode mode
= GET_MODE (mem
);
13888 rtx addrSI
, align
, wdst
, shift
, mask
;
13889 HOST_WIDE_INT shift_mask
= mode
== QImode
? 0x18 : 0x10;
13890 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
13892 /* Shift amount for subword relative to aligned word. */
13893 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
, XEXP (mem
, 0)));
13894 shift
= gen_reg_rtx (SImode
);
13895 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
13896 GEN_INT (shift_mask
)));
13897 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
13899 /* Shift and mask old value into position within word. */
13900 oldval
= convert_modes (SImode
, mode
, oldval
, 1);
13901 oldval
= expand_binop (SImode
, and_optab
,
13902 oldval
, GEN_INT (imask
), NULL_RTX
,
13903 1, OPTAB_LIB_WIDEN
);
13904 emit_insn (gen_ashlsi3 (oldval
, oldval
, shift
));
13906 /* Shift and mask new value into position within word. */
13907 newval
= convert_modes (SImode
, mode
, newval
, 1);
13908 newval
= expand_binop (SImode
, and_optab
,
13909 newval
, GEN_INT (imask
), NULL_RTX
,
13910 1, OPTAB_LIB_WIDEN
);
13911 emit_insn (gen_ashlsi3 (newval
, newval
, shift
));
13913 /* Mask for insertion. */
13914 mask
= gen_reg_rtx (SImode
);
13915 emit_move_insn (mask
, GEN_INT (imask
));
13916 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
13918 /* Address of aligned word containing subword. */
13919 align
= expand_binop (Pmode
, and_optab
, XEXP (mem
, 0), GEN_INT (-4),
13920 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
13921 mem
= change_address (mem
, SImode
, align
);
13922 set_mem_align (mem
, 32);
13923 MEM_VOLATILE_P (mem
) = 1;
13925 wdst
= gen_reg_rtx (SImode
);
13926 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst
, mask
,
13927 oldval
, newval
, mem
));
13929 /* Shift the result back. */
13930 emit_insn (gen_lshrsi3 (wdst
, wdst
, shift
));
13932 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
13936 rs6000_split_compare_and_swapqhi (rtx dest
, rtx mask
,
13937 rtx oldval
, rtx newval
, rtx mem
,
13940 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
13942 emit_insn (gen_memory_barrier ());
13943 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
13944 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
13945 emit_label (XEXP (label1
, 0));
13947 emit_load_locked (SImode
, scratch
, mem
);
13949 /* Mask subword within loaded value for comparison with oldval.
13950 Use UNSPEC_AND to avoid clobber.*/
13951 emit_insn (gen_rtx_SET (SImode
, dest
,
13952 gen_rtx_UNSPEC (SImode
,
13953 gen_rtvec (2, scratch
, mask
),
13956 x
= gen_rtx_COMPARE (CCmode
, dest
, oldval
);
13957 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
13959 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
13960 emit_unlikely_jump (x
, label2
);
13962 /* Clear subword within loaded value for insertion of new value. */
13963 emit_insn (gen_rtx_SET (SImode
, scratch
,
13964 gen_rtx_AND (SImode
,
13965 gen_rtx_NOT (SImode
, mask
), scratch
)));
13966 emit_insn (gen_iorsi3 (scratch
, scratch
, newval
));
13967 emit_store_conditional (SImode
, cond
, mem
, scratch
);
13969 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
13970 emit_unlikely_jump (x
, label1
);
13972 emit_insn (gen_isync ());
13973 emit_label (XEXP (label2
, 0));
13977 /* Emit instructions to move SRC to DST. Called by splitters for
13978 multi-register moves. It will emit at most one instruction for
13979 each register that is accessed; that is, it won't emit li/lis pairs
13980 (or equivalent for 64-bit code). One of SRC or DST must be a hard
13984 rs6000_split_multireg_move (rtx dst
, rtx src
)
13986 /* The register number of the first register being moved. */
13988 /* The mode that is to be moved. */
13989 enum machine_mode mode
;
13990 /* The mode that the move is being done in, and its size. */
13991 enum machine_mode reg_mode
;
13993 /* The number of registers that will be moved. */
13996 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
13997 mode
= GET_MODE (dst
);
13998 nregs
= hard_regno_nregs
[reg
][mode
];
13999 if (FP_REGNO_P (reg
))
14000 reg_mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
: DFmode
;
14001 else if (ALTIVEC_REGNO_P (reg
))
14002 reg_mode
= V16QImode
;
14003 else if (TARGET_E500_DOUBLE
&& (mode
== TFmode
|| mode
== TDmode
))
14004 reg_mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
: DFmode
;
14006 reg_mode
= word_mode
;
14007 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
14009 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
14011 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
14013 /* Move register range backwards, if we might have destructive
14016 for (i
= nregs
- 1; i
>= 0; i
--)
14017 emit_insn (gen_rtx_SET (VOIDmode
,
14018 simplify_gen_subreg (reg_mode
, dst
, mode
,
14019 i
* reg_mode_size
),
14020 simplify_gen_subreg (reg_mode
, src
, mode
,
14021 i
* reg_mode_size
)));
14027 bool used_update
= false;
14029 if (MEM_P (src
) && INT_REGNO_P (reg
))
14033 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
14034 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
14037 breg
= XEXP (XEXP (src
, 0), 0);
14038 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
14039 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
14040 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
14041 emit_insn (TARGET_32BIT
14042 ? gen_addsi3 (breg
, breg
, delta_rtx
)
14043 : gen_adddi3 (breg
, breg
, delta_rtx
));
14044 src
= replace_equiv_address (src
, breg
);
14046 else if (! rs6000_offsettable_memref_p (src
))
14049 basereg
= gen_rtx_REG (Pmode
, reg
);
14050 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
14051 src
= replace_equiv_address (src
, basereg
);
14054 breg
= XEXP (src
, 0);
14055 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
14056 breg
= XEXP (breg
, 0);
14058 /* If the base register we are using to address memory is
14059 also a destination reg, then change that register last. */
14061 && REGNO (breg
) >= REGNO (dst
)
14062 && REGNO (breg
) < REGNO (dst
) + nregs
)
14063 j
= REGNO (breg
) - REGNO (dst
);
14066 if (GET_CODE (dst
) == MEM
&& INT_REGNO_P (reg
))
14070 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
14071 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
14074 breg
= XEXP (XEXP (dst
, 0), 0);
14075 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
14076 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
14077 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
14079 /* We have to update the breg before doing the store.
14080 Use store with update, if available. */
14084 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
14085 emit_insn (TARGET_32BIT
14086 ? (TARGET_POWERPC64
14087 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
14088 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
14089 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
14090 used_update
= true;
14093 emit_insn (TARGET_32BIT
14094 ? gen_addsi3 (breg
, breg
, delta_rtx
)
14095 : gen_adddi3 (breg
, breg
, delta_rtx
));
14096 dst
= replace_equiv_address (dst
, breg
);
14099 gcc_assert (rs6000_offsettable_memref_p (dst
));
14102 for (i
= 0; i
< nregs
; i
++)
14104 /* Calculate index to next subword. */
14109 /* If compiler already emitted move of first word by
14110 store with update, no need to do anything. */
14111 if (j
== 0 && used_update
)
14114 emit_insn (gen_rtx_SET (VOIDmode
,
14115 simplify_gen_subreg (reg_mode
, dst
, mode
,
14116 j
* reg_mode_size
),
14117 simplify_gen_subreg (reg_mode
, src
, mode
,
14118 j
* reg_mode_size
)));
14124 /* This page contains routines that are used to determine what the
14125 function prologue and epilogue code will do and write them out. */
14127 /* Return the first fixed-point register that is required to be
14128 saved. 32 if none. */
14131 first_reg_to_save (void)
14135 /* Find lowest numbered live register. */
14136 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
14137 if (df_regs_ever_live_p (first_reg
)
14138 && (! call_used_regs
[first_reg
]
14139 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
14140 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
14141 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
14142 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
14147 && current_function_uses_pic_offset_table
14148 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
14149 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
14155 /* Similar, for FP regs. */
14158 first_fp_reg_to_save (void)
14162 /* Find lowest numbered live register. */
14163 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
14164 if (df_regs_ever_live_p (first_reg
))
14170 /* Similar, for AltiVec regs. */
14173 first_altivec_reg_to_save (void)
14177 /* Stack frame remains as is unless we are in AltiVec ABI. */
14178 if (! TARGET_ALTIVEC_ABI
)
14179 return LAST_ALTIVEC_REGNO
+ 1;
14181 /* On Darwin, the unwind routines are compiled without
14182 TARGET_ALTIVEC, and use save_world to save/restore the
14183 altivec registers when necessary. */
14184 if (DEFAULT_ABI
== ABI_DARWIN
&& current_function_calls_eh_return
14185 && ! TARGET_ALTIVEC
)
14186 return FIRST_ALTIVEC_REGNO
+ 20;
14188 /* Find lowest numbered live register. */
14189 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14190 if (df_regs_ever_live_p (i
))
14196 /* Return a 32-bit mask of the AltiVec registers we need to set in
14197 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
14198 the 32-bit word is 0. */
14200 static unsigned int
14201 compute_vrsave_mask (void)
14203 unsigned int i
, mask
= 0;
14205 /* On Darwin, the unwind routines are compiled without
14206 TARGET_ALTIVEC, and use save_world to save/restore the
14207 call-saved altivec registers when necessary. */
14208 if (DEFAULT_ABI
== ABI_DARWIN
&& current_function_calls_eh_return
14209 && ! TARGET_ALTIVEC
)
14212 /* First, find out if we use _any_ altivec registers. */
14213 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14214 if (df_regs_ever_live_p (i
))
14215 mask
|= ALTIVEC_REG_BIT (i
);
14220 /* Next, remove the argument registers from the set. These must
14221 be in the VRSAVE mask set by the caller, so we don't need to add
14222 them in again. More importantly, the mask we compute here is
14223 used to generate CLOBBERs in the set_vrsave insn, and we do not
14224 wish the argument registers to die. */
14225 for (i
= crtl
->args
.info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
14226 mask
&= ~ALTIVEC_REG_BIT (i
);
14228 /* Similarly, remove the return value from the set. */
14231 diddle_return_value (is_altivec_return_reg
, &yes
);
14233 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
14239 /* For a very restricted set of circumstances, we can cut down the
14240 size of prologues/epilogues by calling our own save/restore-the-world
14244 compute_save_world_info (rs6000_stack_t
*info_ptr
)
14246 info_ptr
->world_save_p
= 1;
14247 info_ptr
->world_save_p
14248 = (WORLD_SAVE_P (info_ptr
)
14249 && DEFAULT_ABI
== ABI_DARWIN
14250 && ! (current_function_calls_setjmp
&& flag_exceptions
)
14251 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
14252 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
14253 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
14254 && info_ptr
->cr_save_p
);
14256 /* This will not work in conjunction with sibcalls. Make sure there
14257 are none. (This check is expensive, but seldom executed.) */
14258 if (WORLD_SAVE_P (info_ptr
))
14261 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
14262 if ( GET_CODE (insn
) == CALL_INSN
14263 && SIBLING_CALL_P (insn
))
14265 info_ptr
->world_save_p
= 0;
14270 if (WORLD_SAVE_P (info_ptr
))
14272 /* Even if we're not touching VRsave, make sure there's room on the
14273 stack for it, if it looks like we're calling SAVE_WORLD, which
14274 will attempt to save it. */
14275 info_ptr
->vrsave_size
= 4;
14277 /* If we are going to save the world, we need to save the link register too. */
14278 info_ptr
->lr_save_p
= 1;
14280 /* "Save" the VRsave register too if we're saving the world. */
14281 if (info_ptr
->vrsave_mask
== 0)
14282 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
14284 /* Because the Darwin register save/restore routines only handle
14285 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
14287 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
14288 && (info_ptr
->first_altivec_reg_save
14289 >= FIRST_SAVED_ALTIVEC_REGNO
));
14296 is_altivec_return_reg (rtx reg
, void *xyes
)
14298 bool *yes
= (bool *) xyes
;
14299 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
14304 /* Calculate the stack information for the current function. This is
14305 complicated by having two separate calling sequences, the AIX calling
14306 sequence and the V.4 calling sequence.
14308 AIX (and Darwin/Mac OS X) stack frames look like:
14310 SP----> +---------------------------------------+
14311 | back chain to caller | 0 0
14312 +---------------------------------------+
14313 | saved CR | 4 8 (8-11)
14314 +---------------------------------------+
14316 +---------------------------------------+
14317 | reserved for compilers | 12 24
14318 +---------------------------------------+
14319 | reserved for binders | 16 32
14320 +---------------------------------------+
14321 | saved TOC pointer | 20 40
14322 +---------------------------------------+
14323 | Parameter save area (P) | 24 48
14324 +---------------------------------------+
14325 | Alloca space (A) | 24+P etc.
14326 +---------------------------------------+
14327 | Local variable space (L) | 24+P+A
14328 +---------------------------------------+
14329 | Float/int conversion temporary (X) | 24+P+A+L
14330 +---------------------------------------+
14331 | Save area for AltiVec registers (W) | 24+P+A+L+X
14332 +---------------------------------------+
14333 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
14334 +---------------------------------------+
14335 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
14336 +---------------------------------------+
14337 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
14338 +---------------------------------------+
14339 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
14340 +---------------------------------------+
14341 old SP->| back chain to caller's caller |
14342 +---------------------------------------+
14344 The required alignment for AIX configurations is two words (i.e., 8
14348 V.4 stack frames look like:
14350 SP----> +---------------------------------------+
14351 | back chain to caller | 0
14352 +---------------------------------------+
14353 | caller's saved LR | 4
14354 +---------------------------------------+
14355 | Parameter save area (P) | 8
14356 +---------------------------------------+
14357 | Alloca space (A) | 8+P
14358 +---------------------------------------+
14359 | Varargs save area (V) | 8+P+A
14360 +---------------------------------------+
14361 | Local variable space (L) | 8+P+A+V
14362 +---------------------------------------+
14363 | Float/int conversion temporary (X) | 8+P+A+V+L
14364 +---------------------------------------+
14365 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
14366 +---------------------------------------+
14367 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
14368 +---------------------------------------+
14369 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
14370 +---------------------------------------+
14371 | SPE: area for 64-bit GP registers |
14372 +---------------------------------------+
14373 | SPE alignment padding |
14374 +---------------------------------------+
14375 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
14376 +---------------------------------------+
14377 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
14378 +---------------------------------------+
14379 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
14380 +---------------------------------------+
14381 old SP->| back chain to caller's caller |
14382 +---------------------------------------+
14384 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
14385 given. (But note below and in sysv4.h that we require only 8 and
14386 may round up the size of our stack frame anyways. The historical
14387 reason is early versions of powerpc-linux which didn't properly
14388 align the stack at program startup. A happy side-effect is that
14389 -mno-eabi libraries can be used with -meabi programs.)
14391 The EABI configuration defaults to the V.4 layout. However,
14392 the stack alignment requirements may differ. If -mno-eabi is not
14393 given, the required stack alignment is 8 bytes; if -mno-eabi is
14394 given, the required alignment is 16 bytes. (But see V.4 comment
14397 #ifndef ABI_STACK_BOUNDARY
14398 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
14401 static rs6000_stack_t
*
14402 rs6000_stack_info (void)
14404 static rs6000_stack_t info
;
14405 rs6000_stack_t
*info_ptr
= &info
;
14406 int reg_size
= TARGET_32BIT
? 4 : 8;
14410 HOST_WIDE_INT non_fixed_size
;
14412 memset (&info
, 0, sizeof (info
));
14416 /* Cache value so we don't rescan instruction chain over and over. */
14417 if (cfun
->machine
->insn_chain_scanned_p
== 0)
14418 cfun
->machine
->insn_chain_scanned_p
14419 = spe_func_has_64bit_regs_p () + 1;
14420 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
14423 /* Select which calling sequence. */
14424 info_ptr
->abi
= DEFAULT_ABI
;
14426 /* Calculate which registers need to be saved & save area size. */
14427 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
14428 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
14429 even if it currently looks like we won't. Reload may need it to
14430 get at a constant; if so, it will have already created a constant
14431 pool entry for it. */
14432 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
14433 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
14434 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
14435 && current_function_uses_const_pool
14436 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
14437 first_gp
= RS6000_PIC_OFFSET_TABLE_REGNUM
;
14439 first_gp
= info_ptr
->first_gp_reg_save
;
14441 info_ptr
->gp_size
= reg_size
* (32 - first_gp
);
14443 /* For the SPE, we have an additional upper 32-bits on each GPR.
14444 Ideally we should save the entire 64-bits only when the upper
14445 half is used in SIMD instructions. Since we only record
14446 registers live (not the size they are used in), this proves
14447 difficult because we'd have to traverse the instruction chain at
14448 the right time, taking reload into account. This is a real pain,
14449 so we opt to save the GPRs in 64-bits always if but one register
14450 gets used in 64-bits. Otherwise, all the registers in the frame
14451 get saved in 32-bits.
14453 So... since when we save all GPRs (except the SP) in 64-bits, the
14454 traditional GP save area will be empty. */
14455 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
14456 info_ptr
->gp_size
= 0;
14458 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
14459 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
14461 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
14462 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
14463 - info_ptr
->first_altivec_reg_save
);
14465 /* Does this function call anything? */
14466 info_ptr
->calls_p
= (! current_function_is_leaf
14467 || cfun
->machine
->ra_needs_full_frame
);
14469 /* Determine if we need to save the link register. */
14470 if ((DEFAULT_ABI
== ABI_AIX
14471 && current_function_profile
14472 && !TARGET_PROFILE_KERNEL
)
14473 #ifdef TARGET_RELOCATABLE
14474 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
14476 || (info_ptr
->first_fp_reg_save
!= 64
14477 && !FP_SAVE_INLINE (info_ptr
->first_fp_reg_save
))
14478 || (DEFAULT_ABI
== ABI_V4
&& current_function_calls_alloca
)
14479 || info_ptr
->calls_p
14480 || rs6000_ra_ever_killed ())
14482 info_ptr
->lr_save_p
= 1;
14483 df_set_regs_ever_live (LR_REGNO
, true);
14486 /* Determine if we need to save the condition code registers. */
14487 if (df_regs_ever_live_p (CR2_REGNO
)
14488 || df_regs_ever_live_p (CR3_REGNO
)
14489 || df_regs_ever_live_p (CR4_REGNO
))
14491 info_ptr
->cr_save_p
= 1;
14492 if (DEFAULT_ABI
== ABI_V4
)
14493 info_ptr
->cr_size
= reg_size
;
14496 /* If the current function calls __builtin_eh_return, then we need
14497 to allocate stack space for registers that will hold data for
14498 the exception handler. */
14499 if (current_function_calls_eh_return
)
14502 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
14505 /* SPE saves EH registers in 64-bits. */
14506 ehrd_size
= i
* (TARGET_SPE_ABI
14507 && info_ptr
->spe_64bit_regs_used
!= 0
14508 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
14513 /* Determine various sizes. */
14514 info_ptr
->reg_size
= reg_size
;
14515 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
14516 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
14517 info_ptr
->parm_size
= RS6000_ALIGN (crtl
->outgoing_args_size
,
14518 TARGET_ALTIVEC
? 16 : 8);
14519 if (FRAME_GROWS_DOWNWARD
)
14520 info_ptr
->vars_size
14521 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
14522 + info_ptr
->parm_size
,
14523 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
14524 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
14525 + info_ptr
->parm_size
);
14527 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
14528 info_ptr
->spe_gp_size
= 8 * (32 - first_gp
);
14530 info_ptr
->spe_gp_size
= 0;
14532 if (TARGET_ALTIVEC_ABI
)
14533 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
14535 info_ptr
->vrsave_mask
= 0;
14537 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
14538 info_ptr
->vrsave_size
= 4;
14540 info_ptr
->vrsave_size
= 0;
14542 compute_save_world_info (info_ptr
);
14544 /* Calculate the offsets. */
14545 switch (DEFAULT_ABI
)
14549 gcc_unreachable ();
14553 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
14554 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
14556 if (TARGET_ALTIVEC_ABI
)
14558 info_ptr
->vrsave_save_offset
14559 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
14561 /* Align stack so vector save area is on a quadword boundary.
14562 The padding goes above the vectors. */
14563 if (info_ptr
->altivec_size
!= 0)
14564 info_ptr
->altivec_padding_size
14565 = info_ptr
->vrsave_save_offset
& 0xF;
14567 info_ptr
->altivec_padding_size
= 0;
14569 info_ptr
->altivec_save_offset
14570 = info_ptr
->vrsave_save_offset
14571 - info_ptr
->altivec_padding_size
14572 - info_ptr
->altivec_size
;
14573 gcc_assert (info_ptr
->altivec_size
== 0
14574 || info_ptr
->altivec_save_offset
% 16 == 0);
14576 /* Adjust for AltiVec case. */
14577 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
14580 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
14581 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
14582 info_ptr
->lr_save_offset
= 2*reg_size
;
14586 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
14587 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
14588 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
14590 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
14592 /* Align stack so SPE GPR save area is aligned on a
14593 double-word boundary. */
14594 if (info_ptr
->spe_gp_size
!= 0)
14595 info_ptr
->spe_padding_size
14596 = 8 - (-info_ptr
->cr_save_offset
% 8);
14598 info_ptr
->spe_padding_size
= 0;
14600 info_ptr
->spe_gp_save_offset
14601 = info_ptr
->cr_save_offset
14602 - info_ptr
->spe_padding_size
14603 - info_ptr
->spe_gp_size
;
14605 /* Adjust for SPE case. */
14606 info_ptr
->ehrd_offset
= info_ptr
->spe_gp_save_offset
;
14608 else if (TARGET_ALTIVEC_ABI
)
14610 info_ptr
->vrsave_save_offset
14611 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
14613 /* Align stack so vector save area is on a quadword boundary. */
14614 if (info_ptr
->altivec_size
!= 0)
14615 info_ptr
->altivec_padding_size
14616 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
14618 info_ptr
->altivec_padding_size
= 0;
14620 info_ptr
->altivec_save_offset
14621 = info_ptr
->vrsave_save_offset
14622 - info_ptr
->altivec_padding_size
14623 - info_ptr
->altivec_size
;
14625 /* Adjust for AltiVec case. */
14626 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
;
14629 info_ptr
->ehrd_offset
= info_ptr
->cr_save_offset
;
14630 info_ptr
->ehrd_offset
-= ehrd_size
;
14631 info_ptr
->lr_save_offset
= reg_size
;
14635 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
14636 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
14637 + info_ptr
->gp_size
14638 + info_ptr
->altivec_size
14639 + info_ptr
->altivec_padding_size
14640 + info_ptr
->spe_gp_size
14641 + info_ptr
->spe_padding_size
14643 + info_ptr
->cr_size
14644 + info_ptr
->vrsave_size
,
14647 non_fixed_size
= (info_ptr
->vars_size
14648 + info_ptr
->parm_size
14649 + info_ptr
->save_size
);
14651 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
14652 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
14654 /* Determine if we need to allocate any stack frame:
14656 For AIX we need to push the stack if a frame pointer is needed
14657 (because the stack might be dynamically adjusted), if we are
14658 debugging, if we make calls, or if the sum of fp_save, gp_save,
14659 and local variables are more than the space needed to save all
14660 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
14661 + 18*8 = 288 (GPR13 reserved).
14663 For V.4 we don't have the stack cushion that AIX uses, but assume
14664 that the debugger can handle stackless frames. */
14666 if (info_ptr
->calls_p
)
14667 info_ptr
->push_p
= 1;
14669 else if (DEFAULT_ABI
== ABI_V4
)
14670 info_ptr
->push_p
= non_fixed_size
!= 0;
14672 else if (frame_pointer_needed
)
14673 info_ptr
->push_p
= 1;
14675 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
14676 info_ptr
->push_p
= 1;
14679 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
14681 /* Zero offsets if we're not saving those registers. */
14682 if (info_ptr
->fp_size
== 0)
14683 info_ptr
->fp_save_offset
= 0;
14685 if (info_ptr
->gp_size
== 0)
14686 info_ptr
->gp_save_offset
= 0;
14688 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
14689 info_ptr
->altivec_save_offset
= 0;
14691 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
14692 info_ptr
->vrsave_save_offset
= 0;
14694 if (! TARGET_SPE_ABI
14695 || info_ptr
->spe_64bit_regs_used
== 0
14696 || info_ptr
->spe_gp_size
== 0)
14697 info_ptr
->spe_gp_save_offset
= 0;
14699 if (! info_ptr
->lr_save_p
)
14700 info_ptr
->lr_save_offset
= 0;
14702 if (! info_ptr
->cr_save_p
)
14703 info_ptr
->cr_save_offset
= 0;
14708 /* Return true if the current function uses any GPRs in 64-bit SIMD
14712 spe_func_has_64bit_regs_p (void)
14716 /* Functions that save and restore all the call-saved registers will
14717 need to save/restore the registers in 64-bits. */
14718 if (current_function_calls_eh_return
14719 || current_function_calls_setjmp
14720 || current_function_has_nonlocal_goto
)
14723 insns
= get_insns ();
14725 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
14731 /* FIXME: This should be implemented with attributes...
14733 (set_attr "spe64" "true")....then,
14734 if (get_spe64(insn)) return true;
14736 It's the only reliable way to do the stuff below. */
14738 i
= PATTERN (insn
);
14739 if (GET_CODE (i
) == SET
)
14741 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
14743 if (SPE_VECTOR_MODE (mode
))
14745 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
14746 || mode
== DDmode
|| mode
== TDmode
))
14756 debug_stack_info (rs6000_stack_t
*info
)
14758 const char *abi_string
;
14761 info
= rs6000_stack_info ();
14763 fprintf (stderr
, "\nStack information for function %s:\n",
14764 ((current_function_decl
&& DECL_NAME (current_function_decl
))
14765 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
14770 default: abi_string
= "Unknown"; break;
14771 case ABI_NONE
: abi_string
= "NONE"; break;
14772 case ABI_AIX
: abi_string
= "AIX"; break;
14773 case ABI_DARWIN
: abi_string
= "Darwin"; break;
14774 case ABI_V4
: abi_string
= "V.4"; break;
14777 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
14779 if (TARGET_ALTIVEC_ABI
)
14780 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
14782 if (TARGET_SPE_ABI
)
14783 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
14785 if (info
->first_gp_reg_save
!= 32)
14786 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
14788 if (info
->first_fp_reg_save
!= 64)
14789 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
14791 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
14792 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
14793 info
->first_altivec_reg_save
);
14795 if (info
->lr_save_p
)
14796 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
14798 if (info
->cr_save_p
)
14799 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
14801 if (info
->vrsave_mask
)
14802 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
14805 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
14808 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
14810 if (info
->gp_save_offset
)
14811 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
14813 if (info
->fp_save_offset
)
14814 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
14816 if (info
->altivec_save_offset
)
14817 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
14818 info
->altivec_save_offset
);
14820 if (info
->spe_gp_save_offset
)
14821 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
14822 info
->spe_gp_save_offset
);
14824 if (info
->vrsave_save_offset
)
14825 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
14826 info
->vrsave_save_offset
);
14828 if (info
->lr_save_offset
)
14829 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
14831 if (info
->cr_save_offset
)
14832 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
14834 if (info
->varargs_save_offset
)
14835 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
14837 if (info
->total_size
)
14838 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
14841 if (info
->vars_size
)
14842 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
14845 if (info
->parm_size
)
14846 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
14848 if (info
->fixed_size
)
14849 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
14852 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
14854 if (info
->spe_gp_size
)
14855 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
14858 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
14860 if (info
->altivec_size
)
14861 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
14863 if (info
->vrsave_size
)
14864 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
14866 if (info
->altivec_padding_size
)
14867 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
14868 info
->altivec_padding_size
);
14870 if (info
->spe_padding_size
)
14871 fprintf (stderr
, "\tspe_padding_size = %5d\n",
14872 info
->spe_padding_size
);
14875 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
14877 if (info
->save_size
)
14878 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
14880 if (info
->reg_size
!= 4)
14881 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
14883 fprintf (stderr
, "\n");
14887 rs6000_return_addr (int count
, rtx frame
)
14889 /* Currently we don't optimize very well between prolog and body
14890 code and for PIC code the code can be actually quite bad, so
14891 don't try to be too clever here. */
14892 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
14894 cfun
->machine
->ra_needs_full_frame
= 1;
14901 plus_constant (copy_to_reg
14902 (gen_rtx_MEM (Pmode
,
14903 memory_address (Pmode
, frame
))),
14904 RETURN_ADDRESS_OFFSET
)));
14907 cfun
->machine
->ra_need_lr
= 1;
14908 return get_hard_reg_initial_val (Pmode
, LR_REGNO
);
14911 /* Say whether a function is a candidate for sibcall handling or not.
14912 We do not allow indirect calls to be optimized into sibling calls.
14913 Also, we can't do it if there are any vector parameters; there's
14914 nowhere to put the VRsave code so it works; note that functions with
14915 vector parameters are required to have a prototype, so the argument
14916 type info must be available here. (The tail recursion case can work
14917 with vector parameters, but there's no way to distinguish here.) */
14919 rs6000_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
14924 if (TARGET_ALTIVEC_VRSAVE
)
14926 for (type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
14927 type
; type
= TREE_CHAIN (type
))
14929 if (TREE_CODE (TREE_VALUE (type
)) == VECTOR_TYPE
)
14933 if (DEFAULT_ABI
== ABI_DARWIN
14934 || ((*targetm
.binds_local_p
) (decl
)
14935 && (DEFAULT_ABI
!= ABI_AIX
|| !DECL_EXTERNAL (decl
))))
14937 tree attr_list
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
14939 if (!lookup_attribute ("longcall", attr_list
)
14940 || lookup_attribute ("shortcall", attr_list
))
14947 /* NULL if INSN insn is valid within a low-overhead loop.
14948 Otherwise return why doloop cannot be applied.
14949 PowerPC uses the COUNT register for branch on table instructions. */
14951 static const char *
14952 rs6000_invalid_within_doloop (const_rtx insn
)
14955 return "Function call in the loop.";
14958 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
14959 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
14960 return "Computed branch in the loop.";
14966 rs6000_ra_ever_killed (void)
14972 if (current_function_is_thunk
)
14975 /* regs_ever_live has LR marked as used if any sibcalls are present,
14976 but this should not force saving and restoring in the
14977 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
14978 clobbers LR, so that is inappropriate. */
14980 /* Also, the prologue can generate a store into LR that
14981 doesn't really count, like this:
14984 bcl to set PIC register
14988 When we're called from the epilogue, we need to avoid counting
14989 this as a store. */
14991 push_topmost_sequence ();
14992 top
= get_insns ();
14993 pop_topmost_sequence ();
14994 reg
= gen_rtx_REG (Pmode
, LR_REGNO
);
14996 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
15002 if (!SIBLING_CALL_P (insn
))
15005 else if (find_regno_note (insn
, REG_INC
, LR_REGNO
))
15007 else if (set_of (reg
, insn
) != NULL_RTX
15008 && !prologue_epilogue_contains (insn
))
15015 /* Emit instructions needed to load the TOC register.
15016 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
15017 a constant pool; or for SVR4 -fpic. */
15020 rs6000_emit_load_toc_table (int fromprolog
)
15023 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
15025 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
15028 rtx lab
, tmp1
, tmp2
, got
;
15030 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
15031 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15033 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
15035 got
= rs6000_got_sym ();
15036 tmp1
= tmp2
= dest
;
15039 tmp1
= gen_reg_rtx (Pmode
);
15040 tmp2
= gen_reg_rtx (Pmode
);
15042 emit_insn (gen_load_toc_v4_PIC_1 (lab
));
15043 emit_move_insn (tmp1
,
15044 gen_rtx_REG (Pmode
, LR_REGNO
));
15045 emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
15046 emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
15048 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
15050 emit_insn (gen_load_toc_v4_pic_si ());
15051 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
15053 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
15056 rtx temp0
= (fromprolog
15057 ? gen_rtx_REG (Pmode
, 0)
15058 : gen_reg_rtx (Pmode
));
15064 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
15065 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15067 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
15068 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15070 emit_insn (gen_load_toc_v4_PIC_1 (symF
));
15071 emit_move_insn (dest
,
15072 gen_rtx_REG (Pmode
, LR_REGNO
));
15073 emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
, symL
, symF
));
15079 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
15080 emit_insn (gen_load_toc_v4_PIC_1b (tocsym
));
15081 emit_move_insn (dest
,
15082 gen_rtx_REG (Pmode
, LR_REGNO
));
15083 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
15085 emit_insn (gen_addsi3 (dest
, temp0
, dest
));
15087 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
15089 /* This is for AIX code running in non-PIC ELF32. */
15092 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
15093 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15095 emit_insn (gen_elf_high (dest
, realsym
));
15096 emit_insn (gen_elf_low (dest
, dest
, realsym
));
15100 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
15103 emit_insn (gen_load_toc_aix_si (dest
));
15105 emit_insn (gen_load_toc_aix_di (dest
));
15109 /* Emit instructions to restore the link register after determining where
15110 its value has been stored. */
15113 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
15115 rs6000_stack_t
*info
= rs6000_stack_info ();
15118 operands
[0] = source
;
15119 operands
[1] = scratch
;
15121 if (info
->lr_save_p
)
15123 rtx frame_rtx
= stack_pointer_rtx
;
15124 HOST_WIDE_INT sp_offset
= 0;
15127 if (frame_pointer_needed
15128 || current_function_calls_alloca
15129 || info
->total_size
> 32767)
15131 tmp
= gen_frame_mem (Pmode
, frame_rtx
);
15132 emit_move_insn (operands
[1], tmp
);
15133 frame_rtx
= operands
[1];
15135 else if (info
->push_p
)
15136 sp_offset
= info
->total_size
;
15138 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
15139 tmp
= gen_frame_mem (Pmode
, tmp
);
15140 emit_move_insn (tmp
, operands
[0]);
15143 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
), operands
[0]);
15146 static GTY(()) alias_set_type set
= -1;
15149 get_TOC_alias_set (void)
15152 set
= new_alias_set ();
15156 /* This returns nonzero if the current function uses the TOC. This is
15157 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
15158 is generated by the ABI_V4 load_toc_* patterns. */
15165 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
15168 rtx pat
= PATTERN (insn
);
15171 if (GET_CODE (pat
) == PARALLEL
)
15172 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
15174 rtx sub
= XVECEXP (pat
, 0, i
);
15175 if (GET_CODE (sub
) == USE
)
15177 sub
= XEXP (sub
, 0);
15178 if (GET_CODE (sub
) == UNSPEC
15179 && XINT (sub
, 1) == UNSPEC_TOC
)
15189 create_TOC_reference (rtx symbol
)
15191 if (!can_create_pseudo_p ())
15192 df_set_regs_ever_live (TOC_REGISTER
, true);
15193 return gen_rtx_PLUS (Pmode
,
15194 gen_rtx_REG (Pmode
, TOC_REGISTER
),
15195 gen_rtx_CONST (Pmode
,
15196 gen_rtx_MINUS (Pmode
, symbol
,
15197 gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
))));
15200 /* If _Unwind_* has been called from within the same module,
15201 toc register is not guaranteed to be saved to 40(1) on function
15202 entry. Save it there in that case. */
15205 rs6000_aix_emit_builtin_unwind_init (void)
15208 rtx stack_top
= gen_reg_rtx (Pmode
);
15209 rtx opcode_addr
= gen_reg_rtx (Pmode
);
15210 rtx opcode
= gen_reg_rtx (SImode
);
15211 rtx tocompare
= gen_reg_rtx (SImode
);
15212 rtx no_toc_save_needed
= gen_label_rtx ();
15214 mem
= gen_frame_mem (Pmode
, hard_frame_pointer_rtx
);
15215 emit_move_insn (stack_top
, mem
);
15217 mem
= gen_frame_mem (Pmode
,
15218 gen_rtx_PLUS (Pmode
, stack_top
,
15219 GEN_INT (2 * GET_MODE_SIZE (Pmode
))));
15220 emit_move_insn (opcode_addr
, mem
);
15221 emit_move_insn (opcode
, gen_rtx_MEM (SImode
, opcode_addr
));
15222 emit_move_insn (tocompare
, gen_int_mode (TARGET_32BIT
? 0x80410014
15223 : 0xE8410028, SImode
));
15225 do_compare_rtx_and_jump (opcode
, tocompare
, EQ
, 1,
15226 SImode
, NULL_RTX
, NULL_RTX
,
15227 no_toc_save_needed
);
15229 mem
= gen_frame_mem (Pmode
,
15230 gen_rtx_PLUS (Pmode
, stack_top
,
15231 GEN_INT (5 * GET_MODE_SIZE (Pmode
))));
15232 emit_move_insn (mem
, gen_rtx_REG (Pmode
, 2));
15233 emit_label (no_toc_save_needed
);
15236 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
15237 and the change to the stack pointer. */
15240 rs6000_emit_stack_tie (void)
15242 rtx mem
= gen_frame_mem (BLKmode
,
15243 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
15245 emit_insn (gen_stack_tie (mem
));
15248 /* Emit the correct code for allocating stack space, as insns.
15249 If COPY_R12, make sure a copy of the old frame is left in r12.
15250 The generated code may use hard register 0 as a temporary. */
15253 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, int copy_r12
)
15256 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
15257 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
15258 rtx todec
= gen_int_mode (-size
, Pmode
);
15260 if (INTVAL (todec
) != -size
)
15262 warning (0, "stack frame too large");
15263 emit_insn (gen_trap ());
15267 if (current_function_limit_stack
)
15269 if (REG_P (stack_limit_rtx
)
15270 && REGNO (stack_limit_rtx
) > 1
15271 && REGNO (stack_limit_rtx
) <= 31)
15273 emit_insn (TARGET_32BIT
15274 ? gen_addsi3 (tmp_reg
,
15277 : gen_adddi3 (tmp_reg
,
15281 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
15284 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
15286 && DEFAULT_ABI
== ABI_V4
)
15288 rtx toload
= gen_rtx_CONST (VOIDmode
,
15289 gen_rtx_PLUS (Pmode
,
15293 emit_insn (gen_elf_high (tmp_reg
, toload
));
15294 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
15295 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
15299 warning (0, "stack limit expression is not supported");
15302 if (copy_r12
|| ! TARGET_UPDATE
)
15303 emit_move_insn (gen_rtx_REG (Pmode
, 12), stack_reg
);
15309 /* Need a note here so that try_split doesn't get confused. */
15310 if (get_last_insn () == NULL_RTX
)
15311 emit_note (NOTE_INSN_DELETED
);
15312 insn
= emit_move_insn (tmp_reg
, todec
);
15313 try_split (PATTERN (insn
), insn
, 0);
15317 insn
= emit_insn (TARGET_32BIT
15318 ? gen_movsi_update (stack_reg
, stack_reg
,
15320 : gen_movdi_di_update (stack_reg
, stack_reg
,
15321 todec
, stack_reg
));
15325 insn
= emit_insn (TARGET_32BIT
15326 ? gen_addsi3 (stack_reg
, stack_reg
, todec
)
15327 : gen_adddi3 (stack_reg
, stack_reg
, todec
));
15328 emit_move_insn (gen_rtx_MEM (Pmode
, stack_reg
),
15329 gen_rtx_REG (Pmode
, 12));
15332 RTX_FRAME_RELATED_P (insn
) = 1;
15334 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
15335 gen_rtx_SET (VOIDmode
, stack_reg
,
15336 gen_rtx_PLUS (Pmode
, stack_reg
,
15341 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
15342 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
15343 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
15344 deduce these equivalences by itself so it wasn't necessary to hold
15345 its hand so much. */
15348 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
15349 rtx reg2
, rtx rreg
)
15353 /* copy_rtx will not make unique copies of registers, so we need to
15354 ensure we don't have unwanted sharing here. */
15356 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
15359 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
15361 real
= copy_rtx (PATTERN (insn
));
15363 if (reg2
!= NULL_RTX
)
15364 real
= replace_rtx (real
, reg2
, rreg
);
15366 real
= replace_rtx (real
, reg
,
15367 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
15368 STACK_POINTER_REGNUM
),
15371 /* We expect that 'real' is either a SET or a PARALLEL containing
15372 SETs (and possibly other stuff). In a PARALLEL, all the SETs
15373 are important so they all have to be marked RTX_FRAME_RELATED_P. */
15375 if (GET_CODE (real
) == SET
)
15379 temp
= simplify_rtx (SET_SRC (set
));
15381 SET_SRC (set
) = temp
;
15382 temp
= simplify_rtx (SET_DEST (set
));
15384 SET_DEST (set
) = temp
;
15385 if (GET_CODE (SET_DEST (set
)) == MEM
)
15387 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
15389 XEXP (SET_DEST (set
), 0) = temp
;
15396 gcc_assert (GET_CODE (real
) == PARALLEL
);
15397 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
15398 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
15400 rtx set
= XVECEXP (real
, 0, i
);
15402 temp
= simplify_rtx (SET_SRC (set
));
15404 SET_SRC (set
) = temp
;
15405 temp
= simplify_rtx (SET_DEST (set
));
15407 SET_DEST (set
) = temp
;
15408 if (GET_CODE (SET_DEST (set
)) == MEM
)
15410 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
15412 XEXP (SET_DEST (set
), 0) = temp
;
15414 RTX_FRAME_RELATED_P (set
) = 1;
15418 RTX_FRAME_RELATED_P (insn
) = 1;
15419 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
15424 /* Returns an insn that has a vrsave set operation with the
15425 appropriate CLOBBERs. */
15428 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
15431 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
15432 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
15435 = gen_rtx_SET (VOIDmode
,
15437 gen_rtx_UNSPEC_VOLATILE (SImode
,
15438 gen_rtvec (2, reg
, vrsave
),
15439 UNSPECV_SET_VRSAVE
));
15443 /* We need to clobber the registers in the mask so the scheduler
15444 does not move sets to VRSAVE before sets of AltiVec registers.
15446 However, if the function receives nonlocal gotos, reload will set
15447 all call saved registers live. We will end up with:
15449 (set (reg 999) (mem))
15450 (parallel [ (set (reg vrsave) (unspec blah))
15451 (clobber (reg 999))])
15453 The clobber will cause the store into reg 999 to be dead, and
15454 flow will attempt to delete an epilogue insn. In this case, we
15455 need an unspec use/set of the register. */
15457 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
15458 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
15460 if (!epiloguep
|| call_used_regs
[i
])
15461 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
15462 gen_rtx_REG (V4SImode
, i
));
15465 rtx reg
= gen_rtx_REG (V4SImode
, i
);
15468 = gen_rtx_SET (VOIDmode
,
15470 gen_rtx_UNSPEC (V4SImode
,
15471 gen_rtvec (1, reg
), 27));
15475 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
15477 for (i
= 0; i
< nclobs
; ++i
)
15478 XVECEXP (insn
, 0, i
) = clobs
[i
];
15483 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
15484 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
15487 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
15488 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
15490 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
15491 rtx replacea
, replaceb
;
15493 int_rtx
= GEN_INT (offset
);
15495 /* Some cases that need register indexed addressing. */
15496 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
15497 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== DDmode
))
15499 && SPE_VECTOR_MODE (mode
)
15500 && !SPE_CONST_OFFSET_OK (offset
)))
15502 /* Whomever calls us must make sure r11 is available in the
15503 flow path of instructions in the prologue. */
15504 offset_rtx
= gen_rtx_REG (Pmode
, 11);
15505 emit_move_insn (offset_rtx
, int_rtx
);
15507 replacea
= offset_rtx
;
15508 replaceb
= int_rtx
;
15512 offset_rtx
= int_rtx
;
15513 replacea
= NULL_RTX
;
15514 replaceb
= NULL_RTX
;
15517 reg
= gen_rtx_REG (mode
, regno
);
15518 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
15519 mem
= gen_frame_mem (mode
, addr
);
15521 insn
= emit_move_insn (mem
, reg
);
15523 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
15526 /* Emit an offset memory reference suitable for a frame store, while
15527 converting to a valid addressing mode. */
15530 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
15532 rtx int_rtx
, offset_rtx
;
15534 int_rtx
= GEN_INT (offset
);
15536 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
15537 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== DDmode
)))
15539 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
15540 emit_move_insn (offset_rtx
, int_rtx
);
15543 offset_rtx
= int_rtx
;
15545 return gen_frame_mem (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
15548 /* Look for user-defined global regs. We should not save and restore these,
15549 and cannot use stmw/lmw if there are any in its range. */
15552 no_global_regs_above (int first_greg
)
15555 for (i
= 0; i
< 32 - first_greg
; i
++)
15556 if (global_regs
[first_greg
+ i
])
15561 #ifndef TARGET_FIX_AND_CONTINUE
15562 #define TARGET_FIX_AND_CONTINUE 0
15565 /* Determine whether the gp REG is really used. */
15568 rs6000_reg_live_or_pic_offset_p (int reg
)
15570 return ((df_regs_ever_live_p (reg
)
15571 && (!call_used_regs
[reg
]
15572 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
15573 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
15574 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
15575 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
15576 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))));
15579 /* Emit function prologue as insns. */
15582 rs6000_emit_prologue (void)
15584 rs6000_stack_t
*info
= rs6000_stack_info ();
15585 enum machine_mode reg_mode
= Pmode
;
15586 int reg_size
= TARGET_32BIT
? 4 : 8;
15587 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
15588 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
15589 rtx frame_reg_rtx
= sp_reg_rtx
;
15590 rtx cr_save_rtx
= NULL_RTX
;
15592 int saving_FPRs_inline
;
15593 int using_store_multiple
;
15594 HOST_WIDE_INT sp_offset
= 0;
15596 if (TARGET_FIX_AND_CONTINUE
)
15598 /* gdb on darwin arranges to forward a function from the old
15599 address by modifying the first 5 instructions of the function
15600 to branch to the overriding function. This is necessary to
15601 permit function pointers that point to the old function to
15602 actually forward to the new function. */
15603 emit_insn (gen_nop ());
15604 emit_insn (gen_nop ());
15605 emit_insn (gen_nop ());
15606 emit_insn (gen_nop ());
15607 emit_insn (gen_nop ());
15610 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
15612 reg_mode
= V2SImode
;
15616 using_store_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
15617 && (!TARGET_SPE_ABI
15618 || info
->spe_64bit_regs_used
== 0)
15619 && info
->first_gp_reg_save
< 31
15620 && no_global_regs_above (info
->first_gp_reg_save
));
15621 saving_FPRs_inline
= (info
->first_fp_reg_save
== 64
15622 || FP_SAVE_INLINE (info
->first_fp_reg_save
)
15623 || current_function_calls_eh_return
15624 || cfun
->machine
->ra_need_lr
);
15626 /* For V.4, update stack before we do any saving and set back pointer. */
15627 if (! WORLD_SAVE_P (info
)
15629 && (DEFAULT_ABI
== ABI_V4
15630 || current_function_calls_eh_return
))
15632 if (info
->total_size
< 32767)
15633 sp_offset
= info
->total_size
;
15635 frame_reg_rtx
= frame_ptr_rtx
;
15636 rs6000_emit_allocate_stack (info
->total_size
,
15637 (frame_reg_rtx
!= sp_reg_rtx
15638 && (info
->cr_save_p
15640 || info
->first_fp_reg_save
< 64
15641 || info
->first_gp_reg_save
< 32
15643 if (frame_reg_rtx
!= sp_reg_rtx
)
15644 rs6000_emit_stack_tie ();
15647 /* Handle world saves specially here. */
15648 if (WORLD_SAVE_P (info
))
15655 /* save_world expects lr in r0. */
15656 reg0
= gen_rtx_REG (Pmode
, 0);
15657 if (info
->lr_save_p
)
15659 insn
= emit_move_insn (reg0
,
15660 gen_rtx_REG (Pmode
, LR_REGNO
));
15661 RTX_FRAME_RELATED_P (insn
) = 1;
15664 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
15665 assumptions about the offsets of various bits of the stack
15667 gcc_assert (info
->gp_save_offset
== -220
15668 && info
->fp_save_offset
== -144
15669 && info
->lr_save_offset
== 8
15670 && info
->cr_save_offset
== 4
15673 && (!current_function_calls_eh_return
15674 || info
->ehrd_offset
== -432)
15675 && info
->vrsave_save_offset
== -224
15676 && info
->altivec_save_offset
== -416);
15678 treg
= gen_rtx_REG (SImode
, 11);
15679 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
15681 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
15682 in R11. It also clobbers R12, so beware! */
15684 /* Preserve CR2 for save_world prologues */
15686 sz
+= 32 - info
->first_gp_reg_save
;
15687 sz
+= 64 - info
->first_fp_reg_save
;
15688 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
15689 p
= rtvec_alloc (sz
);
15691 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
15692 gen_rtx_REG (SImode
,
15694 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
15695 gen_rtx_SYMBOL_REF (Pmode
,
15697 /* We do floats first so that the instruction pattern matches
15699 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
15701 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
15702 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15703 GEN_INT (info
->fp_save_offset
15704 + sp_offset
+ 8 * i
));
15705 rtx mem
= gen_frame_mem (DFmode
, addr
);
15707 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
15709 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
15711 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
15712 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15713 GEN_INT (info
->altivec_save_offset
15714 + sp_offset
+ 16 * i
));
15715 rtx mem
= gen_frame_mem (V4SImode
, addr
);
15717 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
15719 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
15721 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
15722 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15723 GEN_INT (info
->gp_save_offset
15724 + sp_offset
+ reg_size
* i
));
15725 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15727 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
15731 /* CR register traditionally saved as CR2. */
15732 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
15733 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15734 GEN_INT (info
->cr_save_offset
15736 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15738 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
15740 /* Explain about use of R0. */
15741 if (info
->lr_save_p
)
15743 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15744 GEN_INT (info
->lr_save_offset
15746 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15748 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg0
);
15750 /* Explain what happens to the stack pointer. */
15752 rtx newval
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
, treg
);
15753 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, sp_reg_rtx
, newval
);
15756 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15757 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15758 treg
, GEN_INT (-info
->total_size
));
15759 sp_offset
= info
->total_size
;
15762 /* If we use the link register, get it into r0. */
15763 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
15765 rtx addr
, reg
, mem
;
15767 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
15768 gen_rtx_REG (Pmode
, LR_REGNO
));
15769 RTX_FRAME_RELATED_P (insn
) = 1;
15771 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15772 GEN_INT (info
->lr_save_offset
+ sp_offset
));
15773 reg
= gen_rtx_REG (Pmode
, 0);
15774 mem
= gen_rtx_MEM (Pmode
, addr
);
15775 /* This should not be of rs6000_sr_alias_set, because of
15776 __builtin_return_address. */
15778 insn
= emit_move_insn (mem
, reg
);
15779 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15780 NULL_RTX
, NULL_RTX
);
15783 /* If we need to save CR, put it into r12. */
15784 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
15788 cr_save_rtx
= gen_rtx_REG (SImode
, 12);
15789 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
15790 RTX_FRAME_RELATED_P (insn
) = 1;
15791 /* Now, there's no way that dwarf2out_frame_debug_expr is going
15792 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
15793 But that's OK. All we have to do is specify that _one_ condition
15794 code register is saved in this stack slot. The thrower's epilogue
15795 will then restore all the call-saved registers.
15796 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
15797 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
15798 gen_rtx_REG (SImode
, CR2_REGNO
));
15799 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
15804 /* Do any required saving of fpr's. If only one or two to save, do
15805 it ourselves. Otherwise, call function. */
15806 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
15809 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
15810 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
15811 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
15812 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, DFmode
,
15813 info
->first_fp_reg_save
+ i
,
15814 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
15817 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
15821 const char *alloc_rname
;
15823 p
= rtvec_alloc (2 + 64 - info
->first_fp_reg_save
);
15825 RTVEC_ELT (p
, 0) = gen_rtx_CLOBBER (VOIDmode
,
15826 gen_rtx_REG (Pmode
,
15828 sprintf (rname
, "%s%d%s", SAVE_FP_PREFIX
,
15829 info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
);
15830 alloc_rname
= ggc_strdup (rname
);
15831 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
15832 gen_rtx_SYMBOL_REF (Pmode
,
15834 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
15836 rtx addr
, reg
, mem
;
15837 reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
15838 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15839 GEN_INT (info
->fp_save_offset
15840 + sp_offset
+ 8*i
));
15841 mem
= gen_frame_mem (DFmode
, addr
);
15843 RTVEC_ELT (p
, i
+ 2) = gen_rtx_SET (VOIDmode
, mem
, reg
);
15845 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15846 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15847 NULL_RTX
, NULL_RTX
);
15850 /* Save GPRs. This is done as a PARALLEL if we are using
15851 the store-multiple instructions. */
15852 if (!WORLD_SAVE_P (info
) && using_store_multiple
)
15856 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
15857 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
15859 rtx addr
, reg
, mem
;
15860 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
15861 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15862 GEN_INT (info
->gp_save_offset
15865 mem
= gen_frame_mem (reg_mode
, addr
);
15867 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
15869 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15870 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15871 NULL_RTX
, NULL_RTX
);
15873 else if (!WORLD_SAVE_P (info
)
15875 && info
->spe_64bit_regs_used
!= 0
15876 && info
->first_gp_reg_save
!= 32)
15879 rtx spe_save_area_ptr
;
15880 int using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
15881 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
15882 && !call_used_regs
[STATIC_CHAIN_REGNUM
]);
15884 /* Determine whether we can address all of the registers that need
15885 to be saved with an offset from the stack pointer that fits in
15886 the small const field for SPE memory instructions. */
15887 int spe_regs_addressable_via_sp
15888 = SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
15889 + (32 - info
->first_gp_reg_save
- 1) * reg_size
);
15892 if (spe_regs_addressable_via_sp
)
15894 spe_save_area_ptr
= frame_reg_rtx
;
15895 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
15899 /* Make r11 point to the start of the SPE save area. We need
15900 to be careful here if r11 is holding the static chain. If
15901 it is, then temporarily save it in r0. We would use r0 as
15902 our base register here, but using r0 as a base register in
15903 loads and stores means something different from what we
15905 if (using_static_chain_p
)
15907 rtx r0
= gen_rtx_REG (Pmode
, 0);
15909 gcc_assert (info
->first_gp_reg_save
> 11);
15911 emit_move_insn (r0
, gen_rtx_REG (Pmode
, 11));
15914 spe_save_area_ptr
= gen_rtx_REG (Pmode
, 11);
15915 emit_insn (gen_addsi3 (spe_save_area_ptr
, frame_reg_rtx
,
15916 GEN_INT (info
->spe_gp_save_offset
+ sp_offset
)));
15921 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
15922 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
15924 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
15925 rtx offset
, addr
, mem
;
15927 /* We're doing all this to ensure that the offset fits into
15928 the immediate offset of 'evstdd'. */
15929 gcc_assert (SPE_CONST_OFFSET_OK (reg_size
* i
+ spe_offset
));
15931 offset
= GEN_INT (reg_size
* i
+ spe_offset
);
15932 addr
= gen_rtx_PLUS (Pmode
, spe_save_area_ptr
, offset
);
15933 mem
= gen_rtx_MEM (V2SImode
, addr
);
15935 insn
= emit_move_insn (mem
, reg
);
15937 rs6000_frame_related (insn
, spe_save_area_ptr
,
15938 info
->spe_gp_save_offset
15939 + sp_offset
+ reg_size
* i
,
15940 offset
, const0_rtx
);
15943 /* Move the static chain pointer back. */
15944 if (using_static_chain_p
&& !spe_regs_addressable_via_sp
)
15945 emit_move_insn (gen_rtx_REG (Pmode
, 11), gen_rtx_REG (Pmode
, 0));
15947 else if (!WORLD_SAVE_P (info
))
15950 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
15951 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
15953 rtx addr
, reg
, mem
;
15954 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
15956 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15957 GEN_INT (info
->gp_save_offset
15960 mem
= gen_frame_mem (reg_mode
, addr
);
15962 insn
= emit_move_insn (mem
, reg
);
15963 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15964 NULL_RTX
, NULL_RTX
);
15968 /* ??? There's no need to emit actual instructions here, but it's the
15969 easiest way to get the frame unwind information emitted. */
15970 if (current_function_calls_eh_return
)
15972 unsigned int i
, regno
;
15974 /* In AIX ABI we need to pretend we save r2 here. */
15977 rtx addr
, reg
, mem
;
15979 reg
= gen_rtx_REG (reg_mode
, 2);
15980 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15981 GEN_INT (sp_offset
+ 5 * reg_size
));
15982 mem
= gen_frame_mem (reg_mode
, addr
);
15984 insn
= emit_move_insn (mem
, reg
);
15985 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15986 NULL_RTX
, NULL_RTX
);
15987 PATTERN (insn
) = gen_blockage ();
15992 regno
= EH_RETURN_DATA_REGNO (i
);
15993 if (regno
== INVALID_REGNUM
)
15996 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
15997 info
->ehrd_offset
+ sp_offset
15998 + reg_size
* (int) i
,
16003 /* Save CR if we use any that must be preserved. */
16004 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
16006 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16007 GEN_INT (info
->cr_save_offset
+ sp_offset
));
16008 rtx mem
= gen_frame_mem (SImode
, addr
);
16009 /* See the large comment above about why CR2_REGNO is used. */
16010 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
16012 /* If r12 was used to hold the original sp, copy cr into r0 now
16014 if (REGNO (frame_reg_rtx
) == 12)
16018 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
16019 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
16020 RTX_FRAME_RELATED_P (insn
) = 1;
16021 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
16022 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
16027 insn
= emit_move_insn (mem
, cr_save_rtx
);
16029 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16030 NULL_RTX
, NULL_RTX
);
16033 /* Update stack and set back pointer unless this is V.4,
16034 for which it was done previously. */
16035 if (!WORLD_SAVE_P (info
) && info
->push_p
16036 && !(DEFAULT_ABI
== ABI_V4
|| current_function_calls_eh_return
))
16038 if (info
->total_size
< 32767)
16039 sp_offset
= info
->total_size
;
16041 frame_reg_rtx
= frame_ptr_rtx
;
16042 rs6000_emit_allocate_stack (info
->total_size
,
16043 (frame_reg_rtx
!= sp_reg_rtx
16044 && ((info
->altivec_size
!= 0)
16045 || (info
->vrsave_mask
!= 0)
16047 if (frame_reg_rtx
!= sp_reg_rtx
)
16048 rs6000_emit_stack_tie ();
16051 /* Set frame pointer, if needed. */
16052 if (frame_pointer_needed
)
16054 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
16056 RTX_FRAME_RELATED_P (insn
) = 1;
16059 /* Save AltiVec registers if needed. Save here because the red zone does
16060 not include AltiVec registers. */
16061 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
16065 /* There should be a non inline version of this, for when we
16066 are saving lots of vector registers. */
16067 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
16068 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
16070 rtx areg
, savereg
, mem
;
16073 offset
= info
->altivec_save_offset
+ sp_offset
16074 + 16 * (i
- info
->first_altivec_reg_save
);
16076 savereg
= gen_rtx_REG (V4SImode
, i
);
16078 areg
= gen_rtx_REG (Pmode
, 0);
16079 emit_move_insn (areg
, GEN_INT (offset
));
16081 /* AltiVec addressing mode is [reg+reg]. */
16082 mem
= gen_frame_mem (V4SImode
,
16083 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
16085 insn
= emit_move_insn (mem
, savereg
);
16087 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16088 areg
, GEN_INT (offset
));
16092 /* VRSAVE is a bit vector representing which AltiVec registers
16093 are used. The OS uses this to determine which vector
16094 registers to save on a context switch. We need to save
16095 VRSAVE on the stack frame, add whatever AltiVec registers we
16096 used in this function, and do the corresponding magic in the
16099 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
16100 && info
->vrsave_mask
!= 0)
16102 rtx reg
, mem
, vrsave
;
16105 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
16106 as frame_reg_rtx and r11 as the static chain pointer for
16107 nested functions. */
16108 reg
= gen_rtx_REG (SImode
, 0);
16109 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
16111 emit_insn (gen_get_vrsave_internal (reg
));
16113 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
16115 if (!WORLD_SAVE_P (info
))
16118 offset
= info
->vrsave_save_offset
+ sp_offset
;
16119 mem
= gen_frame_mem (SImode
,
16120 gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16121 GEN_INT (offset
)));
16122 insn
= emit_move_insn (mem
, reg
);
16125 /* Include the registers in the mask. */
16126 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
16128 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
16131 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
16132 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
16133 || (DEFAULT_ABI
== ABI_V4
16134 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
16135 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
)))
16137 /* If emit_load_toc_table will use the link register, we need to save
16138 it. We use R12 for this purpose because emit_load_toc_table
16139 can use register 0. This allows us to use a plain 'blr' to return
16140 from the procedure more often. */
16141 int save_LR_around_toc_setup
= (TARGET_ELF
16142 && DEFAULT_ABI
!= ABI_AIX
16144 && ! info
->lr_save_p
16145 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
16146 if (save_LR_around_toc_setup
)
16148 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
16150 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
16151 RTX_FRAME_RELATED_P (insn
) = 1;
16153 rs6000_emit_load_toc_table (TRUE
);
16155 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
16156 RTX_FRAME_RELATED_P (insn
) = 1;
16159 rs6000_emit_load_toc_table (TRUE
);
16163 if (DEFAULT_ABI
== ABI_DARWIN
16164 && flag_pic
&& current_function_uses_pic_offset_table
)
16166 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
16167 rtx src
= machopic_function_base_sym ();
16169 /* Save and restore LR locally around this call (in R0). */
16170 if (!info
->lr_save_p
)
16171 emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
);
16173 emit_insn (gen_load_macho_picbase (src
));
16175 emit_move_insn (gen_rtx_REG (Pmode
,
16176 RS6000_PIC_OFFSET_TABLE_REGNUM
),
16179 if (!info
->lr_save_p
)
16180 emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0));
16185 /* Write function prologue. */
16188 rs6000_output_function_prologue (FILE *file
,
16189 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
16191 rs6000_stack_t
*info
= rs6000_stack_info ();
16193 if (TARGET_DEBUG_STACK
)
16194 debug_stack_info (info
);
16196 /* Write .extern for any function we will call to save and restore
16198 if (info
->first_fp_reg_save
< 64
16199 && !FP_SAVE_INLINE (info
->first_fp_reg_save
))
16200 fprintf (file
, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
16201 SAVE_FP_PREFIX
, info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
,
16202 RESTORE_FP_PREFIX
, info
->first_fp_reg_save
- 32,
16203 RESTORE_FP_SUFFIX
);
16205 /* Write .extern for AIX common mode routines, if needed. */
16206 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
16208 fputs ("\t.extern __mulh\n", file
);
16209 fputs ("\t.extern __mull\n", file
);
16210 fputs ("\t.extern __divss\n", file
);
16211 fputs ("\t.extern __divus\n", file
);
16212 fputs ("\t.extern __quoss\n", file
);
16213 fputs ("\t.extern __quous\n", file
);
16214 common_mode_defined
= 1;
16217 if (! HAVE_prologue
)
16221 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
16222 the "toplevel" insn chain. */
16223 emit_note (NOTE_INSN_DELETED
);
16224 rs6000_emit_prologue ();
16225 emit_note (NOTE_INSN_DELETED
);
16227 /* Expand INSN_ADDRESSES so final() doesn't crash. */
16231 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
16233 INSN_ADDRESSES_NEW (insn
, addr
);
16238 if (TARGET_DEBUG_STACK
)
16239 debug_rtx_list (get_insns (), 100);
16240 final (get_insns (), file
, FALSE
);
16244 rs6000_pic_labelno
++;
16247 /* Emit function epilogue as insns.
16249 At present, dwarf2out_frame_debug_expr doesn't understand
16250 register restores, so we don't bother setting RTX_FRAME_RELATED_P
16251 anywhere in the epilogue. Most of the insns below would in any case
16252 need special notes to explain where r11 is in relation to the stack. */
16255 rs6000_emit_epilogue (int sibcall
)
16257 rs6000_stack_t
*info
;
16258 int restoring_FPRs_inline
;
16259 int using_load_multiple
;
16260 int using_mtcr_multiple
;
16261 int use_backchain_to_restore_sp
;
16263 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
16264 rtx frame_reg_rtx
= sp_reg_rtx
;
16265 enum machine_mode reg_mode
= Pmode
;
16266 int reg_size
= TARGET_32BIT
? 4 : 8;
16269 info
= rs6000_stack_info ();
16271 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
16273 reg_mode
= V2SImode
;
16277 using_load_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
16278 && (!TARGET_SPE_ABI
16279 || info
->spe_64bit_regs_used
== 0)
16280 && info
->first_gp_reg_save
< 31
16281 && no_global_regs_above (info
->first_gp_reg_save
));
16282 restoring_FPRs_inline
= (sibcall
16283 || current_function_calls_eh_return
16284 || info
->first_fp_reg_save
== 64
16285 || FP_SAVE_INLINE (info
->first_fp_reg_save
));
16286 use_backchain_to_restore_sp
= (frame_pointer_needed
16287 || current_function_calls_alloca
16288 || info
->total_size
> 32767);
16289 using_mtcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
16290 || rs6000_cpu
== PROCESSOR_PPC603
16291 || rs6000_cpu
== PROCESSOR_PPC750
16294 if (WORLD_SAVE_P (info
))
16298 const char *alloc_rname
;
16301 /* eh_rest_world_r10 will return to the location saved in the LR
16302 stack slot (which is not likely to be our caller.)
16303 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
16304 rest_world is similar, except any R10 parameter is ignored.
16305 The exception-handling stuff that was here in 2.95 is no
16306 longer necessary. */
16310 + 32 - info
->first_gp_reg_save
16311 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
16312 + 63 + 1 - info
->first_fp_reg_save
);
16314 strcpy (rname
, ((current_function_calls_eh_return
) ?
16315 "*eh_rest_world_r10" : "*rest_world"));
16316 alloc_rname
= ggc_strdup (rname
);
16319 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
16320 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
16321 gen_rtx_REG (Pmode
,
16324 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
16325 /* The instruction pattern requires a clobber here;
16326 it is shared with the restVEC helper. */
16328 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
16331 /* CR register traditionally saved as CR2. */
16332 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
16333 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16334 GEN_INT (info
->cr_save_offset
));
16335 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16337 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16340 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16342 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16343 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16344 GEN_INT (info
->gp_save_offset
16346 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16348 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16350 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
16352 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
16353 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16354 GEN_INT (info
->altivec_save_offset
16356 rtx mem
= gen_frame_mem (V4SImode
, addr
);
16358 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16360 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
16362 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
16363 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16364 GEN_INT (info
->fp_save_offset
16366 rtx mem
= gen_frame_mem (DFmode
, addr
);
16368 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16371 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
16373 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
16375 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
16377 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
16379 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
16380 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16385 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
16387 sp_offset
= info
->total_size
;
16389 /* Restore AltiVec registers if we must do so before adjusting the
16391 if (TARGET_ALTIVEC_ABI
16392 && info
->altivec_size
!= 0
16393 && DEFAULT_ABI
!= ABI_V4
16394 && info
->altivec_save_offset
< (TARGET_32BIT
? -220 : -288))
16398 if (use_backchain_to_restore_sp
)
16400 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
16401 emit_move_insn (frame_reg_rtx
,
16402 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
16406 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
16407 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
16409 rtx addr
, areg
, mem
;
16411 areg
= gen_rtx_REG (Pmode
, 0);
16413 (areg
, GEN_INT (info
->altivec_save_offset
16415 + 16 * (i
- info
->first_altivec_reg_save
)));
16417 /* AltiVec addressing mode is [reg+reg]. */
16418 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
16419 mem
= gen_frame_mem (V4SImode
, addr
);
16421 emit_move_insn (gen_rtx_REG (V4SImode
, i
), mem
);
16425 /* Restore VRSAVE if we must do so before adjusting the stack. */
16427 && TARGET_ALTIVEC_VRSAVE
16428 && info
->vrsave_mask
!= 0
16429 && DEFAULT_ABI
!= ABI_V4
16430 && info
->vrsave_save_offset
< (TARGET_32BIT
? -220 : -288))
16432 rtx addr
, mem
, reg
;
16434 if (use_backchain_to_restore_sp
16435 && frame_reg_rtx
== sp_reg_rtx
)
16437 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
16438 emit_move_insn (frame_reg_rtx
,
16439 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
16443 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16444 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
16445 mem
= gen_frame_mem (SImode
, addr
);
16446 reg
= gen_rtx_REG (SImode
, 12);
16447 emit_move_insn (reg
, mem
);
16449 emit_insn (generate_set_vrsave (reg
, info
, 1));
16452 /* If we have a frame pointer, a call to alloca, or a large stack
16453 frame, restore the old stack pointer using the backchain. Otherwise,
16454 we know what size to update it with. */
16455 if (use_backchain_to_restore_sp
)
16457 if (frame_reg_rtx
!= sp_reg_rtx
)
16459 emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
16460 frame_reg_rtx
= sp_reg_rtx
;
16464 /* Under V.4, don't reset the stack pointer until after we're done
16465 loading the saved registers. */
16466 if (DEFAULT_ABI
== ABI_V4
)
16467 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
16469 emit_move_insn (frame_reg_rtx
,
16470 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
16474 else if (info
->push_p
16475 && DEFAULT_ABI
!= ABI_V4
16476 && !current_function_calls_eh_return
)
16478 emit_insn (TARGET_32BIT
16479 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
16480 GEN_INT (info
->total_size
))
16481 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
16482 GEN_INT (info
->total_size
)));
16486 /* Restore AltiVec registers if we have not done so already. */
16487 if (TARGET_ALTIVEC_ABI
16488 && info
->altivec_size
!= 0
16489 && (DEFAULT_ABI
== ABI_V4
16490 || info
->altivec_save_offset
>= (TARGET_32BIT
? -220 : -288)))
16494 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
16495 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
16497 rtx addr
, areg
, mem
;
16499 areg
= gen_rtx_REG (Pmode
, 0);
16501 (areg
, GEN_INT (info
->altivec_save_offset
16503 + 16 * (i
- info
->first_altivec_reg_save
)));
16505 /* AltiVec addressing mode is [reg+reg]. */
16506 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
16507 mem
= gen_frame_mem (V4SImode
, addr
);
16509 emit_move_insn (gen_rtx_REG (V4SImode
, i
), mem
);
16513 /* Restore VRSAVE if we have not done so already. */
16515 && TARGET_ALTIVEC_VRSAVE
16516 && info
->vrsave_mask
!= 0
16517 && (DEFAULT_ABI
== ABI_V4
16518 || info
->vrsave_save_offset
>= (TARGET_32BIT
? -220 : -288)))
16520 rtx addr
, mem
, reg
;
16522 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16523 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
16524 mem
= gen_frame_mem (SImode
, addr
);
16525 reg
= gen_rtx_REG (SImode
, 12);
16526 emit_move_insn (reg
, mem
);
16528 emit_insn (generate_set_vrsave (reg
, info
, 1));
16531 /* Get the old lr if we saved it. */
16532 if (info
->lr_save_p
)
16534 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
16535 info
->lr_save_offset
+ sp_offset
);
16537 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
16540 /* Get the old cr if we saved it. */
16541 if (info
->cr_save_p
)
16543 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16544 GEN_INT (info
->cr_save_offset
+ sp_offset
));
16545 rtx mem
= gen_frame_mem (SImode
, addr
);
16547 emit_move_insn (gen_rtx_REG (SImode
, 12), mem
);
16550 /* Set LR here to try to overlap restores below. */
16551 if (info
->lr_save_p
)
16552 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
16553 gen_rtx_REG (Pmode
, 0));
16555 /* Load exception handler data registers, if needed. */
16556 if (current_function_calls_eh_return
)
16558 unsigned int i
, regno
;
16562 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16563 GEN_INT (sp_offset
+ 5 * reg_size
));
16564 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16566 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
16573 regno
= EH_RETURN_DATA_REGNO (i
);
16574 if (regno
== INVALID_REGNUM
)
16577 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
16578 info
->ehrd_offset
+ sp_offset
16579 + reg_size
* (int) i
);
16581 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
16585 /* Restore GPRs. This is done as a PARALLEL if we are using
16586 the load-multiple instructions. */
16587 if (using_load_multiple
)
16590 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
16591 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16593 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16594 GEN_INT (info
->gp_save_offset
16597 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16600 gen_rtx_SET (VOIDmode
,
16601 gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
),
16604 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16606 else if (TARGET_SPE_ABI
16607 && info
->spe_64bit_regs_used
!= 0
16608 && info
->first_gp_reg_save
!= 32)
16610 /* Determine whether we can address all of the registers that need
16611 to be saved with an offset from the stack pointer that fits in
16612 the small const field for SPE memory instructions. */
16613 int spe_regs_addressable_via_sp
16614 = SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
16615 + (32 - info
->first_gp_reg_save
- 1) * reg_size
);
16618 if (spe_regs_addressable_via_sp
)
16619 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
16622 rtx old_frame_reg_rtx
= frame_reg_rtx
;
16623 /* Make r11 point to the start of the SPE save area. We worried about
16624 not clobbering it when we were saving registers in the prologue.
16625 There's no need to worry here because the static chain is passed
16626 anew to every function. */
16627 if (frame_reg_rtx
== sp_reg_rtx
)
16628 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
16629 emit_insn (gen_addsi3 (frame_reg_rtx
, old_frame_reg_rtx
,
16630 GEN_INT (info
->spe_gp_save_offset
+ sp_offset
)));
16631 /* Keep the invariant that frame_reg_rtx + sp_offset points
16632 at the top of the stack frame. */
16633 sp_offset
= -info
->spe_gp_save_offset
;
16638 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16639 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
16641 rtx offset
, addr
, mem
;
16643 /* We're doing all this to ensure that the immediate offset
16644 fits into the immediate field of 'evldd'. */
16645 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset
+ reg_size
* i
));
16647 offset
= GEN_INT (spe_offset
+ reg_size
* i
);
16648 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, offset
);
16649 mem
= gen_rtx_MEM (V2SImode
, addr
);
16651 emit_move_insn (gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
),
16656 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16657 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
16659 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16660 GEN_INT (info
->gp_save_offset
16663 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16665 emit_move_insn (gen_rtx_REG (reg_mode
,
16666 info
->first_gp_reg_save
+ i
), mem
);
16669 /* Restore fpr's if we need to do it without calling a function. */
16670 if (restoring_FPRs_inline
)
16671 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
16672 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
16673 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
16676 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16677 GEN_INT (info
->fp_save_offset
16680 mem
= gen_frame_mem (DFmode
, addr
);
16682 emit_move_insn (gen_rtx_REG (DFmode
,
16683 info
->first_fp_reg_save
+ i
),
16687 /* If we saved cr, restore it here. Just those that were used. */
16688 if (info
->cr_save_p
)
16690 rtx r12_rtx
= gen_rtx_REG (SImode
, 12);
16693 if (using_mtcr_multiple
)
16695 for (i
= 0; i
< 8; i
++)
16696 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
16698 gcc_assert (count
);
16701 if (using_mtcr_multiple
&& count
> 1)
16706 p
= rtvec_alloc (count
);
16709 for (i
= 0; i
< 8; i
++)
16710 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
16712 rtvec r
= rtvec_alloc (2);
16713 RTVEC_ELT (r
, 0) = r12_rtx
;
16714 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
16715 RTVEC_ELT (p
, ndx
) =
16716 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
16717 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
16720 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16721 gcc_assert (ndx
== count
);
16724 for (i
= 0; i
< 8; i
++)
16725 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
16727 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
16733 /* If this is V.4, unwind the stack pointer after all of the loads
16735 if (frame_reg_rtx
!= sp_reg_rtx
)
16737 /* This blockage is needed so that sched doesn't decide to move
16738 the sp change before the register restores. */
16739 rs6000_emit_stack_tie ();
16740 if (sp_offset
!= 0)
16741 emit_insn (gen_addsi3 (sp_reg_rtx
, frame_reg_rtx
,
16742 GEN_INT (sp_offset
)));
16744 emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
16746 else if (sp_offset
!= 0)
16747 emit_insn (TARGET_32BIT
16748 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
16749 GEN_INT (sp_offset
))
16750 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
16751 GEN_INT (sp_offset
)));
16753 if (current_function_calls_eh_return
)
16755 rtx sa
= EH_RETURN_STACKADJ_RTX
;
16756 emit_insn (TARGET_32BIT
16757 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
, sa
)
16758 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
, sa
));
16764 if (! restoring_FPRs_inline
)
16765 p
= rtvec_alloc (3 + 64 - info
->first_fp_reg_save
);
16767 p
= rtvec_alloc (2);
16769 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
16770 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
16771 gen_rtx_REG (Pmode
,
16774 /* If we have to restore more than two FP registers, branch to the
16775 restore function. It will return to our caller. */
16776 if (! restoring_FPRs_inline
)
16780 const char *alloc_rname
;
16782 sprintf (rname
, "%s%d%s", RESTORE_FP_PREFIX
,
16783 info
->first_fp_reg_save
- 32, RESTORE_FP_SUFFIX
);
16784 alloc_rname
= ggc_strdup (rname
);
16785 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
,
16786 gen_rtx_SYMBOL_REF (Pmode
,
16789 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
16792 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
16793 GEN_INT (info
->fp_save_offset
+ 8*i
));
16794 mem
= gen_frame_mem (DFmode
, addr
);
16796 RTVEC_ELT (p
, i
+3) =
16797 gen_rtx_SET (VOIDmode
,
16798 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
16803 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16807 /* Write function epilogue. */
16810 rs6000_output_function_epilogue (FILE *file
,
16811 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
16813 if (! HAVE_epilogue
)
16815 rtx insn
= get_last_insn ();
16816 /* If the last insn was a BARRIER, we don't have to write anything except
16817 the trace table. */
16818 if (GET_CODE (insn
) == NOTE
)
16819 insn
= prev_nonnote_insn (insn
);
16820 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
16822 /* This is slightly ugly, but at least we don't have two
16823 copies of the epilogue-emitting code. */
16826 /* A NOTE_INSN_DELETED is supposed to be at the start
16827 and end of the "toplevel" insn chain. */
16828 emit_note (NOTE_INSN_DELETED
);
16829 rs6000_emit_epilogue (FALSE
);
16830 emit_note (NOTE_INSN_DELETED
);
16832 /* Expand INSN_ADDRESSES so final() doesn't crash. */
16836 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
16838 INSN_ADDRESSES_NEW (insn
, addr
);
16843 if (TARGET_DEBUG_STACK
)
16844 debug_rtx_list (get_insns (), 100);
16845 final (get_insns (), file
, FALSE
);
16851 macho_branch_islands ();
16852 /* Mach-O doesn't support labels at the end of objects, so if
16853 it looks like we might want one, insert a NOP. */
16855 rtx insn
= get_last_insn ();
16858 && NOTE_KIND (insn
) != NOTE_INSN_DELETED_LABEL
)
16859 insn
= PREV_INSN (insn
);
16863 && NOTE_KIND (insn
) == NOTE_INSN_DELETED_LABEL
)))
16864 fputs ("\tnop\n", file
);
16868 /* Output a traceback table here. See /usr/include/sys/debug.h for info
16871 We don't output a traceback table if -finhibit-size-directive was
16872 used. The documentation for -finhibit-size-directive reads
16873 ``don't output a @code{.size} assembler directive, or anything
16874 else that would cause trouble if the function is split in the
16875 middle, and the two halves are placed at locations far apart in
16876 memory.'' The traceback table has this property, since it
16877 includes the offset from the start of the function to the
16878 traceback table itself.
16880 System V.4 Powerpc's (and the embedded ABI derived from it) use a
16881 different traceback table. */
16882 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
16883 && rs6000_traceback
!= traceback_none
&& !current_function_is_thunk
)
16885 const char *fname
= NULL
;
16886 const char *language_string
= lang_hooks
.name
;
16887 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
16889 int optional_tbtab
;
16890 rs6000_stack_t
*info
= rs6000_stack_info ();
16892 if (rs6000_traceback
== traceback_full
)
16893 optional_tbtab
= 1;
16894 else if (rs6000_traceback
== traceback_part
)
16895 optional_tbtab
= 0;
16897 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
16899 if (optional_tbtab
)
16901 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
16902 while (*fname
== '.') /* V.4 encodes . in the name */
16905 /* Need label immediately before tbtab, so we can compute
16906 its offset from the function start. */
16907 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
16908 ASM_OUTPUT_LABEL (file
, fname
);
16911 /* The .tbtab pseudo-op can only be used for the first eight
16912 expressions, since it can't handle the possibly variable
16913 length fields that follow. However, if you omit the optional
16914 fields, the assembler outputs zeros for all optional fields
16915 anyways, giving each variable length field is minimum length
16916 (as defined in sys/debug.h). Thus we can not use the .tbtab
16917 pseudo-op at all. */
16919 /* An all-zero word flags the start of the tbtab, for debuggers
16920 that have to find it by searching forward from the entry
16921 point or from the current pc. */
16922 fputs ("\t.long 0\n", file
);
16924 /* Tbtab format type. Use format type 0. */
16925 fputs ("\t.byte 0,", file
);
16927 /* Language type. Unfortunately, there does not seem to be any
16928 official way to discover the language being compiled, so we
16929 use language_string.
16930 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
16931 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
16932 a number, so for now use 9. */
16933 if (! strcmp (language_string
, "GNU C"))
16935 else if (! strcmp (language_string
, "GNU F77")
16936 || ! strcmp (language_string
, "GNU Fortran"))
16938 else if (! strcmp (language_string
, "GNU Pascal"))
16940 else if (! strcmp (language_string
, "GNU Ada"))
16942 else if (! strcmp (language_string
, "GNU C++")
16943 || ! strcmp (language_string
, "GNU Objective-C++"))
16945 else if (! strcmp (language_string
, "GNU Java"))
16947 else if (! strcmp (language_string
, "GNU Objective-C"))
16950 gcc_unreachable ();
16951 fprintf (file
, "%d,", i
);
16953 /* 8 single bit fields: global linkage (not set for C extern linkage,
16954 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
16955 from start of procedure stored in tbtab, internal function, function
16956 has controlled storage, function has no toc, function uses fp,
16957 function logs/aborts fp operations. */
16958 /* Assume that fp operations are used if any fp reg must be saved. */
16959 fprintf (file
, "%d,",
16960 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
16962 /* 6 bitfields: function is interrupt handler, name present in
16963 proc table, function calls alloca, on condition directives
16964 (controls stack walks, 3 bits), saves condition reg, saves
16966 /* The `function calls alloca' bit seems to be set whenever reg 31 is
16967 set up as a frame pointer, even when there is no alloca call. */
16968 fprintf (file
, "%d,",
16969 ((optional_tbtab
<< 6)
16970 | ((optional_tbtab
& frame_pointer_needed
) << 5)
16971 | (info
->cr_save_p
<< 1)
16972 | (info
->lr_save_p
)));
16974 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
16976 fprintf (file
, "%d,",
16977 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
16979 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
16980 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
16982 if (optional_tbtab
)
16984 /* Compute the parameter info from the function decl argument
16987 int next_parm_info_bit
= 31;
16989 for (decl
= DECL_ARGUMENTS (current_function_decl
);
16990 decl
; decl
= TREE_CHAIN (decl
))
16992 rtx parameter
= DECL_INCOMING_RTL (decl
);
16993 enum machine_mode mode
= GET_MODE (parameter
);
16995 if (GET_CODE (parameter
) == REG
)
16997 if (SCALAR_FLOAT_MODE_P (mode
))
17018 gcc_unreachable ();
17021 /* If only one bit will fit, don't or in this entry. */
17022 if (next_parm_info_bit
> 0)
17023 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
17024 next_parm_info_bit
-= 2;
17028 fixed_parms
+= ((GET_MODE_SIZE (mode
)
17029 + (UNITS_PER_WORD
- 1))
17031 next_parm_info_bit
-= 1;
17037 /* Number of fixed point parameters. */
17038 /* This is actually the number of words of fixed point parameters; thus
17039 an 8 byte struct counts as 2; and thus the maximum value is 8. */
17040 fprintf (file
, "%d,", fixed_parms
);
17042 /* 2 bitfields: number of floating point parameters (7 bits), parameters
17044 /* This is actually the number of fp registers that hold parameters;
17045 and thus the maximum value is 13. */
17046 /* Set parameters on stack bit if parameters are not in their original
17047 registers, regardless of whether they are on the stack? Xlc
17048 seems to set the bit when not optimizing. */
17049 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
17051 if (! optional_tbtab
)
17054 /* Optional fields follow. Some are variable length. */
17056 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
17057 11 double float. */
17058 /* There is an entry for each parameter in a register, in the order that
17059 they occur in the parameter list. Any intervening arguments on the
17060 stack are ignored. If the list overflows a long (max possible length
17061 34 bits) then completely leave off all elements that don't fit. */
17062 /* Only emit this long if there was at least one parameter. */
17063 if (fixed_parms
|| float_parms
)
17064 fprintf (file
, "\t.long %d\n", parm_info
);
17066 /* Offset from start of code to tb table. */
17067 fputs ("\t.long ", file
);
17068 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
17070 RS6000_OUTPUT_BASENAME (file
, fname
);
17072 assemble_name (file
, fname
);
17074 rs6000_output_function_entry (file
, fname
);
17077 /* Interrupt handler mask. */
17078 /* Omit this long, since we never set the interrupt handler bit
17081 /* Number of CTL (controlled storage) anchors. */
17082 /* Omit this long, since the has_ctl bit is never set above. */
17084 /* Displacement into stack of each CTL anchor. */
17085 /* Omit this list of longs, because there are no CTL anchors. */
17087 /* Length of function name. */
17090 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
17092 /* Function name. */
17093 assemble_string (fname
, strlen (fname
));
17095 /* Register for alloca automatic storage; this is always reg 31.
17096 Only emit this if the alloca bit was set above. */
17097 if (frame_pointer_needed
)
17098 fputs ("\t.byte 31\n", file
);
17100 fputs ("\t.align 2\n", file
);
17104 /* A C compound statement that outputs the assembler code for a thunk
17105 function, used to implement C++ virtual function calls with
17106 multiple inheritance. The thunk acts as a wrapper around a virtual
17107 function, adjusting the implicit object parameter before handing
17108 control off to the real function.
17110 First, emit code to add the integer DELTA to the location that
17111 contains the incoming first argument. Assume that this argument
17112 contains a pointer, and is the one used to pass the `this' pointer
17113 in C++. This is the incoming argument *before* the function
17114 prologue, e.g. `%o0' on a sparc. The addition must preserve the
17115 values of all other incoming arguments.
17117 After the addition, emit code to jump to FUNCTION, which is a
17118 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
17119 not touch the return address. Hence returning from FUNCTION will
17120 return to whoever called the current `thunk'.
17122 The effect must be as if FUNCTION had been called directly with the
17123 adjusted first argument. This macro is responsible for emitting
17124 all of the code for a thunk function; output_function_prologue()
17125 and output_function_epilogue() are not invoked.
17127 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
17128 been extracted from it.) It might possibly be useful on some
17129 targets, but probably not.
17131 If you do not define this macro, the target-independent code in the
17132 C++ frontend will generate a less efficient heavyweight thunk that
17133 calls FUNCTION instead of jumping to it. The generic approach does
17134 not support varargs. */
17137 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
17138 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
17141 rtx
this, insn
, funexp
;
17143 reload_completed
= 1;
17144 epilogue_completed
= 1;
17146 /* Mark the end of the (empty) prologue. */
17147 emit_note (NOTE_INSN_PROLOGUE_END
);
17149 /* Find the "this" pointer. If the function returns a structure,
17150 the structure return pointer is in r3. */
17151 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
17152 this = gen_rtx_REG (Pmode
, 4);
17154 this = gen_rtx_REG (Pmode
, 3);
17156 /* Apply the constant offset, if required. */
17159 rtx delta_rtx
= GEN_INT (delta
);
17160 emit_insn (TARGET_32BIT
17161 ? gen_addsi3 (this, this, delta_rtx
)
17162 : gen_adddi3 (this, this, delta_rtx
));
17165 /* Apply the offset from the vtable, if required. */
17168 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
17169 rtx tmp
= gen_rtx_REG (Pmode
, 12);
17171 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this));
17172 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
17174 emit_insn (TARGET_32BIT
17175 ? gen_addsi3 (tmp
, tmp
, vcall_offset_rtx
)
17176 : gen_adddi3 (tmp
, tmp
, vcall_offset_rtx
));
17177 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
17181 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
17183 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
17185 emit_insn (TARGET_32BIT
17186 ? gen_addsi3 (this, this, tmp
)
17187 : gen_adddi3 (this, this, tmp
));
17190 /* Generate a tail call to the target function. */
17191 if (!TREE_USED (function
))
17193 assemble_external (function
);
17194 TREE_USED (function
) = 1;
17196 funexp
= XEXP (DECL_RTL (function
), 0);
17197 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
17200 if (MACHOPIC_INDIRECT
)
17201 funexp
= machopic_indirect_call_target (funexp
);
17204 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
17205 generate sibcall RTL explicitly. */
17206 insn
= emit_call_insn (
17207 gen_rtx_PARALLEL (VOIDmode
,
17209 gen_rtx_CALL (VOIDmode
,
17210 funexp
, const0_rtx
),
17211 gen_rtx_USE (VOIDmode
, const0_rtx
),
17212 gen_rtx_USE (VOIDmode
,
17213 gen_rtx_REG (SImode
,
17215 gen_rtx_RETURN (VOIDmode
))));
17216 SIBLING_CALL_P (insn
) = 1;
17219 /* Run just enough of rest_of_compilation to get the insns emitted.
17220 There's not really enough bulk here to make other passes such as
17221 instruction scheduling worth while. Note that use_thunk calls
17222 assemble_start_function and assemble_end_function. */
17223 insn
= get_insns ();
17224 insn_locators_alloc ();
17225 shorten_branches (insn
);
17226 final_start_function (insn
, file
, 1);
17227 final (insn
, file
, 1);
17228 final_end_function ();
17229 free_after_compilation (cfun
);
17231 reload_completed
= 0;
17232 epilogue_completed
= 0;
17235 /* A quick summary of the various types of 'constant-pool tables'
17238 Target Flags Name One table per
17239 AIX (none) AIX TOC object file
17240 AIX -mfull-toc AIX TOC object file
17241 AIX -mminimal-toc AIX minimal TOC translation unit
17242 SVR4/EABI (none) SVR4 SDATA object file
17243 SVR4/EABI -fpic SVR4 pic object file
17244 SVR4/EABI -fPIC SVR4 PIC translation unit
17245 SVR4/EABI -mrelocatable EABI TOC function
17246 SVR4/EABI -maix AIX TOC object file
17247 SVR4/EABI -maix -mminimal-toc
17248 AIX minimal TOC translation unit
17250 Name Reg. Set by entries contains:
17251 made by addrs? fp? sum?
17253 AIX TOC 2 crt0 as Y option option
17254 AIX minimal TOC 30 prolog gcc Y Y option
17255 SVR4 SDATA 13 crt0 gcc N Y N
17256 SVR4 pic 30 prolog ld Y not yet N
17257 SVR4 PIC 30 prolog gcc Y option option
17258 EABI TOC 30 prolog gcc Y option option
17262 /* Hash functions for the hash table. */
17265 rs6000_hash_constant (rtx k
)
17267 enum rtx_code code
= GET_CODE (k
);
17268 enum machine_mode mode
= GET_MODE (k
);
17269 unsigned result
= (code
<< 3) ^ mode
;
17270 const char *format
;
17273 format
= GET_RTX_FORMAT (code
);
17274 flen
= strlen (format
);
17280 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
17283 if (mode
!= VOIDmode
)
17284 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
17296 for (; fidx
< flen
; fidx
++)
17297 switch (format
[fidx
])
17302 const char *str
= XSTR (k
, fidx
);
17303 len
= strlen (str
);
17304 result
= result
* 613 + len
;
17305 for (i
= 0; i
< len
; i
++)
17306 result
= result
* 613 + (unsigned) str
[i
];
17311 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
17315 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
17318 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
17319 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
17323 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
17324 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
17331 gcc_unreachable ();
17338 toc_hash_function (const void *hash_entry
)
17340 const struct toc_hash_struct
*thc
=
17341 (const struct toc_hash_struct
*) hash_entry
;
17342 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
17345 /* Compare H1 and H2 for equivalence. */
17348 toc_hash_eq (const void *h1
, const void *h2
)
17350 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
17351 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
17353 if (((const struct toc_hash_struct
*) h1
)->key_mode
17354 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
17357 return rtx_equal_p (r1
, r2
);
17360 /* These are the names given by the C++ front-end to vtables, and
17361 vtable-like objects. Ideally, this logic should not be here;
17362 instead, there should be some programmatic way of inquiring as
17363 to whether or not an object is a vtable. */
17365 #define VTABLE_NAME_P(NAME) \
17366 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
17367 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
17368 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
17369 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
17370 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
17373 rs6000_output_symbol_ref (FILE *file
, rtx x
)
17375 /* Currently C++ toc references to vtables can be emitted before it
17376 is decided whether the vtable is public or private. If this is
17377 the case, then the linker will eventually complain that there is
17378 a reference to an unknown section. Thus, for vtables only,
17379 we emit the TOC reference to reference the symbol and not the
17381 const char *name
= XSTR (x
, 0);
17383 if (VTABLE_NAME_P (name
))
17385 RS6000_OUTPUT_BASENAME (file
, name
);
17388 assemble_name (file
, name
);
17391 /* Output a TOC entry. We derive the entry name from what is being
17395 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
17398 const char *name
= buf
;
17399 const char *real_name
;
17401 HOST_WIDE_INT offset
= 0;
17403 gcc_assert (!TARGET_NO_TOC
);
17405 /* When the linker won't eliminate them, don't output duplicate
17406 TOC entries (this happens on AIX if there is any kind of TOC,
17407 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
17409 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
17411 struct toc_hash_struct
*h
;
17414 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
17415 time because GGC is not initialized at that point. */
17416 if (toc_hash_table
== NULL
)
17417 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
17418 toc_hash_eq
, NULL
);
17420 h
= ggc_alloc (sizeof (*h
));
17422 h
->key_mode
= mode
;
17423 h
->labelno
= labelno
;
17425 found
= htab_find_slot (toc_hash_table
, h
, 1);
17426 if (*found
== NULL
)
17428 else /* This is indeed a duplicate.
17429 Set this label equal to that label. */
17431 fputs ("\t.set ", file
);
17432 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
17433 fprintf (file
, "%d,", labelno
);
17434 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
17435 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
17441 /* If we're going to put a double constant in the TOC, make sure it's
17442 aligned properly when strict alignment is on. */
17443 if (GET_CODE (x
) == CONST_DOUBLE
17444 && STRICT_ALIGNMENT
17445 && GET_MODE_BITSIZE (mode
) >= 64
17446 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
17447 ASM_OUTPUT_ALIGN (file
, 3);
17450 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
17452 /* Handle FP constants specially. Note that if we have a minimal
17453 TOC, things we put here aren't actually in the TOC, so we can allow
17455 if (GET_CODE (x
) == CONST_DOUBLE
&&
17456 (GET_MODE (x
) == TFmode
|| GET_MODE (x
) == TDmode
))
17458 REAL_VALUE_TYPE rv
;
17461 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
17462 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
17463 REAL_VALUE_TO_TARGET_DECIMAL128 (rv
, k
);
17465 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
17469 if (TARGET_MINIMAL_TOC
)
17470 fputs (DOUBLE_INT_ASM_OP
, file
);
17472 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
17473 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
17474 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
17475 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
17476 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
17477 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
17482 if (TARGET_MINIMAL_TOC
)
17483 fputs ("\t.long ", file
);
17485 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
17486 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
17487 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
17488 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
17489 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
17490 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
17494 else if (GET_CODE (x
) == CONST_DOUBLE
&&
17495 (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DDmode
))
17497 REAL_VALUE_TYPE rv
;
17500 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
17502 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
17503 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, k
);
17505 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
17509 if (TARGET_MINIMAL_TOC
)
17510 fputs (DOUBLE_INT_ASM_OP
, file
);
17512 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
17513 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
17514 fprintf (file
, "0x%lx%08lx\n",
17515 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
17520 if (TARGET_MINIMAL_TOC
)
17521 fputs ("\t.long ", file
);
17523 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
17524 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
17525 fprintf (file
, "0x%lx,0x%lx\n",
17526 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
17530 else if (GET_CODE (x
) == CONST_DOUBLE
&&
17531 (GET_MODE (x
) == SFmode
|| GET_MODE (x
) == SDmode
))
17533 REAL_VALUE_TYPE rv
;
17536 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
17537 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
17538 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
17540 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
17544 if (TARGET_MINIMAL_TOC
)
17545 fputs (DOUBLE_INT_ASM_OP
, file
);
17547 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
17548 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
17553 if (TARGET_MINIMAL_TOC
)
17554 fputs ("\t.long ", file
);
17556 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
17557 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
17561 else if (GET_MODE (x
) == VOIDmode
17562 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
17564 unsigned HOST_WIDE_INT low
;
17565 HOST_WIDE_INT high
;
17567 if (GET_CODE (x
) == CONST_DOUBLE
)
17569 low
= CONST_DOUBLE_LOW (x
);
17570 high
= CONST_DOUBLE_HIGH (x
);
17573 #if HOST_BITS_PER_WIDE_INT == 32
17576 high
= (low
& 0x80000000) ? ~0 : 0;
17580 low
= INTVAL (x
) & 0xffffffff;
17581 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
17585 /* TOC entries are always Pmode-sized, but since this
17586 is a bigendian machine then if we're putting smaller
17587 integer constants in the TOC we have to pad them.
17588 (This is still a win over putting the constants in
17589 a separate constant pool, because then we'd have
17590 to have both a TOC entry _and_ the actual constant.)
17592 For a 32-bit target, CONST_INT values are loaded and shifted
17593 entirely within `low' and can be stored in one TOC entry. */
17595 /* It would be easy to make this work, but it doesn't now. */
17596 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
17598 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
17600 #if HOST_BITS_PER_WIDE_INT == 32
17601 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
17602 POINTER_SIZE
, &low
, &high
, 0);
17605 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
17606 high
= (HOST_WIDE_INT
) low
>> 32;
17613 if (TARGET_MINIMAL_TOC
)
17614 fputs (DOUBLE_INT_ASM_OP
, file
);
17616 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
17617 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
17618 fprintf (file
, "0x%lx%08lx\n",
17619 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
17624 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
17626 if (TARGET_MINIMAL_TOC
)
17627 fputs ("\t.long ", file
);
17629 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
17630 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
17631 fprintf (file
, "0x%lx,0x%lx\n",
17632 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
17636 if (TARGET_MINIMAL_TOC
)
17637 fputs ("\t.long ", file
);
17639 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
17640 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
17646 if (GET_CODE (x
) == CONST
)
17648 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
);
17650 base
= XEXP (XEXP (x
, 0), 0);
17651 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
17654 switch (GET_CODE (base
))
17657 name
= XSTR (base
, 0);
17661 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
17662 CODE_LABEL_NUMBER (XEXP (base
, 0)));
17666 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
17670 gcc_unreachable ();
17673 real_name
= (*targetm
.strip_name_encoding
) (name
);
17674 if (TARGET_MINIMAL_TOC
)
17675 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
17678 fprintf (file
, "\t.tc %s", real_name
);
17681 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
17683 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
17685 fputs ("[TC],", file
);
17688 /* Currently C++ toc references to vtables can be emitted before it
17689 is decided whether the vtable is public or private. If this is
17690 the case, then the linker will eventually complain that there is
17691 a TOC reference to an unknown section. Thus, for vtables only,
17692 we emit the TOC reference to reference the symbol and not the
17694 if (VTABLE_NAME_P (name
))
17696 RS6000_OUTPUT_BASENAME (file
, name
);
17698 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
17699 else if (offset
> 0)
17700 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
17703 output_addr_const (file
, x
);
17707 /* Output an assembler pseudo-op to write an ASCII string of N characters
17708 starting at P to FILE.
17710 On the RS/6000, we have to do this using the .byte operation and
17711 write out special characters outside the quoted string.
17712 Also, the assembler is broken; very long strings are truncated,
17713 so we must artificially break them up early. */
17716 output_ascii (FILE *file
, const char *p
, int n
)
17719 int i
, count_string
;
17720 const char *for_string
= "\t.byte \"";
17721 const char *for_decimal
= "\t.byte ";
17722 const char *to_close
= NULL
;
17725 for (i
= 0; i
< n
; i
++)
17728 if (c
>= ' ' && c
< 0177)
17731 fputs (for_string
, file
);
17734 /* Write two quotes to get one. */
17742 for_decimal
= "\"\n\t.byte ";
17746 if (count_string
>= 512)
17748 fputs (to_close
, file
);
17750 for_string
= "\t.byte \"";
17751 for_decimal
= "\t.byte ";
17759 fputs (for_decimal
, file
);
17760 fprintf (file
, "%d", c
);
17762 for_string
= "\n\t.byte \"";
17763 for_decimal
= ", ";
17769 /* Now close the string if we have written one. Then end the line. */
17771 fputs (to_close
, file
);
17774 /* Generate a unique section name for FILENAME for a section type
17775 represented by SECTION_DESC. Output goes into BUF.
17777 SECTION_DESC can be any string, as long as it is different for each
17778 possible section type.
17780 We name the section in the same manner as xlc. The name begins with an
17781 underscore followed by the filename (after stripping any leading directory
17782 names) with the last period replaced by the string SECTION_DESC. If
17783 FILENAME does not contain a period, SECTION_DESC is appended to the end of
17787 rs6000_gen_section_name (char **buf
, const char *filename
,
17788 const char *section_desc
)
17790 const char *q
, *after_last_slash
, *last_period
= 0;
17794 after_last_slash
= filename
;
17795 for (q
= filename
; *q
; q
++)
17798 after_last_slash
= q
+ 1;
17799 else if (*q
== '.')
17803 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
17804 *buf
= (char *) xmalloc (len
);
17809 for (q
= after_last_slash
; *q
; q
++)
17811 if (q
== last_period
)
17813 strcpy (p
, section_desc
);
17814 p
+= strlen (section_desc
);
17818 else if (ISALNUM (*q
))
17822 if (last_period
== 0)
17823 strcpy (p
, section_desc
);
17828 /* Emit profile function. */
17831 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
17833 /* Non-standard profiling for kernels, which just saves LR then calls
17834 _mcount without worrying about arg saves. The idea is to change
17835 the function prologue as little as possible as it isn't easy to
17836 account for arg save/restore code added just for _mcount. */
17837 if (TARGET_PROFILE_KERNEL
)
17840 if (DEFAULT_ABI
== ABI_AIX
)
17842 #ifndef NO_PROFILE_COUNTERS
17843 # define NO_PROFILE_COUNTERS 0
17845 if (NO_PROFILE_COUNTERS
)
17846 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 0);
17850 const char *label_name
;
17853 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
17854 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
17855 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
17857 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 1,
17861 else if (DEFAULT_ABI
== ABI_DARWIN
)
17863 const char *mcount_name
= RS6000_MCOUNT
;
17864 int caller_addr_regno
= LR_REGNO
;
17866 /* Be conservative and always set this, at least for now. */
17867 current_function_uses_pic_offset_table
= 1;
17870 /* For PIC code, set up a stub and collect the caller's address
17871 from r0, which is where the prologue puts it. */
17872 if (MACHOPIC_INDIRECT
17873 && current_function_uses_pic_offset_table
)
17874 caller_addr_regno
= 0;
17876 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
17878 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
17882 /* Write function profiler code. */
17885 output_function_profiler (FILE *file
, int labelno
)
17889 switch (DEFAULT_ABI
)
17892 gcc_unreachable ();
17897 warning (0, "no profiling of 64-bit code for this ABI");
17900 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
17901 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
17902 if (NO_PROFILE_COUNTERS
)
17904 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
17905 reg_names
[0], reg_names
[1]);
17907 else if (TARGET_SECURE_PLT
&& flag_pic
)
17909 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
17910 reg_names
[0], reg_names
[1]);
17911 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
17912 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
17913 reg_names
[12], reg_names
[12]);
17914 assemble_name (file
, buf
);
17915 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
17916 assemble_name (file
, buf
);
17917 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
17919 else if (flag_pic
== 1)
17921 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
17922 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
17923 reg_names
[0], reg_names
[1]);
17924 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
17925 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
17926 assemble_name (file
, buf
);
17927 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
17929 else if (flag_pic
> 1)
17931 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
17932 reg_names
[0], reg_names
[1]);
17933 /* Now, we need to get the address of the label. */
17934 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
17935 assemble_name (file
, buf
);
17936 fputs ("-.\n1:", file
);
17937 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
17938 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
17939 reg_names
[0], reg_names
[11]);
17940 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
17941 reg_names
[0], reg_names
[0], reg_names
[11]);
17945 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
17946 assemble_name (file
, buf
);
17947 fputs ("@ha\n", file
);
17948 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
17949 reg_names
[0], reg_names
[1]);
17950 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
17951 assemble_name (file
, buf
);
17952 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
17955 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
17956 fprintf (file
, "\tbl %s%s\n",
17957 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
17962 if (!TARGET_PROFILE_KERNEL
)
17964 /* Don't do anything, done in output_profile_hook (). */
17968 gcc_assert (!TARGET_32BIT
);
17970 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
17971 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
17973 if (cfun
->static_chain_decl
!= NULL
)
17975 asm_fprintf (file
, "\tstd %s,24(%s)\n",
17976 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
17977 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
17978 asm_fprintf (file
, "\tld %s,24(%s)\n",
17979 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
17982 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
17990 /* The following variable value is the last issued insn. */
17992 static rtx last_scheduled_insn
;
17994 /* The following variable helps to balance issuing of load and
17995 store instructions */
17997 static int load_store_pendulum
;
17999 /* Power4 load update and store update instructions are cracked into a
18000 load or store and an integer insn which are executed in the same cycle.
18001 Branches have their own dispatch slot which does not count against the
18002 GCC issue rate, but it changes the program flow so there are no other
18003 instructions to issue in this cycle. */
18006 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED
,
18007 int verbose ATTRIBUTE_UNUSED
,
18008 rtx insn
, int more
)
18010 last_scheduled_insn
= insn
;
18011 if (GET_CODE (PATTERN (insn
)) == USE
18012 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18014 cached_can_issue_more
= more
;
18015 return cached_can_issue_more
;
18018 if (insn_terminates_group_p (insn
, current_group
))
18020 cached_can_issue_more
= 0;
18021 return cached_can_issue_more
;
18024 /* If no reservation, but reach here */
18025 if (recog_memoized (insn
) < 0)
18028 if (rs6000_sched_groups
)
18030 if (is_microcoded_insn (insn
))
18031 cached_can_issue_more
= 0;
18032 else if (is_cracked_insn (insn
))
18033 cached_can_issue_more
= more
> 2 ? more
- 2 : 0;
18035 cached_can_issue_more
= more
- 1;
18037 return cached_can_issue_more
;
18040 if (rs6000_cpu_attr
== CPU_CELL
&& is_nonpipeline_insn (insn
))
18043 cached_can_issue_more
= more
- 1;
18044 return cached_can_issue_more
;
18047 /* Adjust the cost of a scheduling dependency. Return the new cost of
18048 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
18051 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
18053 enum attr_type attr_type
;
18055 if (! recog_memoized (insn
))
18058 switch (REG_NOTE_KIND (link
))
18062 /* Data dependency; DEP_INSN writes a register that INSN reads
18063 some cycles later. */
18065 /* Separate a load from a narrower, dependent store. */
18066 if (rs6000_sched_groups
18067 && GET_CODE (PATTERN (insn
)) == SET
18068 && GET_CODE (PATTERN (dep_insn
)) == SET
18069 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
18070 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
18071 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
18072 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
18075 attr_type
= get_attr_type (insn
);
18080 /* Tell the first scheduling pass about the latency between
18081 a mtctr and bctr (and mtlr and br/blr). The first
18082 scheduling pass will not know about this latency since
18083 the mtctr instruction, which has the latency associated
18084 to it, will be generated by reload. */
18085 return TARGET_POWER
? 5 : 4;
18087 /* Leave some extra cycles between a compare and its
18088 dependent branch, to inhibit expensive mispredicts. */
18089 if ((rs6000_cpu_attr
== CPU_PPC603
18090 || rs6000_cpu_attr
== CPU_PPC604
18091 || rs6000_cpu_attr
== CPU_PPC604E
18092 || rs6000_cpu_attr
== CPU_PPC620
18093 || rs6000_cpu_attr
== CPU_PPC630
18094 || rs6000_cpu_attr
== CPU_PPC750
18095 || rs6000_cpu_attr
== CPU_PPC7400
18096 || rs6000_cpu_attr
== CPU_PPC7450
18097 || rs6000_cpu_attr
== CPU_POWER4
18098 || rs6000_cpu_attr
== CPU_POWER5
18099 || rs6000_cpu_attr
== CPU_CELL
)
18100 && recog_memoized (dep_insn
)
18101 && (INSN_CODE (dep_insn
) >= 0))
18103 switch (get_attr_type (dep_insn
))
18107 case TYPE_DELAYED_COMPARE
:
18108 case TYPE_IMUL_COMPARE
:
18109 case TYPE_LMUL_COMPARE
:
18110 case TYPE_FPCOMPARE
:
18111 case TYPE_CR_LOGICAL
:
18112 case TYPE_DELAYED_CR
:
18121 case TYPE_STORE_UX
:
18123 case TYPE_FPSTORE_U
:
18124 case TYPE_FPSTORE_UX
:
18125 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18126 && recog_memoized (dep_insn
)
18127 && (INSN_CODE (dep_insn
) >= 0))
18130 if (GET_CODE (PATTERN (insn
)) != SET
)
18131 /* If this happens, we have to extend this to schedule
18132 optimally. Return default for now. */
18135 /* Adjust the cost for the case where the value written
18136 by a fixed point operation is used as the address
18137 gen value on a store. */
18138 switch (get_attr_type (dep_insn
))
18145 if (! store_data_bypass_p (dep_insn
, insn
))
18149 case TYPE_LOAD_EXT
:
18150 case TYPE_LOAD_EXT_U
:
18151 case TYPE_LOAD_EXT_UX
:
18152 case TYPE_VAR_SHIFT_ROTATE
:
18153 case TYPE_VAR_DELAYED_COMPARE
:
18155 if (! store_data_bypass_p (dep_insn
, insn
))
18161 case TYPE_FAST_COMPARE
:
18164 case TYPE_INSERT_WORD
:
18165 case TYPE_INSERT_DWORD
:
18166 case TYPE_FPLOAD_U
:
18167 case TYPE_FPLOAD_UX
:
18169 case TYPE_STORE_UX
:
18170 case TYPE_FPSTORE_U
:
18171 case TYPE_FPSTORE_UX
:
18173 if (! store_data_bypass_p (dep_insn
, insn
))
18181 case TYPE_IMUL_COMPARE
:
18182 case TYPE_LMUL_COMPARE
:
18184 if (! store_data_bypass_p (dep_insn
, insn
))
18190 if (! store_data_bypass_p (dep_insn
, insn
))
18196 if (! store_data_bypass_p (dep_insn
, insn
))
18209 case TYPE_LOAD_EXT
:
18210 case TYPE_LOAD_EXT_U
:
18211 case TYPE_LOAD_EXT_UX
:
18212 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18213 && recog_memoized (dep_insn
)
18214 && (INSN_CODE (dep_insn
) >= 0))
18217 /* Adjust the cost for the case where the value written
18218 by a fixed point instruction is used within the address
18219 gen portion of a subsequent load(u)(x) */
18220 switch (get_attr_type (dep_insn
))
18227 if (set_to_load_agen (dep_insn
, insn
))
18231 case TYPE_LOAD_EXT
:
18232 case TYPE_LOAD_EXT_U
:
18233 case TYPE_LOAD_EXT_UX
:
18234 case TYPE_VAR_SHIFT_ROTATE
:
18235 case TYPE_VAR_DELAYED_COMPARE
:
18237 if (set_to_load_agen (dep_insn
, insn
))
18243 case TYPE_FAST_COMPARE
:
18246 case TYPE_INSERT_WORD
:
18247 case TYPE_INSERT_DWORD
:
18248 case TYPE_FPLOAD_U
:
18249 case TYPE_FPLOAD_UX
:
18251 case TYPE_STORE_UX
:
18252 case TYPE_FPSTORE_U
:
18253 case TYPE_FPSTORE_UX
:
18255 if (set_to_load_agen (dep_insn
, insn
))
18263 case TYPE_IMUL_COMPARE
:
18264 case TYPE_LMUL_COMPARE
:
18266 if (set_to_load_agen (dep_insn
, insn
))
18272 if (set_to_load_agen (dep_insn
, insn
))
18278 if (set_to_load_agen (dep_insn
, insn
))
18289 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18290 && recog_memoized (dep_insn
)
18291 && (INSN_CODE (dep_insn
) >= 0)
18292 && (get_attr_type (dep_insn
) == TYPE_MFFGPR
))
18299 /* Fall out to return default cost. */
18303 case REG_DEP_OUTPUT
:
18304 /* Output dependency; DEP_INSN writes a register that INSN writes some
18306 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18307 && recog_memoized (dep_insn
)
18308 && (INSN_CODE (dep_insn
) >= 0))
18310 attr_type
= get_attr_type (insn
);
18315 if (get_attr_type (dep_insn
) == TYPE_FP
)
18319 if (get_attr_type (dep_insn
) == TYPE_MFFGPR
)
18327 /* Anti dependency; DEP_INSN reads a register that INSN writes some
18332 gcc_unreachable ();
18338 /* The function returns a true if INSN is microcoded.
18339 Return false otherwise. */
18342 is_microcoded_insn (rtx insn
)
18344 if (!insn
|| !INSN_P (insn
)
18345 || GET_CODE (PATTERN (insn
)) == USE
18346 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18349 if (rs6000_cpu_attr
== CPU_CELL
)
18350 return get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
;
18352 if (rs6000_sched_groups
)
18354 enum attr_type type
= get_attr_type (insn
);
18355 if (type
== TYPE_LOAD_EXT_U
18356 || type
== TYPE_LOAD_EXT_UX
18357 || type
== TYPE_LOAD_UX
18358 || type
== TYPE_STORE_UX
18359 || type
== TYPE_MFCR
)
18366 /* The function returns true if INSN is cracked into 2 instructions
18367 by the processor (and therefore occupies 2 issue slots). */
18370 is_cracked_insn (rtx insn
)
18372 if (!insn
|| !INSN_P (insn
)
18373 || GET_CODE (PATTERN (insn
)) == USE
18374 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18377 if (rs6000_sched_groups
)
18379 enum attr_type type
= get_attr_type (insn
);
18380 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
18381 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
18382 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
18383 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
18384 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
18385 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
18386 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
18387 || type
== TYPE_INSERT_WORD
)
18394 /* The function returns true if INSN can be issued only from
18395 the branch slot. */
18398 is_branch_slot_insn (rtx insn
)
18400 if (!insn
|| !INSN_P (insn
)
18401 || GET_CODE (PATTERN (insn
)) == USE
18402 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18405 if (rs6000_sched_groups
)
18407 enum attr_type type
= get_attr_type (insn
);
18408 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
18416 /* The function returns true if out_inst sets a value that is
18417 used in the address generation computation of in_insn */
18419 set_to_load_agen (rtx out_insn
, rtx in_insn
)
18421 rtx out_set
, in_set
;
18423 /* For performance reasons, only handle the simple case where
18424 both loads are a single_set. */
18425 out_set
= single_set (out_insn
);
18428 in_set
= single_set (in_insn
);
18430 return reg_mentioned_p (SET_DEST (out_set
), SET_SRC (in_set
));
18436 /* The function returns true if the target storage location of
18437 out_insn is adjacent to the target storage location of in_insn */
18438 /* Return 1 if memory locations are adjacent. */
18441 adjacent_mem_locations (rtx insn1
, rtx insn2
)
18444 rtx a
= get_store_dest (PATTERN (insn1
));
18445 rtx b
= get_store_dest (PATTERN (insn2
));
18447 if ((GET_CODE (XEXP (a
, 0)) == REG
18448 || (GET_CODE (XEXP (a
, 0)) == PLUS
18449 && GET_CODE (XEXP (XEXP (a
, 0), 1)) == CONST_INT
))
18450 && (GET_CODE (XEXP (b
, 0)) == REG
18451 || (GET_CODE (XEXP (b
, 0)) == PLUS
18452 && GET_CODE (XEXP (XEXP (b
, 0), 1)) == CONST_INT
)))
18454 HOST_WIDE_INT val0
= 0, val1
= 0, val_diff
;
18457 if (GET_CODE (XEXP (a
, 0)) == PLUS
)
18459 reg0
= XEXP (XEXP (a
, 0), 0);
18460 val0
= INTVAL (XEXP (XEXP (a
, 0), 1));
18463 reg0
= XEXP (a
, 0);
18465 if (GET_CODE (XEXP (b
, 0)) == PLUS
)
18467 reg1
= XEXP (XEXP (b
, 0), 0);
18468 val1
= INTVAL (XEXP (XEXP (b
, 0), 1));
18471 reg1
= XEXP (b
, 0);
18473 val_diff
= val1
- val0
;
18475 return ((REGNO (reg0
) == REGNO (reg1
))
18476 && ((MEM_SIZE (a
) && val_diff
== INTVAL (MEM_SIZE (a
)))
18477 || (MEM_SIZE (b
) && val_diff
== -INTVAL (MEM_SIZE (b
)))));
18483 /* A C statement (sans semicolon) to update the integer scheduling
18484 priority INSN_PRIORITY (INSN). Increase the priority to execute the
18485 INSN earlier, reduce the priority to execute INSN later. Do not
18486 define this macro if you do not need to adjust the scheduling
18487 priorities of insns. */
18490 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
18492 /* On machines (like the 750) which have asymmetric integer units,
18493 where one integer unit can do multiply and divides and the other
18494 can't, reduce the priority of multiply/divide so it is scheduled
18495 before other integer operations. */
18498 if (! INSN_P (insn
))
18501 if (GET_CODE (PATTERN (insn
)) == USE
)
18504 switch (rs6000_cpu_attr
) {
18506 switch (get_attr_type (insn
))
18513 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
18514 priority
, priority
);
18515 if (priority
>= 0 && priority
< 0x01000000)
18522 if (insn_must_be_first_in_group (insn
)
18523 && reload_completed
18524 && current_sched_info
->sched_max_insns_priority
18525 && rs6000_sched_restricted_insns_priority
)
18528 /* Prioritize insns that can be dispatched only in the first
18530 if (rs6000_sched_restricted_insns_priority
== 1)
18531 /* Attach highest priority to insn. This means that in
18532 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
18533 precede 'priority' (critical path) considerations. */
18534 return current_sched_info
->sched_max_insns_priority
;
18535 else if (rs6000_sched_restricted_insns_priority
== 2)
18536 /* Increase priority of insn by a minimal amount. This means that in
18537 haifa-sched.c:ready_sort(), only 'priority' (critical path)
18538 considerations precede dispatch-slot restriction considerations. */
18539 return (priority
+ 1);
18542 if (rs6000_cpu
== PROCESSOR_POWER6
18543 && ((load_store_pendulum
== -2 && is_load_insn (insn
))
18544 || (load_store_pendulum
== 2 && is_store_insn (insn
))))
18545 /* Attach highest priority to insn if the scheduler has just issued two
18546 stores and this instruction is a load, or two loads and this instruction
18547 is a store. Power6 wants loads and stores scheduled alternately
18549 return current_sched_info
->sched_max_insns_priority
;
18554 /* Return true if the instruction is nonpipelined on the Cell. */
18556 is_nonpipeline_insn (rtx insn
)
18558 enum attr_type type
;
18559 if (!insn
|| !INSN_P (insn
)
18560 || GET_CODE (PATTERN (insn
)) == USE
18561 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18564 type
= get_attr_type (insn
);
18565 if (type
== TYPE_IMUL
18566 || type
== TYPE_IMUL2
18567 || type
== TYPE_IMUL3
18568 || type
== TYPE_LMUL
18569 || type
== TYPE_IDIV
18570 || type
== TYPE_LDIV
18571 || type
== TYPE_SDIV
18572 || type
== TYPE_DDIV
18573 || type
== TYPE_SSQRT
18574 || type
== TYPE_DSQRT
18575 || type
== TYPE_MFCR
18576 || type
== TYPE_MFCRF
18577 || type
== TYPE_MFJMPR
)
18585 /* Return how many instructions the machine can issue per cycle. */
18588 rs6000_issue_rate (void)
18590 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
18591 if (!reload_completed
)
18594 switch (rs6000_cpu_attr
) {
18595 case CPU_RIOS1
: /* ? */
18597 case CPU_PPC601
: /* ? */
18606 case CPU_PPCE300C2
:
18607 case CPU_PPCE300C3
:
18624 /* Return how many instructions to look ahead for better insn
18628 rs6000_use_sched_lookahead (void)
18630 if (rs6000_cpu_attr
== CPU_PPC8540
)
18632 if (rs6000_cpu_attr
== CPU_CELL
)
18633 return (reload_completed
? 8 : 0);
18637 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
18639 rs6000_use_sched_lookahead_guard (rtx insn
)
18641 if (rs6000_cpu_attr
!= CPU_CELL
)
18644 if (insn
== NULL_RTX
|| !INSN_P (insn
))
18647 if (!reload_completed
18648 || is_nonpipeline_insn (insn
)
18649 || is_microcoded_insn (insn
))
18655 /* Determine is PAT refers to memory. */
18658 is_mem_ref (rtx pat
)
18664 /* stack_tie does not produce any real memory traffic. */
18665 if (GET_CODE (pat
) == UNSPEC
18666 && XINT (pat
, 1) == UNSPEC_TIE
)
18669 if (GET_CODE (pat
) == MEM
)
18672 /* Recursively process the pattern. */
18673 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
18675 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
18678 ret
|= is_mem_ref (XEXP (pat
, i
));
18679 else if (fmt
[i
] == 'E')
18680 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
18681 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
18687 /* Determine if PAT is a PATTERN of a load insn. */
18690 is_load_insn1 (rtx pat
)
18692 if (!pat
|| pat
== NULL_RTX
)
18695 if (GET_CODE (pat
) == SET
)
18696 return is_mem_ref (SET_SRC (pat
));
18698 if (GET_CODE (pat
) == PARALLEL
)
18702 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
18703 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
18710 /* Determine if INSN loads from memory. */
18713 is_load_insn (rtx insn
)
18715 if (!insn
|| !INSN_P (insn
))
18718 if (GET_CODE (insn
) == CALL_INSN
)
18721 return is_load_insn1 (PATTERN (insn
));
18724 /* Determine if PAT is a PATTERN of a store insn. */
18727 is_store_insn1 (rtx pat
)
18729 if (!pat
|| pat
== NULL_RTX
)
18732 if (GET_CODE (pat
) == SET
)
18733 return is_mem_ref (SET_DEST (pat
));
18735 if (GET_CODE (pat
) == PARALLEL
)
18739 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
18740 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
18747 /* Determine if INSN stores to memory. */
18750 is_store_insn (rtx insn
)
18752 if (!insn
|| !INSN_P (insn
))
18755 return is_store_insn1 (PATTERN (insn
));
18758 /* Return the dest of a store insn. */
18761 get_store_dest (rtx pat
)
18763 gcc_assert (is_store_insn1 (pat
));
18765 if (GET_CODE (pat
) == SET
)
18766 return SET_DEST (pat
);
18767 else if (GET_CODE (pat
) == PARALLEL
)
18771 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
18773 rtx inner_pat
= XVECEXP (pat
, 0, i
);
18774 if (GET_CODE (inner_pat
) == SET
18775 && is_mem_ref (SET_DEST (inner_pat
)))
18779 /* We shouldn't get here, because we should have either a simple
18780 store insn or a store with update which are covered above. */
18784 /* Returns whether the dependence between INSN and NEXT is considered
18785 costly by the given target. */
18788 rs6000_is_costly_dependence (dep_t dep
, int cost
, int distance
)
18793 /* If the flag is not enabled - no dependence is considered costly;
18794 allow all dependent insns in the same group.
18795 This is the most aggressive option. */
18796 if (rs6000_sched_costly_dep
== no_dep_costly
)
18799 /* If the flag is set to 1 - a dependence is always considered costly;
18800 do not allow dependent instructions in the same group.
18801 This is the most conservative option. */
18802 if (rs6000_sched_costly_dep
== all_deps_costly
)
18805 insn
= DEP_PRO (dep
);
18806 next
= DEP_CON (dep
);
18808 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
18809 && is_load_insn (next
)
18810 && is_store_insn (insn
))
18811 /* Prevent load after store in the same group. */
18814 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
18815 && is_load_insn (next
)
18816 && is_store_insn (insn
)
18817 && DEP_TYPE (dep
) == REG_DEP_TRUE
)
18818 /* Prevent load after store in the same group if it is a true
18822 /* The flag is set to X; dependences with latency >= X are considered costly,
18823 and will not be scheduled in the same group. */
18824 if (rs6000_sched_costly_dep
<= max_dep_latency
18825 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
18831 /* Return the next insn after INSN that is found before TAIL is reached,
18832 skipping any "non-active" insns - insns that will not actually occupy
18833 an issue slot. Return NULL_RTX if such an insn is not found. */
18836 get_next_active_insn (rtx insn
, rtx tail
)
18838 if (insn
== NULL_RTX
|| insn
== tail
)
18843 insn
= NEXT_INSN (insn
);
18844 if (insn
== NULL_RTX
|| insn
== tail
)
18849 || (NONJUMP_INSN_P (insn
)
18850 && GET_CODE (PATTERN (insn
)) != USE
18851 && GET_CODE (PATTERN (insn
)) != CLOBBER
18852 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
18858 /* We are about to begin issuing insns for this clock cycle. */
18861 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED
, int sched_verbose
,
18862 rtx
*ready ATTRIBUTE_UNUSED
,
18863 int *pn_ready ATTRIBUTE_UNUSED
,
18864 int clock_var ATTRIBUTE_UNUSED
)
18866 int n_ready
= *pn_ready
;
18869 fprintf (dump
, "// rs6000_sched_reorder :\n");
18871 /* Reorder the ready list, if the second to last ready insn
18872 is a nonepipeline insn. */
18873 if (rs6000_cpu_attr
== CPU_CELL
&& n_ready
> 1)
18875 if (is_nonpipeline_insn (ready
[n_ready
- 1])
18876 && (recog_memoized (ready
[n_ready
- 2]) > 0))
18877 /* Simply swap first two insns. */
18879 rtx tmp
= ready
[n_ready
- 1];
18880 ready
[n_ready
- 1] = ready
[n_ready
- 2];
18881 ready
[n_ready
- 2] = tmp
;
18885 if (rs6000_cpu
== PROCESSOR_POWER6
)
18886 load_store_pendulum
= 0;
18888 return rs6000_issue_rate ();
18891 /* Like rs6000_sched_reorder, but called after issuing each insn. */
18894 rs6000_sched_reorder2 (FILE *dump
, int sched_verbose
, rtx
*ready
,
18895 int *pn_ready
, int clock_var ATTRIBUTE_UNUSED
)
18898 fprintf (dump
, "// rs6000_sched_reorder2 :\n");
18900 /* For Power6, we need to handle some special cases to try and keep the
18901 store queue from overflowing and triggering expensive flushes.
18903 This code monitors how load and store instructions are being issued
18904 and skews the ready list one way or the other to increase the likelihood
18905 that a desired instruction is issued at the proper time.
18907 A couple of things are done. First, we maintain a "load_store_pendulum"
18908 to track the current state of load/store issue.
18910 - If the pendulum is at zero, then no loads or stores have been
18911 issued in the current cycle so we do nothing.
18913 - If the pendulum is 1, then a single load has been issued in this
18914 cycle and we attempt to locate another load in the ready list to
18917 - If the pendulum is -2, then two stores have already been
18918 issued in this cycle, so we increase the priority of the first load
18919 in the ready list to increase it's likelihood of being chosen first
18922 - If the pendulum is -1, then a single store has been issued in this
18923 cycle and we attempt to locate another store in the ready list to
18924 issue with it, preferring a store to an adjacent memory location to
18925 facilitate store pairing in the store queue.
18927 - If the pendulum is 2, then two loads have already been
18928 issued in this cycle, so we increase the priority of the first store
18929 in the ready list to increase it's likelihood of being chosen first
18932 - If the pendulum < -2 or > 2, then do nothing.
18934 Note: This code covers the most common scenarios. There exist non
18935 load/store instructions which make use of the LSU and which
18936 would need to be accounted for to strictly model the behavior
18937 of the machine. Those instructions are currently unaccounted
18938 for to help minimize compile time overhead of this code.
18940 if (rs6000_cpu
== PROCESSOR_POWER6
&& last_scheduled_insn
)
18946 if (is_store_insn (last_scheduled_insn
))
18947 /* Issuing a store, swing the load_store_pendulum to the left */
18948 load_store_pendulum
--;
18949 else if (is_load_insn (last_scheduled_insn
))
18950 /* Issuing a load, swing the load_store_pendulum to the right */
18951 load_store_pendulum
++;
18953 return cached_can_issue_more
;
18955 /* If the pendulum is balanced, or there is only one instruction on
18956 the ready list, then all is well, so return. */
18957 if ((load_store_pendulum
== 0) || (*pn_ready
<= 1))
18958 return cached_can_issue_more
;
18960 if (load_store_pendulum
== 1)
18962 /* A load has been issued in this cycle. Scan the ready list
18963 for another load to issue with it */
18968 if (is_load_insn (ready
[pos
]))
18970 /* Found a load. Move it to the head of the ready list,
18971 and adjust it's priority so that it is more likely to
18974 for (i
=pos
; i
<*pn_ready
-1; i
++)
18975 ready
[i
] = ready
[i
+ 1];
18976 ready
[*pn_ready
-1] = tmp
;
18977 if INSN_PRIORITY_KNOWN (tmp
)
18978 INSN_PRIORITY (tmp
)++;
18984 else if (load_store_pendulum
== -2)
18986 /* Two stores have been issued in this cycle. Increase the
18987 priority of the first load in the ready list to favor it for
18988 issuing in the next cycle. */
18993 if (is_load_insn (ready
[pos
])
18994 && INSN_PRIORITY_KNOWN (ready
[pos
]))
18996 INSN_PRIORITY (ready
[pos
])++;
18998 /* Adjust the pendulum to account for the fact that a load
18999 was found and increased in priority. This is to prevent
19000 increasing the priority of multiple loads */
19001 load_store_pendulum
--;
19008 else if (load_store_pendulum
== -1)
19010 /* A store has been issued in this cycle. Scan the ready list for
19011 another store to issue with it, preferring a store to an adjacent
19013 int first_store_pos
= -1;
19019 if (is_store_insn (ready
[pos
]))
19021 /* Maintain the index of the first store found on the
19023 if (first_store_pos
== -1)
19024 first_store_pos
= pos
;
19026 if (is_store_insn (last_scheduled_insn
)
19027 && adjacent_mem_locations (last_scheduled_insn
,ready
[pos
]))
19029 /* Found an adjacent store. Move it to the head of the
19030 ready list, and adjust it's priority so that it is
19031 more likely to stay there */
19033 for (i
=pos
; i
<*pn_ready
-1; i
++)
19034 ready
[i
] = ready
[i
+ 1];
19035 ready
[*pn_ready
-1] = tmp
;
19036 if INSN_PRIORITY_KNOWN (tmp
)
19037 INSN_PRIORITY (tmp
)++;
19038 first_store_pos
= -1;
19046 if (first_store_pos
>= 0)
19048 /* An adjacent store wasn't found, but a non-adjacent store was,
19049 so move the non-adjacent store to the front of the ready
19050 list, and adjust its priority so that it is more likely to
19052 tmp
= ready
[first_store_pos
];
19053 for (i
=first_store_pos
; i
<*pn_ready
-1; i
++)
19054 ready
[i
] = ready
[i
+ 1];
19055 ready
[*pn_ready
-1] = tmp
;
19056 if INSN_PRIORITY_KNOWN (tmp
)
19057 INSN_PRIORITY (tmp
)++;
19060 else if (load_store_pendulum
== 2)
19062 /* Two loads have been issued in this cycle. Increase the priority
19063 of the first store in the ready list to favor it for issuing in
19069 if (is_store_insn (ready
[pos
])
19070 && INSN_PRIORITY_KNOWN (ready
[pos
]))
19072 INSN_PRIORITY (ready
[pos
])++;
19074 /* Adjust the pendulum to account for the fact that a store
19075 was found and increased in priority. This is to prevent
19076 increasing the priority of multiple stores */
19077 load_store_pendulum
++;
19086 return cached_can_issue_more
;
19089 /* Return whether the presence of INSN causes a dispatch group termination
19090 of group WHICH_GROUP.
19092 If WHICH_GROUP == current_group, this function will return true if INSN
19093 causes the termination of the current group (i.e, the dispatch group to
19094 which INSN belongs). This means that INSN will be the last insn in the
19095 group it belongs to.
19097 If WHICH_GROUP == previous_group, this function will return true if INSN
19098 causes the termination of the previous group (i.e, the dispatch group that
19099 precedes the group to which INSN belongs). This means that INSN will be
19100 the first insn in the group it belongs to). */
19103 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
19110 first
= insn_must_be_first_in_group (insn
);
19111 last
= insn_must_be_last_in_group (insn
);
19116 if (which_group
== current_group
)
19118 else if (which_group
== previous_group
)
19126 insn_must_be_first_in_group (rtx insn
)
19128 enum attr_type type
;
19131 || insn
== NULL_RTX
19132 || GET_CODE (insn
) == NOTE
19133 || GET_CODE (PATTERN (insn
)) == USE
19134 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19137 switch (rs6000_cpu
)
19139 case PROCESSOR_POWER5
:
19140 if (is_cracked_insn (insn
))
19142 case PROCESSOR_POWER4
:
19143 if (is_microcoded_insn (insn
))
19146 if (!rs6000_sched_groups
)
19149 type
= get_attr_type (insn
);
19156 case TYPE_DELAYED_CR
:
19157 case TYPE_CR_LOGICAL
:
19171 case PROCESSOR_POWER6
:
19172 type
= get_attr_type (insn
);
19176 case TYPE_INSERT_DWORD
:
19180 case TYPE_VAR_SHIFT_ROTATE
:
19187 case TYPE_INSERT_WORD
:
19188 case TYPE_DELAYED_COMPARE
:
19189 case TYPE_IMUL_COMPARE
:
19190 case TYPE_LMUL_COMPARE
:
19191 case TYPE_FPCOMPARE
:
19202 case TYPE_LOAD_EXT_UX
:
19204 case TYPE_STORE_UX
:
19205 case TYPE_FPLOAD_U
:
19206 case TYPE_FPLOAD_UX
:
19207 case TYPE_FPSTORE_U
:
19208 case TYPE_FPSTORE_UX
:
19222 insn_must_be_last_in_group (rtx insn
)
19224 enum attr_type type
;
19227 || insn
== NULL_RTX
19228 || GET_CODE (insn
) == NOTE
19229 || GET_CODE (PATTERN (insn
)) == USE
19230 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19233 switch (rs6000_cpu
) {
19234 case PROCESSOR_POWER4
:
19235 case PROCESSOR_POWER5
:
19236 if (is_microcoded_insn (insn
))
19239 if (is_branch_slot_insn (insn
))
19243 case PROCESSOR_POWER6
:
19244 type
= get_attr_type (insn
);
19251 case TYPE_VAR_SHIFT_ROTATE
:
19258 case TYPE_DELAYED_COMPARE
:
19259 case TYPE_IMUL_COMPARE
:
19260 case TYPE_LMUL_COMPARE
:
19261 case TYPE_FPCOMPARE
:
19282 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
19283 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
19286 is_costly_group (rtx
*group_insns
, rtx next_insn
)
19289 int issue_rate
= rs6000_issue_rate ();
19291 for (i
= 0; i
< issue_rate
; i
++)
19293 sd_iterator_def sd_it
;
19295 rtx insn
= group_insns
[i
];
19300 FOR_EACH_DEP (insn
, SD_LIST_FORW
, sd_it
, dep
)
19302 rtx next
= DEP_CON (dep
);
19304 if (next
== next_insn
19305 && rs6000_is_costly_dependence (dep
, dep_cost (dep
), 0))
19313 /* Utility of the function redefine_groups.
19314 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
19315 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
19316 to keep it "far" (in a separate group) from GROUP_INSNS, following
19317 one of the following schemes, depending on the value of the flag
19318 -minsert_sched_nops = X:
19319 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
19320 in order to force NEXT_INSN into a separate group.
19321 (2) X < sched_finish_regroup_exact: insert exactly X nops.
19322 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
19323 insertion (has a group just ended, how many vacant issue slots remain in the
19324 last group, and how many dispatch groups were encountered so far). */
19327 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
19328 rtx next_insn
, bool *group_end
, int can_issue_more
,
19333 int issue_rate
= rs6000_issue_rate ();
19334 bool end
= *group_end
;
19337 if (next_insn
== NULL_RTX
)
19338 return can_issue_more
;
19340 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
19341 return can_issue_more
;
19343 force
= is_costly_group (group_insns
, next_insn
);
19345 return can_issue_more
;
19347 if (sched_verbose
> 6)
19348 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
19349 *group_count
,can_issue_more
);
19351 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
19354 can_issue_more
= 0;
19356 /* Since only a branch can be issued in the last issue_slot, it is
19357 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
19358 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
19359 in this case the last nop will start a new group and the branch
19360 will be forced to the new group. */
19361 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
19364 while (can_issue_more
> 0)
19367 emit_insn_before (nop
, next_insn
);
19375 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
19377 int n_nops
= rs6000_sched_insert_nops
;
19379 /* Nops can't be issued from the branch slot, so the effective
19380 issue_rate for nops is 'issue_rate - 1'. */
19381 if (can_issue_more
== 0)
19382 can_issue_more
= issue_rate
;
19384 if (can_issue_more
== 0)
19386 can_issue_more
= issue_rate
- 1;
19389 for (i
= 0; i
< issue_rate
; i
++)
19391 group_insns
[i
] = 0;
19398 emit_insn_before (nop
, next_insn
);
19399 if (can_issue_more
== issue_rate
- 1) /* new group begins */
19402 if (can_issue_more
== 0)
19404 can_issue_more
= issue_rate
- 1;
19407 for (i
= 0; i
< issue_rate
; i
++)
19409 group_insns
[i
] = 0;
19415 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
19418 /* Is next_insn going to start a new group? */
19421 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
19422 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
19423 || (can_issue_more
< issue_rate
&&
19424 insn_terminates_group_p (next_insn
, previous_group
)));
19425 if (*group_end
&& end
)
19428 if (sched_verbose
> 6)
19429 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
19430 *group_count
, can_issue_more
);
19431 return can_issue_more
;
19434 return can_issue_more
;
19437 /* This function tries to synch the dispatch groups that the compiler "sees"
19438 with the dispatch groups that the processor dispatcher is expected to
19439 form in practice. It tries to achieve this synchronization by forcing the
19440 estimated processor grouping on the compiler (as opposed to the function
19441 'pad_goups' which tries to force the scheduler's grouping on the processor).
19443 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
19444 examines the (estimated) dispatch groups that will be formed by the processor
19445 dispatcher. It marks these group boundaries to reflect the estimated
19446 processor grouping, overriding the grouping that the scheduler had marked.
19447 Depending on the value of the flag '-minsert-sched-nops' this function can
19448 force certain insns into separate groups or force a certain distance between
19449 them by inserting nops, for example, if there exists a "costly dependence"
19452 The function estimates the group boundaries that the processor will form as
19453 follows: It keeps track of how many vacant issue slots are available after
19454 each insn. A subsequent insn will start a new group if one of the following
19456 - no more vacant issue slots remain in the current dispatch group.
19457 - only the last issue slot, which is the branch slot, is vacant, but the next
19458 insn is not a branch.
19459 - only the last 2 or less issue slots, including the branch slot, are vacant,
19460 which means that a cracked insn (which occupies two issue slots) can't be
19461 issued in this group.
19462 - less than 'issue_rate' slots are vacant, and the next insn always needs to
19463 start a new group. */
19466 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
19468 rtx insn
, next_insn
;
19470 int can_issue_more
;
19473 int group_count
= 0;
19477 issue_rate
= rs6000_issue_rate ();
19478 group_insns
= alloca (issue_rate
* sizeof (rtx
));
19479 for (i
= 0; i
< issue_rate
; i
++)
19481 group_insns
[i
] = 0;
19483 can_issue_more
= issue_rate
;
19485 insn
= get_next_active_insn (prev_head_insn
, tail
);
19488 while (insn
!= NULL_RTX
)
19490 slot
= (issue_rate
- can_issue_more
);
19491 group_insns
[slot
] = insn
;
19493 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
19494 if (insn_terminates_group_p (insn
, current_group
))
19495 can_issue_more
= 0;
19497 next_insn
= get_next_active_insn (insn
, tail
);
19498 if (next_insn
== NULL_RTX
)
19499 return group_count
+ 1;
19501 /* Is next_insn going to start a new group? */
19503 = (can_issue_more
== 0
19504 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
19505 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
19506 || (can_issue_more
< issue_rate
&&
19507 insn_terminates_group_p (next_insn
, previous_group
)));
19509 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
19510 next_insn
, &group_end
, can_issue_more
,
19516 can_issue_more
= 0;
19517 for (i
= 0; i
< issue_rate
; i
++)
19519 group_insns
[i
] = 0;
19523 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
19524 PUT_MODE (next_insn
, VOIDmode
);
19525 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
19526 PUT_MODE (next_insn
, TImode
);
19529 if (can_issue_more
== 0)
19530 can_issue_more
= issue_rate
;
19533 return group_count
;
19536 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
19537 dispatch group boundaries that the scheduler had marked. Pad with nops
19538 any dispatch groups which have vacant issue slots, in order to force the
19539 scheduler's grouping on the processor dispatcher. The function
19540 returns the number of dispatch groups found. */
19543 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
19545 rtx insn
, next_insn
;
19548 int can_issue_more
;
19550 int group_count
= 0;
19552 /* Initialize issue_rate. */
19553 issue_rate
= rs6000_issue_rate ();
19554 can_issue_more
= issue_rate
;
19556 insn
= get_next_active_insn (prev_head_insn
, tail
);
19557 next_insn
= get_next_active_insn (insn
, tail
);
19559 while (insn
!= NULL_RTX
)
19562 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
19564 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
19566 if (next_insn
== NULL_RTX
)
19571 /* If the scheduler had marked group termination at this location
19572 (between insn and next_indn), and neither insn nor next_insn will
19573 force group termination, pad the group with nops to force group
19576 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
19577 && !insn_terminates_group_p (insn
, current_group
)
19578 && !insn_terminates_group_p (next_insn
, previous_group
))
19580 if (!is_branch_slot_insn (next_insn
))
19583 while (can_issue_more
)
19586 emit_insn_before (nop
, next_insn
);
19591 can_issue_more
= issue_rate
;
19596 next_insn
= get_next_active_insn (insn
, tail
);
19599 return group_count
;
19602 /* We're beginning a new block. Initialize data structures as necessary. */
19605 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED
,
19606 int sched_verbose ATTRIBUTE_UNUSED
,
19607 int max_ready ATTRIBUTE_UNUSED
)
19609 last_scheduled_insn
= NULL_RTX
;
19610 load_store_pendulum
= 0;
19613 /* The following function is called at the end of scheduling BB.
19614 After reload, it inserts nops at insn group bundling. */
19617 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
19622 fprintf (dump
, "=== Finishing schedule.\n");
19624 if (reload_completed
&& rs6000_sched_groups
)
19626 if (rs6000_sched_insert_nops
== sched_finish_none
)
19629 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
19630 n_groups
= pad_groups (dump
, sched_verbose
,
19631 current_sched_info
->prev_head
,
19632 current_sched_info
->next_tail
);
19634 n_groups
= redefine_groups (dump
, sched_verbose
,
19635 current_sched_info
->prev_head
,
19636 current_sched_info
->next_tail
);
19638 if (sched_verbose
>= 6)
19640 fprintf (dump
, "ngroups = %d\n", n_groups
);
19641 print_rtl (dump
, current_sched_info
->prev_head
);
19642 fprintf (dump
, "Done finish_sched\n");
19647 /* Length in units of the trampoline for entering a nested function. */
19650 rs6000_trampoline_size (void)
19654 switch (DEFAULT_ABI
)
19657 gcc_unreachable ();
19660 ret
= (TARGET_32BIT
) ? 12 : 24;
19665 ret
= (TARGET_32BIT
) ? 40 : 48;
19672 /* Emit RTL insns to initialize the variable parts of a trampoline.
19673 FNADDR is an RTX for the address of the function's pure code.
19674 CXT is an RTX for the static chain value for the function. */
19677 rs6000_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
19679 int regsize
= (TARGET_32BIT
) ? 4 : 8;
19680 rtx ctx_reg
= force_reg (Pmode
, cxt
);
19682 switch (DEFAULT_ABI
)
19685 gcc_unreachable ();
19687 /* Macros to shorten the code expansions below. */
19688 #define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
19689 #define MEM_PLUS(addr,offset) \
19690 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
19692 /* Under AIX, just build the 3 word function descriptor */
19695 rtx fn_reg
= gen_reg_rtx (Pmode
);
19696 rtx toc_reg
= gen_reg_rtx (Pmode
);
19697 emit_move_insn (fn_reg
, MEM_DEREF (fnaddr
));
19698 emit_move_insn (toc_reg
, MEM_PLUS (fnaddr
, regsize
));
19699 emit_move_insn (MEM_DEREF (addr
), fn_reg
);
19700 emit_move_insn (MEM_PLUS (addr
, regsize
), toc_reg
);
19701 emit_move_insn (MEM_PLUS (addr
, 2*regsize
), ctx_reg
);
19705 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
19708 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__trampoline_setup"),
19709 FALSE
, VOIDmode
, 4,
19711 GEN_INT (rs6000_trampoline_size ()), SImode
,
19721 /* Table of valid machine attributes. */
19723 const struct attribute_spec rs6000_attribute_table
[] =
19725 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
19726 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
},
19727 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
19728 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
19729 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
19730 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
19731 #ifdef SUBTARGET_ATTRIBUTE_TABLE
19732 SUBTARGET_ATTRIBUTE_TABLE
,
19734 { NULL
, 0, 0, false, false, false, NULL
}
19737 /* Handle the "altivec" attribute. The attribute may have
19738 arguments as follows:
19740 __attribute__((altivec(vector__)))
19741 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
19742 __attribute__((altivec(bool__))) (always followed by 'unsigned')
19744 and may appear more than once (e.g., 'vector bool char') in a
19745 given declaration. */
19748 rs6000_handle_altivec_attribute (tree
*node
,
19749 tree name ATTRIBUTE_UNUSED
,
19751 int flags ATTRIBUTE_UNUSED
,
19752 bool *no_add_attrs
)
19754 tree type
= *node
, result
= NULL_TREE
;
19755 enum machine_mode mode
;
19758 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
19759 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
19760 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
19763 while (POINTER_TYPE_P (type
)
19764 || TREE_CODE (type
) == FUNCTION_TYPE
19765 || TREE_CODE (type
) == METHOD_TYPE
19766 || TREE_CODE (type
) == ARRAY_TYPE
)
19767 type
= TREE_TYPE (type
);
19769 mode
= TYPE_MODE (type
);
19771 /* Check for invalid AltiVec type qualifiers. */
19772 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
19775 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
19776 else if (rs6000_warn_altivec_long
)
19777 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
19779 else if (type
== long_long_unsigned_type_node
19780 || type
== long_long_integer_type_node
)
19781 error ("use of %<long long%> in AltiVec types is invalid");
19782 else if (type
== double_type_node
)
19783 error ("use of %<double%> in AltiVec types is invalid");
19784 else if (type
== long_double_type_node
)
19785 error ("use of %<long double%> in AltiVec types is invalid");
19786 else if (type
== boolean_type_node
)
19787 error ("use of boolean types in AltiVec types is invalid");
19788 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
19789 error ("use of %<complex%> in AltiVec types is invalid");
19790 else if (DECIMAL_FLOAT_MODE_P (mode
))
19791 error ("use of decimal floating point types in AltiVec types is invalid");
19793 switch (altivec_type
)
19796 unsigned_p
= TYPE_UNSIGNED (type
);
19800 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
19803 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
19806 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
19808 case SFmode
: result
= V4SF_type_node
; break;
19809 /* If the user says 'vector int bool', we may be handed the 'bool'
19810 attribute _before_ the 'vector' attribute, and so select the
19811 proper type in the 'b' case below. */
19812 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
19820 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
19821 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
19822 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
19829 case V8HImode
: result
= pixel_V8HI_type_node
;
19835 if (result
&& result
!= type
&& TYPE_READONLY (type
))
19836 result
= build_qualified_type (result
, TYPE_QUAL_CONST
);
19838 *no_add_attrs
= true; /* No need to hang on to the attribute. */
19841 *node
= lang_hooks
.types
.reconstruct_complex_type (*node
, result
);
19846 /* AltiVec defines four built-in scalar types that serve as vector
19847 elements; we must teach the compiler how to mangle them. */
19849 static const char *
19850 rs6000_mangle_type (const_tree type
)
19852 type
= TYPE_MAIN_VARIANT (type
);
19854 if (TREE_CODE (type
) != VOID_TYPE
&& TREE_CODE (type
) != BOOLEAN_TYPE
19855 && TREE_CODE (type
) != INTEGER_TYPE
&& TREE_CODE (type
) != REAL_TYPE
)
19858 if (type
== bool_char_type_node
) return "U6__boolc";
19859 if (type
== bool_short_type_node
) return "U6__bools";
19860 if (type
== pixel_type_node
) return "u7__pixel";
19861 if (type
== bool_int_type_node
) return "U6__booli";
19863 /* Mangle IBM extended float long double as `g' (__float128) on
19864 powerpc*-linux where long-double-64 previously was the default. */
19865 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
19867 && TARGET_LONG_DOUBLE_128
19868 && !TARGET_IEEEQUAD
)
19871 /* For all other types, use normal C++ mangling. */
19875 /* Handle a "longcall" or "shortcall" attribute; arguments as in
19876 struct attribute_spec.handler. */
19879 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
19880 tree args ATTRIBUTE_UNUSED
,
19881 int flags ATTRIBUTE_UNUSED
,
19882 bool *no_add_attrs
)
19884 if (TREE_CODE (*node
) != FUNCTION_TYPE
19885 && TREE_CODE (*node
) != FIELD_DECL
19886 && TREE_CODE (*node
) != TYPE_DECL
)
19888 warning (OPT_Wattributes
, "%qs attribute only applies to functions",
19889 IDENTIFIER_POINTER (name
));
19890 *no_add_attrs
= true;
19896 /* Set longcall attributes on all functions declared when
19897 rs6000_default_long_calls is true. */
19899 rs6000_set_default_type_attributes (tree type
)
19901 if (rs6000_default_long_calls
19902 && (TREE_CODE (type
) == FUNCTION_TYPE
19903 || TREE_CODE (type
) == METHOD_TYPE
))
19904 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
19906 TYPE_ATTRIBUTES (type
));
19909 darwin_set_default_type_attributes (type
);
19913 /* Return a reference suitable for calling a function with the
19914 longcall attribute. */
19917 rs6000_longcall_ref (rtx call_ref
)
19919 const char *call_name
;
19922 if (GET_CODE (call_ref
) != SYMBOL_REF
)
19925 /* System V adds '.' to the internal name, so skip them. */
19926 call_name
= XSTR (call_ref
, 0);
19927 if (*call_name
== '.')
19929 while (*call_name
== '.')
19932 node
= get_identifier (call_name
);
19933 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
19936 return force_reg (Pmode
, call_ref
);
19939 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
19940 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
19943 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
19944 struct attribute_spec.handler. */
19946 rs6000_handle_struct_attribute (tree
*node
, tree name
,
19947 tree args ATTRIBUTE_UNUSED
,
19948 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
19951 if (DECL_P (*node
))
19953 if (TREE_CODE (*node
) == TYPE_DECL
)
19954 type
= &TREE_TYPE (*node
);
19959 if (!(type
&& (TREE_CODE (*type
) == RECORD_TYPE
19960 || TREE_CODE (*type
) == UNION_TYPE
)))
19962 warning (OPT_Wattributes
, "%qs attribute ignored", IDENTIFIER_POINTER (name
));
19963 *no_add_attrs
= true;
19966 else if ((is_attribute_p ("ms_struct", name
)
19967 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type
)))
19968 || ((is_attribute_p ("gcc_struct", name
)
19969 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type
)))))
19971 warning (OPT_Wattributes
, "%qs incompatible attribute ignored",
19972 IDENTIFIER_POINTER (name
));
19973 *no_add_attrs
= true;
19980 rs6000_ms_bitfield_layout_p (const_tree record_type
)
19982 return (TARGET_USE_MS_BITFIELD_LAYOUT
&&
19983 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type
)))
19984 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type
));
19987 #ifdef USING_ELFOS_H
19989 /* A get_unnamed_section callback, used for switching to toc_section. */
19992 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
19994 if (DEFAULT_ABI
== ABI_AIX
19995 && TARGET_MINIMAL_TOC
19996 && !TARGET_RELOCATABLE
)
19998 if (!toc_initialized
)
20000 toc_initialized
= 1;
20001 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
20002 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LCTOC", 0);
20003 fprintf (asm_out_file
, "\t.tc ");
20004 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1[TC],");
20005 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
20006 fprintf (asm_out_file
, "\n");
20008 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
20009 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
20010 fprintf (asm_out_file
, " = .+32768\n");
20013 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
20015 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_RELOCATABLE
)
20016 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
20019 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
20020 if (!toc_initialized
)
20022 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
20023 fprintf (asm_out_file
, " = .+32768\n");
20024 toc_initialized
= 1;
20029 /* Implement TARGET_ASM_INIT_SECTIONS. */
20032 rs6000_elf_asm_init_sections (void)
20035 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op
, NULL
);
20038 = get_unnamed_section (SECTION_WRITE
, output_section_asm_op
,
20039 SDATA2_SECTION_ASM_OP
);
20042 /* Implement TARGET_SELECT_RTX_SECTION. */
20045 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
20046 unsigned HOST_WIDE_INT align
)
20048 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
20049 return toc_section
;
20051 return default_elf_select_rtx_section (mode
, x
, align
);
20054 /* For a SYMBOL_REF, set generic flags and then perform some
20055 target-specific processing.
20057 When the AIX ABI is requested on a non-AIX system, replace the
20058 function name with the real name (with a leading .) rather than the
20059 function descriptor name. This saves a lot of overriding code to
20060 read the prefixes. */
20063 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
20065 default_encode_section_info (decl
, rtl
, first
);
20068 && TREE_CODE (decl
) == FUNCTION_DECL
20070 && DEFAULT_ABI
== ABI_AIX
)
20072 rtx sym_ref
= XEXP (rtl
, 0);
20073 size_t len
= strlen (XSTR (sym_ref
, 0));
20074 char *str
= alloca (len
+ 2);
20076 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
20077 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
20082 compare_section_name (const char *section
, const char *template)
20086 len
= strlen (template);
20087 return (strncmp (section
, template, len
) == 0
20088 && (section
[len
] == 0 || section
[len
] == '.'));
20092 rs6000_elf_in_small_data_p (const_tree decl
)
20094 if (rs6000_sdata
== SDATA_NONE
)
20097 /* We want to merge strings, so we never consider them small data. */
20098 if (TREE_CODE (decl
) == STRING_CST
)
20101 /* Functions are never in the small data area. */
20102 if (TREE_CODE (decl
) == FUNCTION_DECL
)
20105 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
20107 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
20108 if (compare_section_name (section
, ".sdata")
20109 || compare_section_name (section
, ".sdata2")
20110 || compare_section_name (section
, ".gnu.linkonce.s")
20111 || compare_section_name (section
, ".sbss")
20112 || compare_section_name (section
, ".sbss2")
20113 || compare_section_name (section
, ".gnu.linkonce.sb")
20114 || strcmp (section
, ".PPC.EMB.sdata0") == 0
20115 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
20120 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
20123 && (unsigned HOST_WIDE_INT
) size
<= g_switch_value
20124 /* If it's not public, and we're not going to reference it there,
20125 there's no need to put it in the small data section. */
20126 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
20133 #endif /* USING_ELFOS_H */
20135 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
20138 rs6000_use_blocks_for_constant_p (enum machine_mode mode
, const_rtx x
)
20140 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
);
20143 /* Return a REG that occurs in ADDR with coefficient 1.
20144 ADDR can be effectively incremented by incrementing REG.
20146 r0 is special and we must not select it as an address
20147 register by this routine since our caller will try to
20148 increment the returned register via an "la" instruction. */
20151 find_addr_reg (rtx addr
)
20153 while (GET_CODE (addr
) == PLUS
)
20155 if (GET_CODE (XEXP (addr
, 0)) == REG
20156 && REGNO (XEXP (addr
, 0)) != 0)
20157 addr
= XEXP (addr
, 0);
20158 else if (GET_CODE (XEXP (addr
, 1)) == REG
20159 && REGNO (XEXP (addr
, 1)) != 0)
20160 addr
= XEXP (addr
, 1);
20161 else if (CONSTANT_P (XEXP (addr
, 0)))
20162 addr
= XEXP (addr
, 1);
20163 else if (CONSTANT_P (XEXP (addr
, 1)))
20164 addr
= XEXP (addr
, 0);
20166 gcc_unreachable ();
20168 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
20173 rs6000_fatal_bad_address (rtx op
)
20175 fatal_insn ("bad address", op
);
20180 static tree branch_island_list
= 0;
20182 /* Remember to generate a branch island for far calls to the given
20186 add_compiler_branch_island (tree label_name
, tree function_name
,
20189 tree branch_island
= build_tree_list (function_name
, label_name
);
20190 TREE_TYPE (branch_island
) = build_int_cst (NULL_TREE
, line_number
);
20191 TREE_CHAIN (branch_island
) = branch_island_list
;
20192 branch_island_list
= branch_island
;
20195 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
20196 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
20197 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
20198 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
20200 /* Generate far-jump branch islands for everything on the
20201 branch_island_list. Invoked immediately after the last instruction
20202 of the epilogue has been emitted; the branch-islands must be
20203 appended to, and contiguous with, the function body. Mach-O stubs
20204 are generated in machopic_output_stub(). */
20207 macho_branch_islands (void)
20210 tree branch_island
;
20212 for (branch_island
= branch_island_list
;
20214 branch_island
= TREE_CHAIN (branch_island
))
20216 const char *label
=
20217 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island
));
20219 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island
));
20220 char name_buf
[512];
20221 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
20222 if (name
[0] == '*' || name
[0] == '&')
20223 strcpy (name_buf
, name
+1);
20227 strcpy (name_buf
+1, name
);
20229 strcpy (tmp_buf
, "\n");
20230 strcat (tmp_buf
, label
);
20231 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
20232 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
20233 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
20234 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
20237 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
20238 strcat (tmp_buf
, label
);
20239 strcat (tmp_buf
, "_pic\n");
20240 strcat (tmp_buf
, label
);
20241 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
20243 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
20244 strcat (tmp_buf
, name_buf
);
20245 strcat (tmp_buf
, " - ");
20246 strcat (tmp_buf
, label
);
20247 strcat (tmp_buf
, "_pic)\n");
20249 strcat (tmp_buf
, "\tmtlr r0\n");
20251 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
20252 strcat (tmp_buf
, name_buf
);
20253 strcat (tmp_buf
, " - ");
20254 strcat (tmp_buf
, label
);
20255 strcat (tmp_buf
, "_pic)\n");
20257 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
20261 strcat (tmp_buf
, ":\nlis r12,hi16(");
20262 strcat (tmp_buf
, name_buf
);
20263 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
20264 strcat (tmp_buf
, name_buf
);
20265 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
20267 output_asm_insn (tmp_buf
, 0);
20268 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
20269 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
20270 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
20271 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
20274 branch_island_list
= 0;
20277 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
20278 already there or not. */
20281 no_previous_def (tree function_name
)
20283 tree branch_island
;
20284 for (branch_island
= branch_island_list
;
20286 branch_island
= TREE_CHAIN (branch_island
))
20287 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
20292 /* GET_PREV_LABEL gets the label name from the previous definition of
20296 get_prev_label (tree function_name
)
20298 tree branch_island
;
20299 for (branch_island
= branch_island_list
;
20301 branch_island
= TREE_CHAIN (branch_island
))
20302 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
20303 return BRANCH_ISLAND_LABEL_NAME (branch_island
);
20307 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
20308 #define DARWIN_LINKER_GENERATES_ISLANDS 0
20311 /* KEXTs still need branch islands. */
20312 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
20313 || flag_mkernel || flag_apple_kext)
20315 /* INSN is either a function call or a millicode call. It may have an
20316 unconditional jump in its delay slot.
20318 CALL_DEST is the routine we are calling. */
20321 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
20322 int cookie_operand_number
)
20324 static char buf
[256];
20325 if (DARWIN_GENERATE_ISLANDS
20326 && GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
20327 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
20330 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
20332 if (no_previous_def (funname
))
20334 rtx label_rtx
= gen_label_rtx ();
20335 char *label_buf
, temp_buf
[256];
20336 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
20337 CODE_LABEL_NUMBER (label_rtx
));
20338 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
20339 labelname
= get_identifier (label_buf
);
20340 add_compiler_branch_island (labelname
, funname
, insn_line (insn
));
20343 labelname
= get_prev_label (funname
);
20345 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
20346 instruction will reach 'foo', otherwise link as 'bl L42'".
20347 "L42" should be a 'branch island', that will do a far jump to
20348 'foo'. Branch islands are generated in
20349 macho_branch_islands(). */
20350 sprintf (buf
, "jbsr %%z%d,%.246s",
20351 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
20354 sprintf (buf
, "bl %%z%d", dest_operand_number
);
20358 /* Generate PIC and indirect symbol stubs. */
20361 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
20363 unsigned int length
;
20364 char *symbol_name
, *lazy_ptr_name
;
20365 char *local_label_0
;
20366 static int label
= 0;
20368 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
20369 symb
= (*targetm
.strip_name_encoding
) (symb
);
20372 length
= strlen (symb
);
20373 symbol_name
= alloca (length
+ 32);
20374 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
20376 lazy_ptr_name
= alloca (length
+ 32);
20377 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
20380 switch_to_section (darwin_sections
[machopic_picsymbol_stub1_section
]);
20382 switch_to_section (darwin_sections
[machopic_symbol_stub1_section
]);
20386 fprintf (file
, "\t.align 5\n");
20388 fprintf (file
, "%s:\n", stub
);
20389 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
20392 local_label_0
= alloca (sizeof ("\"L00000000000$spb\""));
20393 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
20395 fprintf (file
, "\tmflr r0\n");
20396 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
20397 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
20398 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
20399 lazy_ptr_name
, local_label_0
);
20400 fprintf (file
, "\tmtlr r0\n");
20401 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
20402 (TARGET_64BIT
? "ldu" : "lwzu"),
20403 lazy_ptr_name
, local_label_0
);
20404 fprintf (file
, "\tmtctr r12\n");
20405 fprintf (file
, "\tbctr\n");
20409 fprintf (file
, "\t.align 4\n");
20411 fprintf (file
, "%s:\n", stub
);
20412 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
20414 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
20415 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
20416 (TARGET_64BIT
? "ldu" : "lwzu"),
20418 fprintf (file
, "\tmtctr r12\n");
20419 fprintf (file
, "\tbctr\n");
20422 switch_to_section (darwin_sections
[machopic_lazy_symbol_ptr_section
]);
20423 fprintf (file
, "%s:\n", lazy_ptr_name
);
20424 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
20425 fprintf (file
, "%sdyld_stub_binding_helper\n",
20426 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
20429 /* Legitimize PIC addresses. If the address is already
20430 position-independent, we return ORIG. Newly generated
20431 position-independent addresses go into a reg. This is REG if non
20432 zero, otherwise we allocate register(s) as necessary. */
20434 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
20437 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
20442 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
20443 reg
= gen_reg_rtx (Pmode
);
20445 if (GET_CODE (orig
) == CONST
)
20449 if (GET_CODE (XEXP (orig
, 0)) == PLUS
20450 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
20453 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
20455 /* Use a different reg for the intermediate value, as
20456 it will be marked UNCHANGING. */
20457 reg_temp
= !can_create_pseudo_p () ? reg
: gen_reg_rtx (Pmode
);
20458 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
20461 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
20464 if (GET_CODE (offset
) == CONST_INT
)
20466 if (SMALL_INT (offset
))
20467 return plus_constant (base
, INTVAL (offset
));
20468 else if (! reload_in_progress
&& ! reload_completed
)
20469 offset
= force_reg (Pmode
, offset
);
20472 rtx mem
= force_const_mem (Pmode
, orig
);
20473 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
20476 return gen_rtx_PLUS (Pmode
, base
, offset
);
20479 /* Fall back on generic machopic code. */
20480 return machopic_legitimize_pic_address (orig
, mode
, reg
);
20483 /* Output a .machine directive for the Darwin assembler, and call
20484 the generic start_file routine. */
20487 rs6000_darwin_file_start (void)
20489 static const struct
20495 { "ppc64", "ppc64", MASK_64BIT
},
20496 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
20497 { "power4", "ppc970", 0 },
20498 { "G5", "ppc970", 0 },
20499 { "7450", "ppc7450", 0 },
20500 { "7400", "ppc7400", MASK_ALTIVEC
},
20501 { "G4", "ppc7400", 0 },
20502 { "750", "ppc750", 0 },
20503 { "740", "ppc750", 0 },
20504 { "G3", "ppc750", 0 },
20505 { "604e", "ppc604e", 0 },
20506 { "604", "ppc604", 0 },
20507 { "603e", "ppc603", 0 },
20508 { "603", "ppc603", 0 },
20509 { "601", "ppc601", 0 },
20510 { NULL
, "ppc", 0 } };
20511 const char *cpu_id
= "";
20514 rs6000_file_start ();
20515 darwin_file_start ();
20517 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
20518 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
20519 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
20520 && rs6000_select
[i
].string
[0] != '\0')
20521 cpu_id
= rs6000_select
[i
].string
;
20523 /* Look through the mapping array. Pick the first name that either
20524 matches the argument, has a bit set in IF_SET that is also set
20525 in the target flags, or has a NULL name. */
20528 while (mapping
[i
].arg
!= NULL
20529 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
20530 && (mapping
[i
].if_set
& target_flags
) == 0)
20533 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
20536 #endif /* TARGET_MACHO */
20540 rs6000_elf_reloc_rw_mask (void)
20544 else if (DEFAULT_ABI
== ABI_AIX
)
20550 /* Record an element in the table of global constructors. SYMBOL is
20551 a SYMBOL_REF of the function to be called; PRIORITY is a number
20552 between 0 and MAX_INIT_PRIORITY.
20554 This differs from default_named_section_asm_out_constructor in
20555 that we have special handling for -mrelocatable. */
20558 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
20560 const char *section
= ".ctors";
20563 if (priority
!= DEFAULT_INIT_PRIORITY
)
20565 sprintf (buf
, ".ctors.%.5u",
20566 /* Invert the numbering so the linker puts us in the proper
20567 order; constructors are run from right to left, and the
20568 linker sorts in increasing order. */
20569 MAX_INIT_PRIORITY
- priority
);
20573 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
20574 assemble_align (POINTER_SIZE
);
20576 if (TARGET_RELOCATABLE
)
20578 fputs ("\t.long (", asm_out_file
);
20579 output_addr_const (asm_out_file
, symbol
);
20580 fputs (")@fixup\n", asm_out_file
);
20583 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
20587 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
20589 const char *section
= ".dtors";
20592 if (priority
!= DEFAULT_INIT_PRIORITY
)
20594 sprintf (buf
, ".dtors.%.5u",
20595 /* Invert the numbering so the linker puts us in the proper
20596 order; constructors are run from right to left, and the
20597 linker sorts in increasing order. */
20598 MAX_INIT_PRIORITY
- priority
);
20602 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
20603 assemble_align (POINTER_SIZE
);
20605 if (TARGET_RELOCATABLE
)
20607 fputs ("\t.long (", asm_out_file
);
20608 output_addr_const (asm_out_file
, symbol
);
20609 fputs (")@fixup\n", asm_out_file
);
20612 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
20616 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
20620 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
20621 ASM_OUTPUT_LABEL (file
, name
);
20622 fputs (DOUBLE_INT_ASM_OP
, file
);
20623 rs6000_output_function_entry (file
, name
);
20624 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
20627 fputs ("\t.size\t", file
);
20628 assemble_name (file
, name
);
20629 fputs (",24\n\t.type\t.", file
);
20630 assemble_name (file
, name
);
20631 fputs (",@function\n", file
);
20632 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
20634 fputs ("\t.globl\t.", file
);
20635 assemble_name (file
, name
);
20640 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
20641 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
20642 rs6000_output_function_entry (file
, name
);
20643 fputs (":\n", file
);
20647 if (TARGET_RELOCATABLE
20648 && !TARGET_SECURE_PLT
20649 && (get_pool_size () != 0 || current_function_profile
)
20654 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
20656 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
20657 fprintf (file
, "\t.long ");
20658 assemble_name (file
, buf
);
20660 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
20661 assemble_name (file
, buf
);
20665 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
20666 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
20668 if (DEFAULT_ABI
== ABI_AIX
)
20670 const char *desc_name
, *orig_name
;
20672 orig_name
= (*targetm
.strip_name_encoding
) (name
);
20673 desc_name
= orig_name
;
20674 while (*desc_name
== '.')
20677 if (TREE_PUBLIC (decl
))
20678 fprintf (file
, "\t.globl %s\n", desc_name
);
20680 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
20681 fprintf (file
, "%s:\n", desc_name
);
20682 fprintf (file
, "\t.long %s\n", orig_name
);
20683 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
20684 if (DEFAULT_ABI
== ABI_AIX
)
20685 fputs ("\t.long 0\n", file
);
20686 fprintf (file
, "\t.previous\n");
20688 ASM_OUTPUT_LABEL (file
, name
);
20692 rs6000_elf_end_indicate_exec_stack (void)
20695 file_end_indicate_exec_stack ();
20701 rs6000_xcoff_asm_output_anchor (rtx symbol
)
20705 sprintf (buffer
, "$ + " HOST_WIDE_INT_PRINT_DEC
,
20706 SYMBOL_REF_BLOCK_OFFSET (symbol
));
20707 ASM_OUTPUT_DEF (asm_out_file
, XSTR (symbol
, 0), buffer
);
20711 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
20713 fputs (GLOBAL_ASM_OP
, stream
);
20714 RS6000_OUTPUT_BASENAME (stream
, name
);
20715 putc ('\n', stream
);
20718 /* A get_unnamed_decl callback, used for read-only sections. PTR
20719 points to the section string variable. */
20722 rs6000_xcoff_output_readonly_section_asm_op (const void *directive
)
20724 fprintf (asm_out_file
, "\t.csect %s[RO],%s\n",
20725 *(const char *const *) directive
,
20726 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
20729 /* Likewise for read-write sections. */
20732 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive
)
20734 fprintf (asm_out_file
, "\t.csect %s[RW],%s\n",
20735 *(const char *const *) directive
,
20736 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
20739 /* A get_unnamed_section callback, used for switching to toc_section. */
20742 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
20744 if (TARGET_MINIMAL_TOC
)
20746 /* toc_section is always selected at least once from
20747 rs6000_xcoff_file_start, so this is guaranteed to
20748 always be defined once and only once in each file. */
20749 if (!toc_initialized
)
20751 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file
);
20752 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file
);
20753 toc_initialized
= 1;
20755 fprintf (asm_out_file
, "\t.csect toc_table[RW]%s\n",
20756 (TARGET_32BIT
? "" : ",3"));
20759 fputs ("\t.toc\n", asm_out_file
);
20762 /* Implement TARGET_ASM_INIT_SECTIONS. */
20765 rs6000_xcoff_asm_init_sections (void)
20767 read_only_data_section
20768 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
20769 &xcoff_read_only_section_name
);
20771 private_data_section
20772 = get_unnamed_section (SECTION_WRITE
,
20773 rs6000_xcoff_output_readwrite_section_asm_op
,
20774 &xcoff_private_data_section_name
);
20776 read_only_private_data_section
20777 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
20778 &xcoff_private_data_section_name
);
20781 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op
, NULL
);
20783 readonly_data_section
= read_only_data_section
;
20784 exception_section
= data_section
;
20788 rs6000_xcoff_reloc_rw_mask (void)
20794 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
20795 tree decl ATTRIBUTE_UNUSED
)
20798 static const char * const suffix
[3] = { "PR", "RO", "RW" };
20800 if (flags
& SECTION_CODE
)
20802 else if (flags
& SECTION_WRITE
)
20807 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
20808 (flags
& SECTION_CODE
) ? "." : "",
20809 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
20813 rs6000_xcoff_select_section (tree decl
, int reloc
,
20814 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
20816 if (decl_readonly_section (decl
, reloc
))
20818 if (TREE_PUBLIC (decl
))
20819 return read_only_data_section
;
20821 return read_only_private_data_section
;
20825 if (TREE_PUBLIC (decl
))
20826 return data_section
;
20828 return private_data_section
;
20833 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
20837 /* Use select_section for private and uninitialized data. */
20838 if (!TREE_PUBLIC (decl
)
20839 || DECL_COMMON (decl
)
20840 || DECL_INITIAL (decl
) == NULL_TREE
20841 || DECL_INITIAL (decl
) == error_mark_node
20842 || (flag_zero_initialized_in_bss
20843 && initializer_zerop (DECL_INITIAL (decl
))))
20846 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
20847 name
= (*targetm
.strip_name_encoding
) (name
);
20848 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
20851 /* Select section for constant in constant pool.
20853 On RS/6000, all constants are in the private read-only data area.
20854 However, if this is being placed in the TOC it must be output as a
20858 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
20859 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
20861 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
20862 return toc_section
;
20864 return read_only_private_data_section
;
20867 /* Remove any trailing [DS] or the like from the symbol name. */
20869 static const char *
20870 rs6000_xcoff_strip_name_encoding (const char *name
)
20875 len
= strlen (name
);
20876 if (name
[len
- 1] == ']')
20877 return ggc_alloc_string (name
, len
- 4);
20882 /* Section attributes. AIX is always PIC. */
20884 static unsigned int
20885 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
20887 unsigned int align
;
20888 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
20890 /* Align to at least UNIT size. */
20891 if (flags
& SECTION_CODE
)
20892 align
= MIN_UNITS_PER_WORD
;
20894 /* Increase alignment of large objects if not already stricter. */
20895 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
20896 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
20897 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
20899 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
20902 /* Output at beginning of assembler file.
20904 Initialize the section names for the RS/6000 at this point.
20906 Specify filename, including full path, to assembler.
20908 We want to go into the TOC section so at least one .toc will be emitted.
20909 Also, in order to output proper .bs/.es pairs, we need at least one static
20910 [RW] section emitted.
20912 Finally, declare mcount when profiling to make the assembler happy. */
20915 rs6000_xcoff_file_start (void)
20917 rs6000_gen_section_name (&xcoff_bss_section_name
,
20918 main_input_filename
, ".bss_");
20919 rs6000_gen_section_name (&xcoff_private_data_section_name
,
20920 main_input_filename
, ".rw_");
20921 rs6000_gen_section_name (&xcoff_read_only_section_name
,
20922 main_input_filename
, ".ro_");
20924 fputs ("\t.file\t", asm_out_file
);
20925 output_quoted_string (asm_out_file
, main_input_filename
);
20926 fputc ('\n', asm_out_file
);
20927 if (write_symbols
!= NO_DEBUG
)
20928 switch_to_section (private_data_section
);
20929 switch_to_section (text_section
);
20931 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
20932 rs6000_file_start ();
20935 /* Output at end of assembler file.
20936 On the RS/6000, referencing data should automatically pull in text. */
20939 rs6000_xcoff_file_end (void)
20941 switch_to_section (text_section
);
20942 fputs ("_section_.text:\n", asm_out_file
);
20943 switch_to_section (data_section
);
20944 fputs (TARGET_32BIT
20945 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
20948 #endif /* TARGET_XCOFF */
20950 /* Compute a (partial) cost for rtx X. Return true if the complete
20951 cost has been computed, and false if subexpressions should be
20952 scanned. In either case, *TOTAL contains the cost result. */
20955 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
20957 enum machine_mode mode
= GET_MODE (x
);
20961 /* On the RS/6000, if it is valid in the insn, it is free. */
20963 if (((outer_code
== SET
20964 || outer_code
== PLUS
20965 || outer_code
== MINUS
)
20966 && (satisfies_constraint_I (x
)
20967 || satisfies_constraint_L (x
)))
20968 || (outer_code
== AND
20969 && (satisfies_constraint_K (x
)
20971 ? satisfies_constraint_L (x
)
20972 : satisfies_constraint_J (x
))
20973 || mask_operand (x
, mode
)
20975 && mask64_operand (x
, DImode
))))
20976 || ((outer_code
== IOR
|| outer_code
== XOR
)
20977 && (satisfies_constraint_K (x
)
20979 ? satisfies_constraint_L (x
)
20980 : satisfies_constraint_J (x
))))
20981 || outer_code
== ASHIFT
20982 || outer_code
== ASHIFTRT
20983 || outer_code
== LSHIFTRT
20984 || outer_code
== ROTATE
20985 || outer_code
== ROTATERT
20986 || outer_code
== ZERO_EXTRACT
20987 || (outer_code
== MULT
20988 && satisfies_constraint_I (x
))
20989 || ((outer_code
== DIV
|| outer_code
== UDIV
20990 || outer_code
== MOD
|| outer_code
== UMOD
)
20991 && exact_log2 (INTVAL (x
)) >= 0)
20992 || (outer_code
== COMPARE
20993 && (satisfies_constraint_I (x
)
20994 || satisfies_constraint_K (x
)))
20995 || (outer_code
== EQ
20996 && (satisfies_constraint_I (x
)
20997 || satisfies_constraint_K (x
)
20999 ? satisfies_constraint_L (x
)
21000 : satisfies_constraint_J (x
))))
21001 || (outer_code
== GTU
21002 && satisfies_constraint_I (x
))
21003 || (outer_code
== LTU
21004 && satisfies_constraint_P (x
)))
21009 else if ((outer_code
== PLUS
21010 && reg_or_add_cint_operand (x
, VOIDmode
))
21011 || (outer_code
== MINUS
21012 && reg_or_sub_cint_operand (x
, VOIDmode
))
21013 || ((outer_code
== SET
21014 || outer_code
== IOR
21015 || outer_code
== XOR
)
21017 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
21019 *total
= COSTS_N_INSNS (1);
21025 if (mode
== DImode
&& code
== CONST_DOUBLE
)
21027 if ((outer_code
== IOR
|| outer_code
== XOR
)
21028 && CONST_DOUBLE_HIGH (x
) == 0
21029 && (CONST_DOUBLE_LOW (x
)
21030 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)
21035 else if ((outer_code
== AND
&& and64_2_operand (x
, DImode
))
21036 || ((outer_code
== SET
21037 || outer_code
== IOR
21038 || outer_code
== XOR
)
21039 && CONST_DOUBLE_HIGH (x
) == 0))
21041 *total
= COSTS_N_INSNS (1);
21051 /* When optimizing for size, MEM should be slightly more expensive
21052 than generating address, e.g., (plus (reg) (const)).
21053 L1 cache latency is about two instructions. */
21054 *total
= optimize_size
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
21062 if (mode
== DFmode
)
21064 if (GET_CODE (XEXP (x
, 0)) == MULT
)
21066 /* FNMA accounted in outer NEG. */
21067 if (outer_code
== NEG
)
21068 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
21070 *total
= rs6000_cost
->dmul
;
21073 *total
= rs6000_cost
->fp
;
21075 else if (mode
== SFmode
)
21077 /* FNMA accounted in outer NEG. */
21078 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
21081 *total
= rs6000_cost
->fp
;
21084 *total
= COSTS_N_INSNS (1);
21088 if (mode
== DFmode
)
21090 if (GET_CODE (XEXP (x
, 0)) == MULT
21091 || GET_CODE (XEXP (x
, 1)) == MULT
)
21093 /* FNMA accounted in outer NEG. */
21094 if (outer_code
== NEG
)
21095 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
21097 *total
= rs6000_cost
->dmul
;
21100 *total
= rs6000_cost
->fp
;
21102 else if (mode
== SFmode
)
21104 /* FNMA accounted in outer NEG. */
21105 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
21108 *total
= rs6000_cost
->fp
;
21111 *total
= COSTS_N_INSNS (1);
21115 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
21116 && satisfies_constraint_I (XEXP (x
, 1)))
21118 if (INTVAL (XEXP (x
, 1)) >= -256
21119 && INTVAL (XEXP (x
, 1)) <= 255)
21120 *total
= rs6000_cost
->mulsi_const9
;
21122 *total
= rs6000_cost
->mulsi_const
;
21124 /* FMA accounted in outer PLUS/MINUS. */
21125 else if ((mode
== DFmode
|| mode
== SFmode
)
21126 && (outer_code
== PLUS
|| outer_code
== MINUS
))
21128 else if (mode
== DFmode
)
21129 *total
= rs6000_cost
->dmul
;
21130 else if (mode
== SFmode
)
21131 *total
= rs6000_cost
->fp
;
21132 else if (mode
== DImode
)
21133 *total
= rs6000_cost
->muldi
;
21135 *total
= rs6000_cost
->mulsi
;
21140 if (FLOAT_MODE_P (mode
))
21142 *total
= mode
== DFmode
? rs6000_cost
->ddiv
21143 : rs6000_cost
->sdiv
;
21150 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
21151 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
21153 if (code
== DIV
|| code
== MOD
)
21155 *total
= COSTS_N_INSNS (2);
21158 *total
= COSTS_N_INSNS (1);
21162 if (GET_MODE (XEXP (x
, 1)) == DImode
)
21163 *total
= rs6000_cost
->divdi
;
21165 *total
= rs6000_cost
->divsi
;
21167 /* Add in shift and subtract for MOD. */
21168 if (code
== MOD
|| code
== UMOD
)
21169 *total
+= COSTS_N_INSNS (2);
21174 *total
= COSTS_N_INSNS (4);
21178 *total
= COSTS_N_INSNS (6);
21182 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
21194 *total
= COSTS_N_INSNS (1);
21202 /* Handle mul_highpart. */
21203 if (outer_code
== TRUNCATE
21204 && GET_CODE (XEXP (x
, 0)) == MULT
)
21206 if (mode
== DImode
)
21207 *total
= rs6000_cost
->muldi
;
21209 *total
= rs6000_cost
->mulsi
;
21212 else if (outer_code
== AND
)
21215 *total
= COSTS_N_INSNS (1);
21220 if (GET_CODE (XEXP (x
, 0)) == MEM
)
21223 *total
= COSTS_N_INSNS (1);
21229 if (!FLOAT_MODE_P (mode
))
21231 *total
= COSTS_N_INSNS (1);
21237 case UNSIGNED_FLOAT
:
21240 case FLOAT_TRUNCATE
:
21241 *total
= rs6000_cost
->fp
;
21245 if (mode
== DFmode
)
21248 *total
= rs6000_cost
->fp
;
21252 switch (XINT (x
, 1))
21255 *total
= rs6000_cost
->fp
;
21267 *total
= COSTS_N_INSNS (1);
21270 else if (FLOAT_MODE_P (mode
)
21271 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
21273 *total
= rs6000_cost
->fp
;
21281 /* Carry bit requires mode == Pmode.
21282 NEG or PLUS already counted so only add one. */
21284 && (outer_code
== NEG
|| outer_code
== PLUS
))
21286 *total
= COSTS_N_INSNS (1);
21289 if (outer_code
== SET
)
21291 if (XEXP (x
, 1) == const0_rtx
)
21293 *total
= COSTS_N_INSNS (2);
21296 else if (mode
== Pmode
)
21298 *total
= COSTS_N_INSNS (3);
21307 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
21309 *total
= COSTS_N_INSNS (2);
21313 if (outer_code
== COMPARE
)
21327 /* A C expression returning the cost of moving data from a register of class
21328 CLASS1 to one of CLASS2. */
21331 rs6000_register_move_cost (enum machine_mode mode
,
21332 enum reg_class from
, enum reg_class to
)
21334 /* Moves from/to GENERAL_REGS. */
21335 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
21336 || reg_classes_intersect_p (from
, GENERAL_REGS
))
21338 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
21341 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
)
21342 return (rs6000_memory_move_cost (mode
, from
, 0)
21343 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, 0));
21345 /* It's more expensive to move CR_REGS than CR0_REGS because of the
21347 else if (from
== CR_REGS
)
21350 /* Power6 has slower LR/CTR moves so make them more expensive than
21351 memory in order to bias spills to memory .*/
21352 else if (rs6000_cpu
== PROCESSOR_POWER6
21353 && reg_classes_intersect_p (from
, LINK_OR_CTR_REGS
))
21354 return 6 * hard_regno_nregs
[0][mode
];
21357 /* A move will cost one instruction per GPR moved. */
21358 return 2 * hard_regno_nregs
[0][mode
];
21361 /* Moving between two similar registers is just one instruction. */
21362 else if (reg_classes_intersect_p (to
, from
))
21363 return (mode
== TFmode
|| mode
== TDmode
) ? 4 : 2;
21365 /* Everything else has to go through GENERAL_REGS. */
21367 return (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
21368 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
21371 /* A C expressions returning the cost of moving data of MODE from a register to
21375 rs6000_memory_move_cost (enum machine_mode mode
, enum reg_class
class,
21376 int in ATTRIBUTE_UNUSED
)
21378 if (reg_classes_intersect_p (class, GENERAL_REGS
))
21379 return 4 * hard_regno_nregs
[0][mode
];
21380 else if (reg_classes_intersect_p (class, FLOAT_REGS
))
21381 return 4 * hard_regno_nregs
[32][mode
];
21382 else if (reg_classes_intersect_p (class, ALTIVEC_REGS
))
21383 return 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
21385 return 4 + rs6000_register_move_cost (mode
, class, GENERAL_REGS
);
21388 /* Returns a code for a target-specific builtin that implements
21389 reciprocal of the function, or NULL_TREE if not available. */
21392 rs6000_builtin_reciprocal (unsigned int fn
, bool md_fn
,
21393 bool sqrt ATTRIBUTE_UNUSED
)
21395 if (! (TARGET_RECIP
&& TARGET_PPC_GFXOPT
&& !optimize_size
21396 && flag_finite_math_only
&& !flag_trapping_math
21397 && flag_unsafe_math_optimizations
))
21405 case BUILT_IN_SQRTF
:
21406 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRTF
];
21413 /* Newton-Raphson approximation of single-precision floating point divide n/d.
21414 Assumes no trapping math and finite arguments. */
21417 rs6000_emit_swdivsf (rtx dst
, rtx n
, rtx d
)
21419 rtx x0
, e0
, e1
, y1
, u0
, v0
, one
;
21421 x0
= gen_reg_rtx (SFmode
);
21422 e0
= gen_reg_rtx (SFmode
);
21423 e1
= gen_reg_rtx (SFmode
);
21424 y1
= gen_reg_rtx (SFmode
);
21425 u0
= gen_reg_rtx (SFmode
);
21426 v0
= gen_reg_rtx (SFmode
);
21427 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
21429 /* x0 = 1./d estimate */
21430 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
21431 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, d
),
21433 /* e0 = 1. - d * x0 */
21434 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
21435 gen_rtx_MINUS (SFmode
, one
,
21436 gen_rtx_MULT (SFmode
, d
, x0
))));
21437 /* e1 = e0 + e0 * e0 */
21438 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
21439 gen_rtx_PLUS (SFmode
,
21440 gen_rtx_MULT (SFmode
, e0
, e0
), e0
)));
21441 /* y1 = x0 + e1 * x0 */
21442 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
21443 gen_rtx_PLUS (SFmode
,
21444 gen_rtx_MULT (SFmode
, e1
, x0
), x0
)));
21446 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
21447 gen_rtx_MULT (SFmode
, n
, y1
)));
21448 /* v0 = n - d * u0 */
21449 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
21450 gen_rtx_MINUS (SFmode
, n
,
21451 gen_rtx_MULT (SFmode
, d
, u0
))));
21452 /* dst = u0 + v0 * y1 */
21453 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
21454 gen_rtx_PLUS (SFmode
,
21455 gen_rtx_MULT (SFmode
, v0
, y1
), u0
)));
21458 /* Newton-Raphson approximation of double-precision floating point divide n/d.
21459 Assumes no trapping math and finite arguments. */
21462 rs6000_emit_swdivdf (rtx dst
, rtx n
, rtx d
)
21464 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
21466 x0
= gen_reg_rtx (DFmode
);
21467 e0
= gen_reg_rtx (DFmode
);
21468 e1
= gen_reg_rtx (DFmode
);
21469 e2
= gen_reg_rtx (DFmode
);
21470 y1
= gen_reg_rtx (DFmode
);
21471 y2
= gen_reg_rtx (DFmode
);
21472 y3
= gen_reg_rtx (DFmode
);
21473 u0
= gen_reg_rtx (DFmode
);
21474 v0
= gen_reg_rtx (DFmode
);
21475 one
= force_reg (DFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, DFmode
));
21477 /* x0 = 1./d estimate */
21478 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
21479 gen_rtx_UNSPEC (DFmode
, gen_rtvec (1, d
),
21481 /* e0 = 1. - d * x0 */
21482 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
21483 gen_rtx_MINUS (DFmode
, one
,
21484 gen_rtx_MULT (SFmode
, d
, x0
))));
21485 /* y1 = x0 + e0 * x0 */
21486 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
21487 gen_rtx_PLUS (DFmode
,
21488 gen_rtx_MULT (DFmode
, e0
, x0
), x0
)));
21490 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
21491 gen_rtx_MULT (DFmode
, e0
, e0
)));
21492 /* y2 = y1 + e1 * y1 */
21493 emit_insn (gen_rtx_SET (VOIDmode
, y2
,
21494 gen_rtx_PLUS (DFmode
,
21495 gen_rtx_MULT (DFmode
, e1
, y1
), y1
)));
21497 emit_insn (gen_rtx_SET (VOIDmode
, e2
,
21498 gen_rtx_MULT (DFmode
, e1
, e1
)));
21499 /* y3 = y2 + e2 * y2 */
21500 emit_insn (gen_rtx_SET (VOIDmode
, y3
,
21501 gen_rtx_PLUS (DFmode
,
21502 gen_rtx_MULT (DFmode
, e2
, y2
), y2
)));
21504 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
21505 gen_rtx_MULT (DFmode
, n
, y3
)));
21506 /* v0 = n - d * u0 */
21507 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
21508 gen_rtx_MINUS (DFmode
, n
,
21509 gen_rtx_MULT (DFmode
, d
, u0
))));
21510 /* dst = u0 + v0 * y3 */
21511 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
21512 gen_rtx_PLUS (DFmode
,
21513 gen_rtx_MULT (DFmode
, v0
, y3
), u0
)));
21517 /* Newton-Raphson approximation of single-precision floating point rsqrt.
21518 Assumes no trapping math and finite arguments. */
21521 rs6000_emit_swrsqrtsf (rtx dst
, rtx src
)
21523 rtx x0
, x1
, x2
, y1
, u0
, u1
, u2
, v0
, v1
, v2
, t0
,
21524 half
, one
, halfthree
, c1
, cond
, label
;
21526 x0
= gen_reg_rtx (SFmode
);
21527 x1
= gen_reg_rtx (SFmode
);
21528 x2
= gen_reg_rtx (SFmode
);
21529 y1
= gen_reg_rtx (SFmode
);
21530 u0
= gen_reg_rtx (SFmode
);
21531 u1
= gen_reg_rtx (SFmode
);
21532 u2
= gen_reg_rtx (SFmode
);
21533 v0
= gen_reg_rtx (SFmode
);
21534 v1
= gen_reg_rtx (SFmode
);
21535 v2
= gen_reg_rtx (SFmode
);
21536 t0
= gen_reg_rtx (SFmode
);
21537 halfthree
= gen_reg_rtx (SFmode
);
21538 cond
= gen_rtx_REG (CCFPmode
, CR1_REGNO
);
21539 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
21541 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
21542 emit_insn (gen_rtx_SET (VOIDmode
, t0
,
21543 gen_rtx_MULT (SFmode
, src
, src
)));
21545 emit_insn (gen_rtx_SET (VOIDmode
, cond
,
21546 gen_rtx_COMPARE (CCFPmode
, t0
, src
)));
21547 c1
= gen_rtx_EQ (VOIDmode
, cond
, const0_rtx
);
21548 emit_unlikely_jump (c1
, label
);
21550 half
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf
, SFmode
));
21551 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
21553 /* halfthree = 1.5 = 1.0 + 0.5 */
21554 emit_insn (gen_rtx_SET (VOIDmode
, halfthree
,
21555 gen_rtx_PLUS (SFmode
, one
, half
)));
21557 /* x0 = rsqrt estimate */
21558 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
21559 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, src
),
21562 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
21563 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
21564 gen_rtx_MINUS (SFmode
,
21565 gen_rtx_MULT (SFmode
, src
, halfthree
),
21568 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
21569 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
21570 gen_rtx_MULT (SFmode
, x0
, x0
)));
21571 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
21572 gen_rtx_MINUS (SFmode
,
21574 gen_rtx_MULT (SFmode
, y1
, u0
))));
21575 emit_insn (gen_rtx_SET (VOIDmode
, x1
,
21576 gen_rtx_MULT (SFmode
, x0
, v0
)));
21578 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
21579 emit_insn (gen_rtx_SET (VOIDmode
, u1
,
21580 gen_rtx_MULT (SFmode
, x1
, x1
)));
21581 emit_insn (gen_rtx_SET (VOIDmode
, v1
,
21582 gen_rtx_MINUS (SFmode
,
21584 gen_rtx_MULT (SFmode
, y1
, u1
))));
21585 emit_insn (gen_rtx_SET (VOIDmode
, x2
,
21586 gen_rtx_MULT (SFmode
, x1
, v1
)));
21588 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
21589 emit_insn (gen_rtx_SET (VOIDmode
, u2
,
21590 gen_rtx_MULT (SFmode
, x2
, x2
)));
21591 emit_insn (gen_rtx_SET (VOIDmode
, v2
,
21592 gen_rtx_MINUS (SFmode
,
21594 gen_rtx_MULT (SFmode
, y1
, u2
))));
21595 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
21596 gen_rtx_MULT (SFmode
, x2
, v2
)));
21598 emit_label (XEXP (label
, 0));
21601 /* Emit popcount intrinsic on TARGET_POPCNTB targets. DST is the
21602 target, and SRC is the argument operand. */
21605 rs6000_emit_popcount (rtx dst
, rtx src
)
21607 enum machine_mode mode
= GET_MODE (dst
);
21610 tmp1
= gen_reg_rtx (mode
);
21612 if (mode
== SImode
)
21614 emit_insn (gen_popcntbsi2 (tmp1
, src
));
21615 tmp2
= expand_mult (SImode
, tmp1
, GEN_INT (0x01010101),
21617 tmp2
= force_reg (SImode
, tmp2
);
21618 emit_insn (gen_lshrsi3 (dst
, tmp2
, GEN_INT (24)));
21622 emit_insn (gen_popcntbdi2 (tmp1
, src
));
21623 tmp2
= expand_mult (DImode
, tmp1
,
21624 GEN_INT ((HOST_WIDE_INT
)
21625 0x01010101 << 32 | 0x01010101),
21627 tmp2
= force_reg (DImode
, tmp2
);
21628 emit_insn (gen_lshrdi3 (dst
, tmp2
, GEN_INT (56)));
21633 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
21634 target, and SRC is the argument operand. */
21637 rs6000_emit_parity (rtx dst
, rtx src
)
21639 enum machine_mode mode
= GET_MODE (dst
);
21642 tmp
= gen_reg_rtx (mode
);
21643 if (mode
== SImode
)
21645 /* Is mult+shift >= shift+xor+shift+xor? */
21646 if (rs6000_cost
->mulsi_const
>= COSTS_N_INSNS (3))
21648 rtx tmp1
, tmp2
, tmp3
, tmp4
;
21650 tmp1
= gen_reg_rtx (SImode
);
21651 emit_insn (gen_popcntbsi2 (tmp1
, src
));
21653 tmp2
= gen_reg_rtx (SImode
);
21654 emit_insn (gen_lshrsi3 (tmp2
, tmp1
, GEN_INT (16)));
21655 tmp3
= gen_reg_rtx (SImode
);
21656 emit_insn (gen_xorsi3 (tmp3
, tmp1
, tmp2
));
21658 tmp4
= gen_reg_rtx (SImode
);
21659 emit_insn (gen_lshrsi3 (tmp4
, tmp3
, GEN_INT (8)));
21660 emit_insn (gen_xorsi3 (tmp
, tmp3
, tmp4
));
21663 rs6000_emit_popcount (tmp
, src
);
21664 emit_insn (gen_andsi3 (dst
, tmp
, const1_rtx
));
21668 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
21669 if (rs6000_cost
->muldi
>= COSTS_N_INSNS (5))
21671 rtx tmp1
, tmp2
, tmp3
, tmp4
, tmp5
, tmp6
;
21673 tmp1
= gen_reg_rtx (DImode
);
21674 emit_insn (gen_popcntbdi2 (tmp1
, src
));
21676 tmp2
= gen_reg_rtx (DImode
);
21677 emit_insn (gen_lshrdi3 (tmp2
, tmp1
, GEN_INT (32)));
21678 tmp3
= gen_reg_rtx (DImode
);
21679 emit_insn (gen_xordi3 (tmp3
, tmp1
, tmp2
));
21681 tmp4
= gen_reg_rtx (DImode
);
21682 emit_insn (gen_lshrdi3 (tmp4
, tmp3
, GEN_INT (16)));
21683 tmp5
= gen_reg_rtx (DImode
);
21684 emit_insn (gen_xordi3 (tmp5
, tmp3
, tmp4
));
21686 tmp6
= gen_reg_rtx (DImode
);
21687 emit_insn (gen_lshrdi3 (tmp6
, tmp5
, GEN_INT (8)));
21688 emit_insn (gen_xordi3 (tmp
, tmp5
, tmp6
));
21691 rs6000_emit_popcount (tmp
, src
);
21692 emit_insn (gen_anddi3 (dst
, tmp
, const1_rtx
));
21696 /* Return an RTX representing where to find the function value of a
21697 function returning MODE. */
21699 rs6000_complex_function_value (enum machine_mode mode
)
21701 unsigned int regno
;
21703 enum machine_mode inner
= GET_MODE_INNER (mode
);
21704 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
21706 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
21707 regno
= FP_ARG_RETURN
;
21710 regno
= GP_ARG_RETURN
;
21712 /* 32-bit is OK since it'll go in r3/r4. */
21713 if (TARGET_32BIT
&& inner_bytes
>= 4)
21714 return gen_rtx_REG (mode
, regno
);
21717 if (inner_bytes
>= 8)
21718 return gen_rtx_REG (mode
, regno
);
21720 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
21722 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
21723 GEN_INT (inner_bytes
));
21724 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
21727 /* Define how to find the value returned by a function.
21728 VALTYPE is the data type of the value (as a tree).
21729 If the precise function being called is known, FUNC is its FUNCTION_DECL;
21730 otherwise, FUNC is 0.
21732 On the SPE, both FPs and vectors are returned in r3.
21734 On RS/6000 an integer value is in r3 and a floating-point value is in
21735 fp1, unless -msoft-float. */
21738 rs6000_function_value (const_tree valtype
, const_tree func ATTRIBUTE_UNUSED
)
21740 enum machine_mode mode
;
21741 unsigned int regno
;
21743 /* Special handling for structs in darwin64. */
21744 if (rs6000_darwin64_abi
21745 && TYPE_MODE (valtype
) == BLKmode
21746 && TREE_CODE (valtype
) == RECORD_TYPE
21747 && int_size_in_bytes (valtype
) > 0)
21749 CUMULATIVE_ARGS valcum
;
21753 valcum
.fregno
= FP_ARG_MIN_REG
;
21754 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
21755 /* Do a trial code generation as if this were going to be passed as
21756 an argument; if any part goes in memory, we return NULL. */
21757 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, 1, true);
21760 /* Otherwise fall through to standard ABI rules. */
21763 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
21765 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
21766 return gen_rtx_PARALLEL (DImode
,
21768 gen_rtx_EXPR_LIST (VOIDmode
,
21769 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
21771 gen_rtx_EXPR_LIST (VOIDmode
,
21772 gen_rtx_REG (SImode
,
21773 GP_ARG_RETURN
+ 1),
21776 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
21778 return gen_rtx_PARALLEL (DCmode
,
21780 gen_rtx_EXPR_LIST (VOIDmode
,
21781 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
21783 gen_rtx_EXPR_LIST (VOIDmode
,
21784 gen_rtx_REG (SImode
,
21785 GP_ARG_RETURN
+ 1),
21787 gen_rtx_EXPR_LIST (VOIDmode
,
21788 gen_rtx_REG (SImode
,
21789 GP_ARG_RETURN
+ 2),
21791 gen_rtx_EXPR_LIST (VOIDmode
,
21792 gen_rtx_REG (SImode
,
21793 GP_ARG_RETURN
+ 3),
21797 mode
= TYPE_MODE (valtype
);
21798 if ((INTEGRAL_TYPE_P (valtype
) && GET_MODE_BITSIZE (mode
) < BITS_PER_WORD
)
21799 || POINTER_TYPE_P (valtype
))
21800 mode
= TARGET_32BIT
? SImode
: DImode
;
21802 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
21803 /* _Decimal128 must use an even/odd register pair. */
21804 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
21805 else if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
21806 regno
= FP_ARG_RETURN
;
21807 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
21808 && targetm
.calls
.split_complex_arg
)
21809 return rs6000_complex_function_value (mode
);
21810 else if (TREE_CODE (valtype
) == VECTOR_TYPE
21811 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
21812 && ALTIVEC_VECTOR_MODE (mode
))
21813 regno
= ALTIVEC_ARG_RETURN
;
21814 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
21815 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DCmode
21816 || mode
== TFmode
|| mode
== TDmode
|| mode
== TCmode
))
21817 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
21819 regno
= GP_ARG_RETURN
;
21821 return gen_rtx_REG (mode
, regno
);
21824 /* Define how to find the value returned by a library function
21825 assuming the value has mode MODE. */
21827 rs6000_libcall_value (enum machine_mode mode
)
21829 unsigned int regno
;
21831 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
21833 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
21834 return gen_rtx_PARALLEL (DImode
,
21836 gen_rtx_EXPR_LIST (VOIDmode
,
21837 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
21839 gen_rtx_EXPR_LIST (VOIDmode
,
21840 gen_rtx_REG (SImode
,
21841 GP_ARG_RETURN
+ 1),
21845 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
21846 /* _Decimal128 must use an even/odd register pair. */
21847 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
21848 else if (SCALAR_FLOAT_MODE_P (mode
)
21849 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
21850 regno
= FP_ARG_RETURN
;
21851 else if (ALTIVEC_VECTOR_MODE (mode
)
21852 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
21853 regno
= ALTIVEC_ARG_RETURN
;
21854 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
21855 return rs6000_complex_function_value (mode
);
21856 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
21857 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DCmode
21858 || mode
== TFmode
|| mode
== TDmode
|| mode
== TCmode
))
21859 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
21861 regno
= GP_ARG_RETURN
;
21863 return gen_rtx_REG (mode
, regno
);
21866 /* Define the offset between two registers, FROM to be eliminated and its
21867 replacement TO, at the start of a routine. */
21869 rs6000_initial_elimination_offset (int from
, int to
)
21871 rs6000_stack_t
*info
= rs6000_stack_info ();
21872 HOST_WIDE_INT offset
;
21874 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
21875 offset
= info
->push_p
? 0 : -info
->total_size
;
21876 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
21878 offset
= info
->push_p
? 0 : -info
->total_size
;
21879 if (FRAME_GROWS_DOWNWARD
)
21880 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
21882 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
21883 offset
= FRAME_GROWS_DOWNWARD
21884 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
21886 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
21887 offset
= info
->total_size
;
21888 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
21889 offset
= info
->push_p
? info
->total_size
: 0;
21890 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
21893 gcc_unreachable ();
21898 /* Return true if TYPE is a SPE or AltiVec opaque type. */
21901 rs6000_is_opaque_type (const_tree type
)
21903 return (type
== opaque_V2SI_type_node
21904 || type
== opaque_V2SF_type_node
21905 || type
== opaque_p_V2SI_type_node
21906 || type
== opaque_V4SI_type_node
);
21910 rs6000_dwarf_register_span (rtx reg
)
21915 && (SPE_VECTOR_MODE (GET_MODE (reg
))
21916 || (TARGET_E500_DOUBLE
21917 && (GET_MODE (reg
) == DFmode
|| GET_MODE (reg
) == DDmode
))))
21922 regno
= REGNO (reg
);
21924 /* The duality of the SPE register size wreaks all kinds of havoc.
21925 This is a way of distinguishing r0 in 32-bits from r0 in
21928 gen_rtx_PARALLEL (VOIDmode
,
21931 gen_rtx_REG (SImode
, regno
+ 1200),
21932 gen_rtx_REG (SImode
, regno
))
21934 gen_rtx_REG (SImode
, regno
),
21935 gen_rtx_REG (SImode
, regno
+ 1200)));
21938 /* Fill in sizes for SPE register high parts in table used by unwinder. */
21941 rs6000_init_dwarf_reg_sizes_extra (tree address
)
21946 enum machine_mode mode
= TYPE_MODE (char_type_node
);
21947 rtx addr
= expand_expr (address
, NULL_RTX
, VOIDmode
, 0);
21948 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
21949 rtx value
= gen_int_mode (4, mode
);
21951 for (i
= 1201; i
< 1232; i
++)
21953 int column
= DWARF_REG_TO_UNWIND_COLUMN (i
);
21954 HOST_WIDE_INT offset
21955 = DWARF_FRAME_REGNUM (column
) * GET_MODE_SIZE (mode
);
21957 emit_move_insn (adjust_address (mem
, mode
, offset
), value
);
21962 /* Map internal gcc register numbers to DWARF2 register numbers. */
21965 rs6000_dbx_register_number (unsigned int regno
)
21967 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
21969 if (regno
== MQ_REGNO
)
21971 if (regno
== LR_REGNO
)
21973 if (regno
== CTR_REGNO
)
21975 if (CR_REGNO_P (regno
))
21976 return regno
- CR0_REGNO
+ 86;
21977 if (regno
== XER_REGNO
)
21979 if (ALTIVEC_REGNO_P (regno
))
21980 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
21981 if (regno
== VRSAVE_REGNO
)
21983 if (regno
== VSCR_REGNO
)
21985 if (regno
== SPE_ACC_REGNO
)
21987 if (regno
== SPEFSCR_REGNO
)
21989 /* SPE high reg number. We get these values of regno from
21990 rs6000_dwarf_register_span. */
21991 gcc_assert (regno
>= 1200 && regno
< 1232);
21995 /* target hook eh_return_filter_mode */
21996 static enum machine_mode
21997 rs6000_eh_return_filter_mode (void)
21999 return TARGET_32BIT
? SImode
: word_mode
;
22002 /* Target hook for scalar_mode_supported_p. */
22004 rs6000_scalar_mode_supported_p (enum machine_mode mode
)
22006 if (DECIMAL_FLOAT_MODE_P (mode
))
22009 return default_scalar_mode_supported_p (mode
);
22012 /* Target hook for vector_mode_supported_p. */
22014 rs6000_vector_mode_supported_p (enum machine_mode mode
)
22017 if (TARGET_PAIRED_FLOAT
&& PAIRED_VECTOR_MODE (mode
))
22020 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
22023 else if (TARGET_ALTIVEC
&& ALTIVEC_VECTOR_MODE (mode
))
22030 /* Target hook for invalid_arg_for_unprototyped_fn. */
22031 static const char *
22032 invalid_arg_for_unprototyped_fn (const_tree typelist
, const_tree funcdecl
, const_tree val
)
22034 return (!rs6000_darwin64_abi
22036 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
22037 && (funcdecl
== NULL_TREE
22038 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
22039 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
22040 ? N_("AltiVec argument passed to unprototyped function")
22044 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
22045 setup by using __stack_chk_fail_local hidden function instead of
22046 calling __stack_chk_fail directly. Otherwise it is better to call
22047 __stack_chk_fail directly. */
22050 rs6000_stack_protect_fail (void)
22052 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
22053 ? default_hidden_stack_protect_fail ()
22054 : default_external_stack_protect_fail ();
22057 #include "gt-rs6000.h"