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 ABI extensions. */
180 /* Nonzero if floating point operations are done in the GPRs. */
181 int rs6000_float_gprs
= 0;
183 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
184 int rs6000_darwin64_abi
;
186 /* Set to nonzero once AIX common-mode calls have been defined. */
187 static GTY(()) int common_mode_defined
;
189 /* Save information from a "cmpxx" operation until the branch or scc is
191 rtx rs6000_compare_op0
, rs6000_compare_op1
;
192 int rs6000_compare_fp_p
;
194 /* Label number of label created for -mrelocatable, to call to so we can
195 get the address of the GOT section */
196 int rs6000_pic_labelno
;
199 /* Which abi to adhere to */
200 const char *rs6000_abi_name
;
202 /* Semantics of the small data area */
203 enum rs6000_sdata_type rs6000_sdata
= SDATA_DATA
;
205 /* Which small data model to use */
206 const char *rs6000_sdata_name
= (char *)0;
208 /* Counter for labels which are to be placed in .fixup. */
209 int fixuplabelno
= 0;
212 /* Bit size of immediate TLS offsets and string from which it is decoded. */
213 int rs6000_tls_size
= 32;
214 const char *rs6000_tls_size_string
;
216 /* ABI enumeration available for subtarget to use. */
217 enum rs6000_abi rs6000_current_abi
;
219 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
223 const char *rs6000_debug_name
;
224 int rs6000_debug_stack
; /* debug stack applications */
225 int rs6000_debug_arg
; /* debug argument handling */
227 /* Value is TRUE if register/mode pair is acceptable. */
228 bool rs6000_hard_regno_mode_ok_p
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
230 /* Built in types. */
232 tree rs6000_builtin_types
[RS6000_BTI_MAX
];
233 tree rs6000_builtin_decls
[RS6000_BUILTIN_COUNT
];
235 const char *rs6000_traceback_name
;
237 traceback_default
= 0,
243 /* Flag to say the TOC is initialized */
245 char toc_label_name
[10];
247 /* Cached value of rs6000_variable_issue. This is cached in
248 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
249 static short cached_can_issue_more
;
251 static GTY(()) section
*read_only_data_section
;
252 static GTY(()) section
*private_data_section
;
253 static GTY(()) section
*read_only_private_data_section
;
254 static GTY(()) section
*sdata2_section
;
255 static GTY(()) section
*toc_section
;
257 /* Control alignment for fields within structures. */
258 /* String from -malign-XXXXX. */
259 int rs6000_alignment_flags
;
261 /* True for any options that were explicitly set. */
263 bool aix_struct_ret
; /* True if -maix-struct-ret was used. */
264 bool alignment
; /* True if -malign- was used. */
265 bool spe_abi
; /* True if -mabi=spe/no-spe was used. */
266 bool altivec_abi
; /* True if -mabi=altivec/no-altivec used. */
267 bool spe
; /* True if -mspe= was used. */
268 bool float_gprs
; /* True if -mfloat-gprs= was used. */
269 bool isel
; /* True if -misel was used. */
270 bool long_double
; /* True if -mlong-double- was used. */
271 bool ieee
; /* True if -mabi=ieee/ibmlongdouble used. */
272 bool vrsave
; /* True if -mvrsave was used. */
273 } rs6000_explicit_options
;
275 struct builtin_description
277 /* mask is not const because we're going to alter it below. This
278 nonsense will go away when we rewrite the -march infrastructure
279 to give us more target flag bits. */
281 const enum insn_code icode
;
282 const char *const name
;
283 const enum rs6000_builtins code
;
286 /* Target cpu costs. */
288 struct processor_costs
{
289 const int mulsi
; /* cost of SImode multiplication. */
290 const int mulsi_const
; /* cost of SImode multiplication by constant. */
291 const int mulsi_const9
; /* cost of SImode mult by short constant. */
292 const int muldi
; /* cost of DImode multiplication. */
293 const int divsi
; /* cost of SImode division. */
294 const int divdi
; /* cost of DImode division. */
295 const int fp
; /* cost of simple SFmode and DFmode insns. */
296 const int dmul
; /* cost of DFmode multiplication (and fmadd). */
297 const int sdiv
; /* cost of SFmode division (fdivs). */
298 const int ddiv
; /* cost of DFmode division (fdiv). */
299 const int cache_line_size
; /* cache line size in bytes. */
300 const int l1_cache_size
; /* size of l1 cache, in kilobytes. */
301 const int l2_cache_size
; /* size of l2 cache, in kilobytes. */
302 const int simultaneous_prefetches
; /* number of parallel prefetch
306 const struct processor_costs
*rs6000_cost
;
308 /* Processor costs (relative to an add) */
310 /* Instruction size costs on 32bit processors. */
312 struct processor_costs size32_cost
= {
313 COSTS_N_INSNS (1), /* mulsi */
314 COSTS_N_INSNS (1), /* mulsi_const */
315 COSTS_N_INSNS (1), /* mulsi_const9 */
316 COSTS_N_INSNS (1), /* muldi */
317 COSTS_N_INSNS (1), /* divsi */
318 COSTS_N_INSNS (1), /* divdi */
319 COSTS_N_INSNS (1), /* fp */
320 COSTS_N_INSNS (1), /* dmul */
321 COSTS_N_INSNS (1), /* sdiv */
322 COSTS_N_INSNS (1), /* ddiv */
329 /* Instruction size costs on 64bit processors. */
331 struct processor_costs size64_cost
= {
332 COSTS_N_INSNS (1), /* mulsi */
333 COSTS_N_INSNS (1), /* mulsi_const */
334 COSTS_N_INSNS (1), /* mulsi_const9 */
335 COSTS_N_INSNS (1), /* muldi */
336 COSTS_N_INSNS (1), /* divsi */
337 COSTS_N_INSNS (1), /* divdi */
338 COSTS_N_INSNS (1), /* fp */
339 COSTS_N_INSNS (1), /* dmul */
340 COSTS_N_INSNS (1), /* sdiv */
341 COSTS_N_INSNS (1), /* ddiv */
348 /* Instruction costs on RIOS1 processors. */
350 struct processor_costs rios1_cost
= {
351 COSTS_N_INSNS (5), /* mulsi */
352 COSTS_N_INSNS (4), /* mulsi_const */
353 COSTS_N_INSNS (3), /* mulsi_const9 */
354 COSTS_N_INSNS (5), /* muldi */
355 COSTS_N_INSNS (19), /* divsi */
356 COSTS_N_INSNS (19), /* divdi */
357 COSTS_N_INSNS (2), /* fp */
358 COSTS_N_INSNS (2), /* dmul */
359 COSTS_N_INSNS (19), /* sdiv */
360 COSTS_N_INSNS (19), /* ddiv */
361 128, /* cache line size */
367 /* Instruction costs on RIOS2 processors. */
369 struct processor_costs rios2_cost
= {
370 COSTS_N_INSNS (2), /* mulsi */
371 COSTS_N_INSNS (2), /* mulsi_const */
372 COSTS_N_INSNS (2), /* mulsi_const9 */
373 COSTS_N_INSNS (2), /* muldi */
374 COSTS_N_INSNS (13), /* divsi */
375 COSTS_N_INSNS (13), /* divdi */
376 COSTS_N_INSNS (2), /* fp */
377 COSTS_N_INSNS (2), /* dmul */
378 COSTS_N_INSNS (17), /* sdiv */
379 COSTS_N_INSNS (17), /* ddiv */
380 256, /* cache line size */
386 /* Instruction costs on RS64A processors. */
388 struct processor_costs rs64a_cost
= {
389 COSTS_N_INSNS (20), /* mulsi */
390 COSTS_N_INSNS (12), /* mulsi_const */
391 COSTS_N_INSNS (8), /* mulsi_const9 */
392 COSTS_N_INSNS (34), /* muldi */
393 COSTS_N_INSNS (65), /* divsi */
394 COSTS_N_INSNS (67), /* divdi */
395 COSTS_N_INSNS (4), /* fp */
396 COSTS_N_INSNS (4), /* dmul */
397 COSTS_N_INSNS (31), /* sdiv */
398 COSTS_N_INSNS (31), /* ddiv */
399 128, /* cache line size */
405 /* Instruction costs on MPCCORE processors. */
407 struct processor_costs mpccore_cost
= {
408 COSTS_N_INSNS (2), /* mulsi */
409 COSTS_N_INSNS (2), /* mulsi_const */
410 COSTS_N_INSNS (2), /* mulsi_const9 */
411 COSTS_N_INSNS (2), /* muldi */
412 COSTS_N_INSNS (6), /* divsi */
413 COSTS_N_INSNS (6), /* divdi */
414 COSTS_N_INSNS (4), /* fp */
415 COSTS_N_INSNS (5), /* dmul */
416 COSTS_N_INSNS (10), /* sdiv */
417 COSTS_N_INSNS (17), /* ddiv */
418 32, /* cache line size */
424 /* Instruction costs on PPC403 processors. */
426 struct processor_costs ppc403_cost
= {
427 COSTS_N_INSNS (4), /* mulsi */
428 COSTS_N_INSNS (4), /* mulsi_const */
429 COSTS_N_INSNS (4), /* mulsi_const9 */
430 COSTS_N_INSNS (4), /* muldi */
431 COSTS_N_INSNS (33), /* divsi */
432 COSTS_N_INSNS (33), /* divdi */
433 COSTS_N_INSNS (11), /* fp */
434 COSTS_N_INSNS (11), /* dmul */
435 COSTS_N_INSNS (11), /* sdiv */
436 COSTS_N_INSNS (11), /* ddiv */
437 32, /* cache line size */
443 /* Instruction costs on PPC405 processors. */
445 struct processor_costs ppc405_cost
= {
446 COSTS_N_INSNS (5), /* mulsi */
447 COSTS_N_INSNS (4), /* mulsi_const */
448 COSTS_N_INSNS (3), /* mulsi_const9 */
449 COSTS_N_INSNS (5), /* muldi */
450 COSTS_N_INSNS (35), /* divsi */
451 COSTS_N_INSNS (35), /* divdi */
452 COSTS_N_INSNS (11), /* fp */
453 COSTS_N_INSNS (11), /* dmul */
454 COSTS_N_INSNS (11), /* sdiv */
455 COSTS_N_INSNS (11), /* ddiv */
456 32, /* cache line size */
462 /* Instruction costs on PPC440 processors. */
464 struct processor_costs ppc440_cost
= {
465 COSTS_N_INSNS (3), /* mulsi */
466 COSTS_N_INSNS (2), /* mulsi_const */
467 COSTS_N_INSNS (2), /* mulsi_const9 */
468 COSTS_N_INSNS (3), /* muldi */
469 COSTS_N_INSNS (34), /* divsi */
470 COSTS_N_INSNS (34), /* divdi */
471 COSTS_N_INSNS (5), /* fp */
472 COSTS_N_INSNS (5), /* dmul */
473 COSTS_N_INSNS (19), /* sdiv */
474 COSTS_N_INSNS (33), /* ddiv */
475 32, /* cache line size */
481 /* Instruction costs on PPC601 processors. */
483 struct processor_costs ppc601_cost
= {
484 COSTS_N_INSNS (5), /* mulsi */
485 COSTS_N_INSNS (5), /* mulsi_const */
486 COSTS_N_INSNS (5), /* mulsi_const9 */
487 COSTS_N_INSNS (5), /* muldi */
488 COSTS_N_INSNS (36), /* divsi */
489 COSTS_N_INSNS (36), /* divdi */
490 COSTS_N_INSNS (4), /* fp */
491 COSTS_N_INSNS (5), /* dmul */
492 COSTS_N_INSNS (17), /* sdiv */
493 COSTS_N_INSNS (31), /* ddiv */
494 32, /* cache line size */
500 /* Instruction costs on PPC603 processors. */
502 struct processor_costs ppc603_cost
= {
503 COSTS_N_INSNS (5), /* mulsi */
504 COSTS_N_INSNS (3), /* mulsi_const */
505 COSTS_N_INSNS (2), /* mulsi_const9 */
506 COSTS_N_INSNS (5), /* muldi */
507 COSTS_N_INSNS (37), /* divsi */
508 COSTS_N_INSNS (37), /* divdi */
509 COSTS_N_INSNS (3), /* fp */
510 COSTS_N_INSNS (4), /* dmul */
511 COSTS_N_INSNS (18), /* sdiv */
512 COSTS_N_INSNS (33), /* ddiv */
513 32, /* cache line size */
519 /* Instruction costs on PPC604 processors. */
521 struct processor_costs ppc604_cost
= {
522 COSTS_N_INSNS (4), /* mulsi */
523 COSTS_N_INSNS (4), /* mulsi_const */
524 COSTS_N_INSNS (4), /* mulsi_const9 */
525 COSTS_N_INSNS (4), /* muldi */
526 COSTS_N_INSNS (20), /* divsi */
527 COSTS_N_INSNS (20), /* divdi */
528 COSTS_N_INSNS (3), /* fp */
529 COSTS_N_INSNS (3), /* dmul */
530 COSTS_N_INSNS (18), /* sdiv */
531 COSTS_N_INSNS (32), /* ddiv */
532 32, /* cache line size */
538 /* Instruction costs on PPC604e processors. */
540 struct processor_costs ppc604e_cost
= {
541 COSTS_N_INSNS (2), /* mulsi */
542 COSTS_N_INSNS (2), /* mulsi_const */
543 COSTS_N_INSNS (2), /* mulsi_const9 */
544 COSTS_N_INSNS (2), /* muldi */
545 COSTS_N_INSNS (20), /* divsi */
546 COSTS_N_INSNS (20), /* divdi */
547 COSTS_N_INSNS (3), /* fp */
548 COSTS_N_INSNS (3), /* dmul */
549 COSTS_N_INSNS (18), /* sdiv */
550 COSTS_N_INSNS (32), /* ddiv */
551 32, /* cache line size */
557 /* Instruction costs on PPC620 processors. */
559 struct processor_costs ppc620_cost
= {
560 COSTS_N_INSNS (5), /* mulsi */
561 COSTS_N_INSNS (4), /* mulsi_const */
562 COSTS_N_INSNS (3), /* mulsi_const9 */
563 COSTS_N_INSNS (7), /* muldi */
564 COSTS_N_INSNS (21), /* divsi */
565 COSTS_N_INSNS (37), /* divdi */
566 COSTS_N_INSNS (3), /* fp */
567 COSTS_N_INSNS (3), /* dmul */
568 COSTS_N_INSNS (18), /* sdiv */
569 COSTS_N_INSNS (32), /* ddiv */
570 128, /* cache line size */
576 /* Instruction costs on PPC630 processors. */
578 struct processor_costs ppc630_cost
= {
579 COSTS_N_INSNS (5), /* mulsi */
580 COSTS_N_INSNS (4), /* mulsi_const */
581 COSTS_N_INSNS (3), /* mulsi_const9 */
582 COSTS_N_INSNS (7), /* muldi */
583 COSTS_N_INSNS (21), /* divsi */
584 COSTS_N_INSNS (37), /* divdi */
585 COSTS_N_INSNS (3), /* fp */
586 COSTS_N_INSNS (3), /* dmul */
587 COSTS_N_INSNS (17), /* sdiv */
588 COSTS_N_INSNS (21), /* ddiv */
589 128, /* cache line size */
595 /* Instruction costs on Cell processor. */
596 /* COSTS_N_INSNS (1) ~ one add. */
598 struct processor_costs ppccell_cost
= {
599 COSTS_N_INSNS (9/2)+2, /* mulsi */
600 COSTS_N_INSNS (6/2), /* mulsi_const */
601 COSTS_N_INSNS (6/2), /* mulsi_const9 */
602 COSTS_N_INSNS (15/2)+2, /* muldi */
603 COSTS_N_INSNS (38/2), /* divsi */
604 COSTS_N_INSNS (70/2), /* divdi */
605 COSTS_N_INSNS (10/2), /* fp */
606 COSTS_N_INSNS (10/2), /* dmul */
607 COSTS_N_INSNS (74/2), /* sdiv */
608 COSTS_N_INSNS (74/2), /* ddiv */
609 128, /* cache line size */
615 /* Instruction costs on PPC750 and PPC7400 processors. */
617 struct processor_costs ppc750_cost
= {
618 COSTS_N_INSNS (5), /* mulsi */
619 COSTS_N_INSNS (3), /* mulsi_const */
620 COSTS_N_INSNS (2), /* mulsi_const9 */
621 COSTS_N_INSNS (5), /* muldi */
622 COSTS_N_INSNS (17), /* divsi */
623 COSTS_N_INSNS (17), /* divdi */
624 COSTS_N_INSNS (3), /* fp */
625 COSTS_N_INSNS (3), /* dmul */
626 COSTS_N_INSNS (17), /* sdiv */
627 COSTS_N_INSNS (31), /* ddiv */
628 32, /* cache line size */
634 /* Instruction costs on PPC7450 processors. */
636 struct processor_costs ppc7450_cost
= {
637 COSTS_N_INSNS (4), /* mulsi */
638 COSTS_N_INSNS (3), /* mulsi_const */
639 COSTS_N_INSNS (3), /* mulsi_const9 */
640 COSTS_N_INSNS (4), /* muldi */
641 COSTS_N_INSNS (23), /* divsi */
642 COSTS_N_INSNS (23), /* divdi */
643 COSTS_N_INSNS (5), /* fp */
644 COSTS_N_INSNS (5), /* dmul */
645 COSTS_N_INSNS (21), /* sdiv */
646 COSTS_N_INSNS (35), /* ddiv */
647 32, /* cache line size */
653 /* Instruction costs on PPC8540 processors. */
655 struct processor_costs ppc8540_cost
= {
656 COSTS_N_INSNS (4), /* mulsi */
657 COSTS_N_INSNS (4), /* mulsi_const */
658 COSTS_N_INSNS (4), /* mulsi_const9 */
659 COSTS_N_INSNS (4), /* muldi */
660 COSTS_N_INSNS (19), /* divsi */
661 COSTS_N_INSNS (19), /* divdi */
662 COSTS_N_INSNS (4), /* fp */
663 COSTS_N_INSNS (4), /* dmul */
664 COSTS_N_INSNS (29), /* sdiv */
665 COSTS_N_INSNS (29), /* ddiv */
666 32, /* cache line size */
669 1, /* prefetch streams /*/
672 /* Instruction costs on E300C2 and E300C3 cores. */
674 struct processor_costs ppce300c2c3_cost
= {
675 COSTS_N_INSNS (4), /* mulsi */
676 COSTS_N_INSNS (4), /* mulsi_const */
677 COSTS_N_INSNS (4), /* mulsi_const9 */
678 COSTS_N_INSNS (4), /* muldi */
679 COSTS_N_INSNS (19), /* divsi */
680 COSTS_N_INSNS (19), /* divdi */
681 COSTS_N_INSNS (3), /* fp */
682 COSTS_N_INSNS (4), /* dmul */
683 COSTS_N_INSNS (18), /* sdiv */
684 COSTS_N_INSNS (33), /* ddiv */
688 1, /* prefetch streams /*/
691 /* Instruction costs on POWER4 and POWER5 processors. */
693 struct processor_costs power4_cost
= {
694 COSTS_N_INSNS (3), /* mulsi */
695 COSTS_N_INSNS (2), /* mulsi_const */
696 COSTS_N_INSNS (2), /* mulsi_const9 */
697 COSTS_N_INSNS (4), /* muldi */
698 COSTS_N_INSNS (18), /* divsi */
699 COSTS_N_INSNS (34), /* divdi */
700 COSTS_N_INSNS (3), /* fp */
701 COSTS_N_INSNS (3), /* dmul */
702 COSTS_N_INSNS (17), /* sdiv */
703 COSTS_N_INSNS (17), /* ddiv */
704 128, /* cache line size */
707 8, /* prefetch streams /*/
710 /* Instruction costs on POWER6 processors. */
712 struct processor_costs power6_cost
= {
713 COSTS_N_INSNS (8), /* mulsi */
714 COSTS_N_INSNS (8), /* mulsi_const */
715 COSTS_N_INSNS (8), /* mulsi_const9 */
716 COSTS_N_INSNS (8), /* muldi */
717 COSTS_N_INSNS (22), /* divsi */
718 COSTS_N_INSNS (28), /* divdi */
719 COSTS_N_INSNS (3), /* fp */
720 COSTS_N_INSNS (3), /* dmul */
721 COSTS_N_INSNS (13), /* sdiv */
722 COSTS_N_INSNS (16), /* ddiv */
723 128, /* cache line size */
726 16, /* prefetch streams */
730 static bool rs6000_function_ok_for_sibcall (tree
, tree
);
731 static const char *rs6000_invalid_within_doloop (const_rtx
);
732 static rtx
rs6000_generate_compare (enum rtx_code
);
733 static void rs6000_emit_stack_tie (void);
734 static void rs6000_frame_related (rtx
, rtx
, HOST_WIDE_INT
, rtx
, rtx
);
735 static bool spe_func_has_64bit_regs_p (void);
736 static void emit_frame_save (rtx
, rtx
, enum machine_mode
, unsigned int,
738 static rtx
gen_frame_mem_offset (enum machine_mode
, rtx
, int);
739 static void rs6000_emit_allocate_stack (HOST_WIDE_INT
, int);
740 static unsigned rs6000_hash_constant (rtx
);
741 static unsigned toc_hash_function (const void *);
742 static int toc_hash_eq (const void *, const void *);
743 static int constant_pool_expr_1 (rtx
, int *, int *);
744 static bool constant_pool_expr_p (rtx
);
745 static bool legitimate_small_data_p (enum machine_mode
, rtx
);
746 static bool legitimate_lo_sum_address_p (enum machine_mode
, rtx
, int);
747 static struct machine_function
* rs6000_init_machine_status (void);
748 static bool rs6000_assemble_integer (rtx
, unsigned int, int);
749 static bool no_global_regs_above (int);
750 #ifdef HAVE_GAS_HIDDEN
751 static void rs6000_assemble_visibility (tree
, int);
753 static int rs6000_ra_ever_killed (void);
754 static tree
rs6000_handle_longcall_attribute (tree
*, tree
, tree
, int, bool *);
755 static tree
rs6000_handle_altivec_attribute (tree
*, tree
, tree
, int, bool *);
756 static bool rs6000_ms_bitfield_layout_p (const_tree
);
757 static tree
rs6000_handle_struct_attribute (tree
*, tree
, tree
, int, bool *);
758 static void rs6000_eliminate_indexed_memrefs (rtx operands
[2]);
759 static const char *rs6000_mangle_type (const_tree
);
760 extern const struct attribute_spec rs6000_attribute_table
[];
761 static void rs6000_set_default_type_attributes (tree
);
762 static bool rs6000_reg_live_or_pic_offset_p (int);
763 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT
);
764 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT
);
765 static void rs6000_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
767 static rtx
rs6000_emit_set_long_const (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
768 static bool rs6000_return_in_memory (const_tree
, const_tree
);
769 static void rs6000_file_start (void);
771 static int rs6000_elf_reloc_rw_mask (void);
772 static void rs6000_elf_asm_out_constructor (rtx
, int);
773 static void rs6000_elf_asm_out_destructor (rtx
, int);
774 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED
;
775 static void rs6000_elf_asm_init_sections (void);
776 static section
*rs6000_elf_select_rtx_section (enum machine_mode
, rtx
,
777 unsigned HOST_WIDE_INT
);
778 static void rs6000_elf_encode_section_info (tree
, rtx
, int)
781 static bool rs6000_use_blocks_for_constant_p (enum machine_mode
, const_rtx
);
782 static void rs6000_alloc_sdmode_stack_slot (void);
783 static void rs6000_instantiate_decls (void);
785 static void rs6000_xcoff_asm_output_anchor (rtx
);
786 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
787 static void rs6000_xcoff_asm_init_sections (void);
788 static int rs6000_xcoff_reloc_rw_mask (void);
789 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree
);
790 static section
*rs6000_xcoff_select_section (tree
, int,
791 unsigned HOST_WIDE_INT
);
792 static void rs6000_xcoff_unique_section (tree
, int);
793 static section
*rs6000_xcoff_select_rtx_section
794 (enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
);
795 static const char * rs6000_xcoff_strip_name_encoding (const char *);
796 static unsigned int rs6000_xcoff_section_type_flags (tree
, const char *, int);
797 static void rs6000_xcoff_file_start (void);
798 static void rs6000_xcoff_file_end (void);
800 static int rs6000_variable_issue (FILE *, int, rtx
, int);
801 static bool rs6000_rtx_costs (rtx
, int, int, int *);
802 static int rs6000_adjust_cost (rtx
, rtx
, rtx
, int);
803 static void rs6000_sched_init (FILE *, int, int);
804 static bool is_microcoded_insn (rtx
);
805 static bool is_nonpipeline_insn (rtx
);
806 static bool is_cracked_insn (rtx
);
807 static bool is_branch_slot_insn (rtx
);
808 static bool is_load_insn (rtx
);
809 static rtx
get_store_dest (rtx pat
);
810 static bool is_store_insn (rtx
);
811 static bool set_to_load_agen (rtx
,rtx
);
812 static bool adjacent_mem_locations (rtx
,rtx
);
813 static int rs6000_adjust_priority (rtx
, int);
814 static int rs6000_issue_rate (void);
815 static bool rs6000_is_costly_dependence (dep_t
, int, int);
816 static rtx
get_next_active_insn (rtx
, rtx
);
817 static bool insn_terminates_group_p (rtx
, enum group_termination
);
818 static bool insn_must_be_first_in_group (rtx
);
819 static bool insn_must_be_last_in_group (rtx
);
820 static bool is_costly_group (rtx
*, rtx
);
821 static int force_new_group (int, FILE *, rtx
*, rtx
, bool *, int, int *);
822 static int redefine_groups (FILE *, int, rtx
, rtx
);
823 static int pad_groups (FILE *, int, rtx
, rtx
);
824 static void rs6000_sched_finish (FILE *, int);
825 static int rs6000_sched_reorder (FILE *, int, rtx
*, int *, int);
826 static int rs6000_sched_reorder2 (FILE *, int, rtx
*, int *, int);
827 static int rs6000_use_sched_lookahead (void);
828 static int rs6000_use_sched_lookahead_guard (rtx
);
829 static tree
rs6000_builtin_reciprocal (unsigned int, bool, bool);
830 static tree
rs6000_builtin_mask_for_load (void);
831 static tree
rs6000_builtin_mul_widen_even (tree
);
832 static tree
rs6000_builtin_mul_widen_odd (tree
);
833 static tree
rs6000_builtin_conversion (enum tree_code
, tree
);
835 static void def_builtin (int, const char *, tree
, int);
836 static bool rs6000_vector_alignment_reachable (const_tree
, bool);
837 static void rs6000_init_builtins (void);
838 static rtx
rs6000_expand_unop_builtin (enum insn_code
, tree
, rtx
);
839 static rtx
rs6000_expand_binop_builtin (enum insn_code
, tree
, rtx
);
840 static rtx
rs6000_expand_ternop_builtin (enum insn_code
, tree
, rtx
);
841 static rtx
rs6000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
842 static void altivec_init_builtins (void);
843 static void rs6000_common_init_builtins (void);
844 static void rs6000_init_libfuncs (void);
846 static void paired_init_builtins (void);
847 static rtx
paired_expand_builtin (tree
, rtx
, bool *);
848 static rtx
paired_expand_lv_builtin (enum insn_code
, tree
, rtx
);
849 static rtx
paired_expand_stv_builtin (enum insn_code
, tree
);
850 static rtx
paired_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
852 static void enable_mask_for_builtins (struct builtin_description
*, int,
853 enum rs6000_builtins
,
854 enum rs6000_builtins
);
855 static tree
build_opaque_vector_type (tree
, int);
856 static void spe_init_builtins (void);
857 static rtx
spe_expand_builtin (tree
, rtx
, bool *);
858 static rtx
spe_expand_stv_builtin (enum insn_code
, tree
);
859 static rtx
spe_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
860 static rtx
spe_expand_evsel_builtin (enum insn_code
, tree
, rtx
);
861 static int rs6000_emit_int_cmove (rtx
, rtx
, rtx
, rtx
);
862 static rs6000_stack_t
*rs6000_stack_info (void);
863 static void debug_stack_info (rs6000_stack_t
*);
865 static rtx
altivec_expand_builtin (tree
, rtx
, bool *);
866 static rtx
altivec_expand_ld_builtin (tree
, rtx
, bool *);
867 static rtx
altivec_expand_st_builtin (tree
, rtx
, bool *);
868 static rtx
altivec_expand_dst_builtin (tree
, rtx
, bool *);
869 static rtx
altivec_expand_abs_builtin (enum insn_code
, tree
, rtx
);
870 static rtx
altivec_expand_predicate_builtin (enum insn_code
,
871 const char *, tree
, rtx
);
872 static rtx
altivec_expand_lv_builtin (enum insn_code
, tree
, rtx
);
873 static rtx
altivec_expand_stv_builtin (enum insn_code
, tree
);
874 static rtx
altivec_expand_vec_init_builtin (tree
, tree
, rtx
);
875 static rtx
altivec_expand_vec_set_builtin (tree
);
876 static rtx
altivec_expand_vec_ext_builtin (tree
, rtx
);
877 static int get_element_number (tree
, tree
);
878 static bool rs6000_handle_option (size_t, const char *, int);
879 static void rs6000_parse_tls_size_option (void);
880 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
881 static int first_altivec_reg_to_save (void);
882 static unsigned int compute_vrsave_mask (void);
883 static void compute_save_world_info (rs6000_stack_t
*info_ptr
);
884 static void is_altivec_return_reg (rtx
, void *);
885 static rtx
generate_set_vrsave (rtx
, rs6000_stack_t
*, int);
886 int easy_vector_constant (rtx
, enum machine_mode
);
887 static bool rs6000_is_opaque_type (const_tree
);
888 static rtx
rs6000_dwarf_register_span (rtx
);
889 static void rs6000_init_dwarf_reg_sizes_extra (tree
);
890 static rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
891 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
892 static rtx
rs6000_tls_get_addr (void);
893 static rtx
rs6000_got_sym (void);
894 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
895 static const char *rs6000_get_some_local_dynamic_name (void);
896 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
897 static rtx
rs6000_complex_function_value (enum machine_mode
);
898 static rtx
rs6000_spe_function_arg (CUMULATIVE_ARGS
*,
899 enum machine_mode
, tree
);
900 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
902 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
903 tree
, HOST_WIDE_INT
);
904 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
907 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
908 const_tree
, HOST_WIDE_INT
,
910 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, const_tree
, int, bool);
911 static rtx
rs6000_mixed_function_arg (enum machine_mode
, tree
, int);
912 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
913 static void setup_incoming_varargs (CUMULATIVE_ARGS
*,
914 enum machine_mode
, tree
,
916 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
918 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
920 static const char *invalid_arg_for_unprototyped_fn (const_tree
, const_tree
, const_tree
);
922 static void macho_branch_islands (void);
923 static int no_previous_def (tree function_name
);
924 static tree
get_prev_label (tree function_name
);
925 static void rs6000_darwin_file_start (void);
928 static tree
rs6000_build_builtin_va_list (void);
929 static void rs6000_va_start (tree
, rtx
);
930 static tree
rs6000_gimplify_va_arg (tree
, tree
, tree
*, tree
*);
931 static bool rs6000_must_pass_in_stack (enum machine_mode
, const_tree
);
932 static bool rs6000_scalar_mode_supported_p (enum machine_mode
);
933 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
934 static int get_vec_cmp_insn (enum rtx_code
, enum machine_mode
,
936 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
938 static int get_vsel_insn (enum machine_mode
);
939 static void rs6000_emit_vector_select (rtx
, rtx
, rtx
, rtx
);
940 static tree
rs6000_stack_protect_fail (void);
942 const int INSN_NOT_AVAILABLE
= -1;
943 static enum machine_mode
rs6000_eh_return_filter_mode (void);
945 /* Hash table stuff for keeping track of TOC entries. */
947 struct toc_hash_struct
GTY(())
949 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
950 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
952 enum machine_mode key_mode
;
956 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
958 /* Default register names. */
959 char rs6000_reg_names
[][8] =
961 "0", "1", "2", "3", "4", "5", "6", "7",
962 "8", "9", "10", "11", "12", "13", "14", "15",
963 "16", "17", "18", "19", "20", "21", "22", "23",
964 "24", "25", "26", "27", "28", "29", "30", "31",
965 "0", "1", "2", "3", "4", "5", "6", "7",
966 "8", "9", "10", "11", "12", "13", "14", "15",
967 "16", "17", "18", "19", "20", "21", "22", "23",
968 "24", "25", "26", "27", "28", "29", "30", "31",
969 "mq", "lr", "ctr","ap",
970 "0", "1", "2", "3", "4", "5", "6", "7",
972 /* AltiVec registers. */
973 "0", "1", "2", "3", "4", "5", "6", "7",
974 "8", "9", "10", "11", "12", "13", "14", "15",
975 "16", "17", "18", "19", "20", "21", "22", "23",
976 "24", "25", "26", "27", "28", "29", "30", "31",
979 "spe_acc", "spefscr",
980 /* Soft frame pointer. */
984 #ifdef TARGET_REGNAMES
985 static const char alt_reg_names
[][8] =
987 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
988 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
989 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
990 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
991 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
992 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
993 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
994 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
995 "mq", "lr", "ctr", "ap",
996 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
998 /* AltiVec registers. */
999 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1000 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1001 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1002 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1004 /* SPE registers. */
1005 "spe_acc", "spefscr",
1006 /* Soft frame pointer. */
1011 #ifndef MASK_STRICT_ALIGN
1012 #define MASK_STRICT_ALIGN 0
1014 #ifndef TARGET_PROFILE_KERNEL
1015 #define TARGET_PROFILE_KERNEL 0
1018 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1019 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1021 /* Initialize the GCC target structure. */
1022 #undef TARGET_ATTRIBUTE_TABLE
1023 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1024 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1025 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1027 #undef TARGET_ASM_ALIGNED_DI_OP
1028 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1030 /* Default unaligned ops are only provided for ELF. Find the ops needed
1031 for non-ELF systems. */
1032 #ifndef OBJECT_FORMAT_ELF
1034 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1036 #undef TARGET_ASM_UNALIGNED_HI_OP
1037 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1038 #undef TARGET_ASM_UNALIGNED_SI_OP
1039 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1040 #undef TARGET_ASM_UNALIGNED_DI_OP
1041 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1044 #undef TARGET_ASM_UNALIGNED_HI_OP
1045 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1046 #undef TARGET_ASM_UNALIGNED_SI_OP
1047 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1048 #undef TARGET_ASM_UNALIGNED_DI_OP
1049 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1050 #undef TARGET_ASM_ALIGNED_DI_OP
1051 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1055 /* This hook deals with fixups for relocatable code and DI-mode objects
1057 #undef TARGET_ASM_INTEGER
1058 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1060 #ifdef HAVE_GAS_HIDDEN
1061 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1062 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1065 #undef TARGET_HAVE_TLS
1066 #define TARGET_HAVE_TLS HAVE_AS_TLS
1068 #undef TARGET_CANNOT_FORCE_CONST_MEM
1069 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1071 #undef TARGET_ASM_FUNCTION_PROLOGUE
1072 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1073 #undef TARGET_ASM_FUNCTION_EPILOGUE
1074 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1076 #undef TARGET_SCHED_VARIABLE_ISSUE
1077 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1079 #undef TARGET_SCHED_ISSUE_RATE
1080 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1081 #undef TARGET_SCHED_ADJUST_COST
1082 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1083 #undef TARGET_SCHED_ADJUST_PRIORITY
1084 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1085 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1086 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1087 #undef TARGET_SCHED_INIT
1088 #define TARGET_SCHED_INIT rs6000_sched_init
1089 #undef TARGET_SCHED_FINISH
1090 #define TARGET_SCHED_FINISH rs6000_sched_finish
1091 #undef TARGET_SCHED_REORDER
1092 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1093 #undef TARGET_SCHED_REORDER2
1094 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1096 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1097 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1099 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1100 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1102 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1103 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1104 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1105 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1106 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1107 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1108 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1109 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1111 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1112 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1114 #undef TARGET_INIT_BUILTINS
1115 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1117 #undef TARGET_EXPAND_BUILTIN
1118 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1120 #undef TARGET_MANGLE_TYPE
1121 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1123 #undef TARGET_INIT_LIBFUNCS
1124 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1127 #undef TARGET_BINDS_LOCAL_P
1128 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1131 #undef TARGET_MS_BITFIELD_LAYOUT_P
1132 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1134 #undef TARGET_ASM_OUTPUT_MI_THUNK
1135 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1137 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1138 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1140 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1141 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1143 #undef TARGET_INVALID_WITHIN_DOLOOP
1144 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1146 #undef TARGET_RTX_COSTS
1147 #define TARGET_RTX_COSTS rs6000_rtx_costs
1148 #undef TARGET_ADDRESS_COST
1149 #define TARGET_ADDRESS_COST hook_int_rtx_0
1151 #undef TARGET_VECTOR_OPAQUE_P
1152 #define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
1154 #undef TARGET_DWARF_REGISTER_SPAN
1155 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1157 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1158 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1160 /* On rs6000, function arguments are promoted, as are function return
1162 #undef TARGET_PROMOTE_FUNCTION_ARGS
1163 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
1164 #undef TARGET_PROMOTE_FUNCTION_RETURN
1165 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
1167 #undef TARGET_RETURN_IN_MEMORY
1168 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1170 #undef TARGET_SETUP_INCOMING_VARARGS
1171 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1173 /* Always strict argument naming on rs6000. */
1174 #undef TARGET_STRICT_ARGUMENT_NAMING
1175 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1176 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1177 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1178 #undef TARGET_SPLIT_COMPLEX_ARG
1179 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1180 #undef TARGET_MUST_PASS_IN_STACK
1181 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1182 #undef TARGET_PASS_BY_REFERENCE
1183 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1184 #undef TARGET_ARG_PARTIAL_BYTES
1185 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1187 #undef TARGET_BUILD_BUILTIN_VA_LIST
1188 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1190 #undef TARGET_EXPAND_BUILTIN_VA_START
1191 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1193 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1194 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1196 #undef TARGET_EH_RETURN_FILTER_MODE
1197 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1199 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1200 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1202 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1203 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1205 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1206 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1208 #undef TARGET_HANDLE_OPTION
1209 #define TARGET_HANDLE_OPTION rs6000_handle_option
1211 #undef TARGET_DEFAULT_TARGET_FLAGS
1212 #define TARGET_DEFAULT_TARGET_FLAGS \
1215 #undef TARGET_STACK_PROTECT_FAIL
1216 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1218 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1219 The PowerPC architecture requires only weak consistency among
1220 processors--that is, memory accesses between processors need not be
1221 sequentially consistent and memory accesses among processors can occur
1222 in any order. The ability to order memory accesses weakly provides
1223 opportunities for more efficient use of the system bus. Unless a
1224 dependency exists, the 604e allows read operations to precede store
1226 #undef TARGET_RELAXED_ORDERING
1227 #define TARGET_RELAXED_ORDERING true
1230 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1231 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1234 /* Use a 32-bit anchor range. This leads to sequences like:
1236 addis tmp,anchor,high
1239 where tmp itself acts as an anchor, and can be shared between
1240 accesses to the same 64k page. */
1241 #undef TARGET_MIN_ANCHOR_OFFSET
1242 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1243 #undef TARGET_MAX_ANCHOR_OFFSET
1244 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1245 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1246 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1248 #undef TARGET_BUILTIN_RECIPROCAL
1249 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1251 #undef TARGET_EXPAND_TO_RTL_HOOK
1252 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1254 #undef TARGET_INSTANTIATE_DECLS
1255 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1257 struct gcc_target targetm
= TARGET_INITIALIZER
;
1260 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1263 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
1265 /* The GPRs can hold any mode, but values bigger than one register
1266 cannot go past R31. */
1267 if (INT_REGNO_P (regno
))
1268 return INT_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1);
1270 /* The float registers can only hold floating modes and DImode.
1271 This excludes the 32-bit decimal float mode for now. */
1272 if (FP_REGNO_P (regno
))
1274 ((SCALAR_FLOAT_MODE_P (mode
)
1275 && (mode
!= TDmode
|| (regno
% 2) == 0)
1276 && FP_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1))
1277 || (GET_MODE_CLASS (mode
) == MODE_INT
1278 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
)
1279 || (PAIRED_SIMD_REGNO_P (regno
) && TARGET_PAIRED_FLOAT
1280 && PAIRED_VECTOR_MODE (mode
)));
1282 /* The CR register can only hold CC modes. */
1283 if (CR_REGNO_P (regno
))
1284 return GET_MODE_CLASS (mode
) == MODE_CC
;
1286 if (XER_REGNO_P (regno
))
1287 return mode
== PSImode
;
1289 /* AltiVec only in AldyVec registers. */
1290 if (ALTIVEC_REGNO_P (regno
))
1291 return ALTIVEC_VECTOR_MODE (mode
);
1293 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1294 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1297 /* We cannot put TImode anywhere except general register and it must be
1298 able to fit within the register set. */
1300 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1303 /* Initialize rs6000_hard_regno_mode_ok_p table. */
1305 rs6000_init_hard_regno_mode_ok (void)
1309 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
1310 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1311 if (rs6000_hard_regno_mode_ok (r
, m
))
1312 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
1316 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
1319 darwin_rs6000_override_options (void)
1321 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
1323 rs6000_altivec_abi
= 1;
1324 TARGET_ALTIVEC_VRSAVE
= 1;
1325 if (DEFAULT_ABI
== ABI_DARWIN
)
1327 if (MACHO_DYNAMIC_NO_PIC_P
)
1330 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
1333 else if (flag_pic
== 1)
1338 if (TARGET_64BIT
&& ! TARGET_POWERPC64
)
1340 target_flags
|= MASK_POWERPC64
;
1341 warning (0, "-m64 requires PowerPC64 architecture, enabling");
1345 rs6000_default_long_calls
= 1;
1346 target_flags
|= MASK_SOFT_FLOAT
;
1349 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
1351 if (!flag_mkernel
&& !flag_apple_kext
1353 && ! (target_flags_explicit
& MASK_ALTIVEC
))
1354 target_flags
|= MASK_ALTIVEC
;
1356 /* Unless the user (not the configurer) has explicitly overridden
1357 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
1358 G4 unless targetting the kernel. */
1361 && strverscmp (darwin_macosx_version_min
, "10.5") >= 0
1362 && ! (target_flags_explicit
& MASK_ALTIVEC
)
1363 && ! rs6000_select
[1].string
)
1365 target_flags
|= MASK_ALTIVEC
;
1370 /* If not otherwise specified by a target, make 'long double' equivalent to
1373 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1374 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1377 /* Override command line options. Mostly we process the processor
1378 type and sometimes adjust other TARGET_ options. */
1381 rs6000_override_options (const char *default_cpu
)
1384 struct rs6000_cpu_select
*ptr
;
1387 /* Simplifications for entries below. */
1390 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
1391 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
1394 /* This table occasionally claims that a processor does not support
1395 a particular feature even though it does, but the feature is slower
1396 than the alternative. Thus, it shouldn't be relied on as a
1397 complete description of the processor's support.
1399 Please keep this list in order, and don't forget to update the
1400 documentation in invoke.texi when adding a new processor or
1404 const char *const name
; /* Canonical processor name. */
1405 const enum processor_type processor
; /* Processor type enum value. */
1406 const int target_enable
; /* Target flags to enable. */
1407 } const processor_target_table
[]
1408 = {{"401", PROCESSOR_PPC403
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1409 {"403", PROCESSOR_PPC403
,
1410 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_STRICT_ALIGN
},
1411 {"405", PROCESSOR_PPC405
,
1412 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1413 {"405fp", PROCESSOR_PPC405
,
1414 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1415 {"440", PROCESSOR_PPC440
,
1416 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1417 {"440fp", PROCESSOR_PPC440
,
1418 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1419 {"505", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
},
1420 {"601", PROCESSOR_PPC601
,
1421 MASK_POWER
| POWERPC_BASE_MASK
| MASK_MULTIPLE
| MASK_STRING
},
1422 {"602", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1423 {"603", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1424 {"603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1425 {"604", PROCESSOR_PPC604
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1426 {"604e", PROCESSOR_PPC604e
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1427 {"620", PROCESSOR_PPC620
,
1428 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1429 {"630", PROCESSOR_PPC630
,
1430 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1431 {"740", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1432 {"7400", PROCESSOR_PPC7400
, POWERPC_7400_MASK
},
1433 {"7450", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1434 {"750", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1435 {"801", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1436 {"821", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1437 {"823", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1438 {"8540", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
},
1439 /* 8548 has a dummy entry for now. */
1440 {"8548", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_STRICT_ALIGN
},
1441 {"e300c2", PROCESSOR_PPCE300C2
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1442 {"e300c3", PROCESSOR_PPCE300C3
, POWERPC_BASE_MASK
},
1443 {"860", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1444 {"970", PROCESSOR_POWER4
,
1445 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1446 {"cell", PROCESSOR_CELL
,
1447 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1448 {"common", PROCESSOR_COMMON
, MASK_NEW_MNEMONICS
},
1449 {"ec603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1450 {"G3", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1451 {"G4", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1452 {"G5", PROCESSOR_POWER4
,
1453 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1454 {"power", PROCESSOR_POWER
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1455 {"power2", PROCESSOR_POWER
,
1456 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1457 {"power3", PROCESSOR_PPC630
,
1458 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1459 {"power4", PROCESSOR_POWER4
,
1460 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1461 {"power5", PROCESSOR_POWER5
,
1462 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GFXOPT
1463 | MASK_MFCRF
| MASK_POPCNTB
},
1464 {"power5+", PROCESSOR_POWER5
,
1465 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GFXOPT
1466 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
},
1467 {"power6", PROCESSOR_POWER6
,
1468 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_MFCRF
| MASK_POPCNTB
1469 | MASK_FPRND
| MASK_CMPB
| MASK_DFP
},
1470 {"power6x", PROCESSOR_POWER6
,
1471 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_MFCRF
| MASK_POPCNTB
1472 | MASK_FPRND
| MASK_CMPB
| MASK_MFPGPR
| MASK_DFP
},
1473 {"powerpc", PROCESSOR_POWERPC
, POWERPC_BASE_MASK
},
1474 {"powerpc64", PROCESSOR_POWERPC64
,
1475 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1476 {"rios", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1477 {"rios1", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1478 {"rios2", PROCESSOR_RIOS2
,
1479 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1480 {"rsc", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1481 {"rsc1", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1482 {"rs64", PROCESSOR_RS64A
,
1483 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
}
1486 const size_t ptt_size
= ARRAY_SIZE (processor_target_table
);
1488 /* Some OSs don't support saving the high part of 64-bit registers on
1489 context switch. Other OSs don't support saving Altivec registers.
1490 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1491 settings; if the user wants either, the user must explicitly specify
1492 them and we won't interfere with the user's specification. */
1495 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
1496 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
| MASK_STRICT_ALIGN
1497 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
1498 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_MULHW
1499 | MASK_DLMZB
| MASK_CMPB
| MASK_MFPGPR
| MASK_DFP
)
1502 rs6000_init_hard_regno_mode_ok ();
1504 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
1505 #ifdef OS_MISSING_POWERPC64
1506 if (OS_MISSING_POWERPC64
)
1507 set_masks
&= ~MASK_POWERPC64
;
1509 #ifdef OS_MISSING_ALTIVEC
1510 if (OS_MISSING_ALTIVEC
)
1511 set_masks
&= ~MASK_ALTIVEC
;
1514 /* Don't override by the processor default if given explicitly. */
1515 set_masks
&= ~target_flags_explicit
;
1517 /* Identify the processor type. */
1518 rs6000_select
[0].string
= default_cpu
;
1519 rs6000_cpu
= TARGET_POWERPC64
? PROCESSOR_DEFAULT64
: PROCESSOR_DEFAULT
;
1521 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
1523 ptr
= &rs6000_select
[i
];
1524 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
1526 for (j
= 0; j
< ptt_size
; j
++)
1527 if (! strcmp (ptr
->string
, processor_target_table
[j
].name
))
1529 if (ptr
->set_tune_p
)
1530 rs6000_cpu
= processor_target_table
[j
].processor
;
1532 if (ptr
->set_arch_p
)
1534 target_flags
&= ~set_masks
;
1535 target_flags
|= (processor_target_table
[j
].target_enable
1542 error ("bad value (%s) for %s switch", ptr
->string
, ptr
->name
);
1549 if (rs6000_cpu
== PROCESSOR_PPCE300C2
|| rs6000_cpu
== PROCESSOR_PPCE300C3
)
1552 error ("AltiVec not supported in this target");
1554 error ("Spe not supported in this target");
1557 /* If we are optimizing big endian systems for space, use the load/store
1558 multiple and string instructions. */
1559 if (BYTES_BIG_ENDIAN
&& optimize_size
)
1560 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
1562 /* Don't allow -mmultiple or -mstring on little endian systems
1563 unless the cpu is a 750, because the hardware doesn't support the
1564 instructions used in little endian mode, and causes an alignment
1565 trap. The 750 does not cause an alignment trap (except when the
1566 target is unaligned). */
1568 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
1570 if (TARGET_MULTIPLE
)
1572 target_flags
&= ~MASK_MULTIPLE
;
1573 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
1574 warning (0, "-mmultiple is not supported on little endian systems");
1579 target_flags
&= ~MASK_STRING
;
1580 if ((target_flags_explicit
& MASK_STRING
) != 0)
1581 warning (0, "-mstring is not supported on little endian systems");
1585 /* Set debug flags */
1586 if (rs6000_debug_name
)
1588 if (! strcmp (rs6000_debug_name
, "all"))
1589 rs6000_debug_stack
= rs6000_debug_arg
= 1;
1590 else if (! strcmp (rs6000_debug_name
, "stack"))
1591 rs6000_debug_stack
= 1;
1592 else if (! strcmp (rs6000_debug_name
, "arg"))
1593 rs6000_debug_arg
= 1;
1595 error ("unknown -mdebug-%s switch", rs6000_debug_name
);
1598 if (rs6000_traceback_name
)
1600 if (! strncmp (rs6000_traceback_name
, "full", 4))
1601 rs6000_traceback
= traceback_full
;
1602 else if (! strncmp (rs6000_traceback_name
, "part", 4))
1603 rs6000_traceback
= traceback_part
;
1604 else if (! strncmp (rs6000_traceback_name
, "no", 2))
1605 rs6000_traceback
= traceback_none
;
1607 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
1608 rs6000_traceback_name
);
1611 if (!rs6000_explicit_options
.long_double
)
1612 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1614 #ifndef POWERPC_LINUX
1615 if (!rs6000_explicit_options
.ieee
)
1616 rs6000_ieeequad
= 1;
1619 /* Enable Altivec ABI for AIX -maltivec. */
1620 if (TARGET_XCOFF
&& TARGET_ALTIVEC
)
1621 rs6000_altivec_abi
= 1;
1623 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
1624 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
1625 be explicitly overridden in either case. */
1628 if (!rs6000_explicit_options
.altivec_abi
1629 && (TARGET_64BIT
|| TARGET_ALTIVEC
))
1630 rs6000_altivec_abi
= 1;
1632 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
1633 if (!rs6000_explicit_options
.vrsave
)
1634 TARGET_ALTIVEC_VRSAVE
= rs6000_altivec_abi
;
1637 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1638 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
1640 rs6000_darwin64_abi
= 1;
1642 darwin_one_byte_bool
= 1;
1644 /* Default to natural alignment, for better performance. */
1645 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
1648 /* Place FP constants in the constant pool instead of TOC
1649 if section anchors enabled. */
1650 if (flag_section_anchors
)
1651 TARGET_NO_FP_IN_TOC
= 1;
1653 /* Handle -mtls-size option. */
1654 rs6000_parse_tls_size_option ();
1656 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1657 SUBTARGET_OVERRIDE_OPTIONS
;
1659 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1660 SUBSUBTARGET_OVERRIDE_OPTIONS
;
1662 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
1663 SUB3TARGET_OVERRIDE_OPTIONS
;
1668 /* The e500 does not have string instructions, and we set
1669 MASK_STRING above when optimizing for size. */
1670 if ((target_flags
& MASK_STRING
) != 0)
1671 target_flags
= target_flags
& ~MASK_STRING
;
1673 else if (rs6000_select
[1].string
!= NULL
)
1675 /* For the powerpc-eabispe configuration, we set all these by
1676 default, so let's unset them if we manually set another
1677 CPU that is not the E500. */
1678 if (!rs6000_explicit_options
.spe_abi
)
1680 if (!rs6000_explicit_options
.spe
)
1682 if (!rs6000_explicit_options
.float_gprs
)
1683 rs6000_float_gprs
= 0;
1684 if (!rs6000_explicit_options
.isel
)
1688 /* Detect invalid option combinations with E500. */
1691 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
1692 && rs6000_cpu
!= PROCESSOR_POWER5
1693 && rs6000_cpu
!= PROCESSOR_POWER6
1694 && rs6000_cpu
!= PROCESSOR_CELL
);
1695 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
1696 || rs6000_cpu
== PROCESSOR_POWER5
);
1697 rs6000_align_branch_targets
= (rs6000_cpu
== PROCESSOR_POWER4
1698 || rs6000_cpu
== PROCESSOR_POWER5
1699 || rs6000_cpu
== PROCESSOR_POWER6
);
1701 rs6000_sched_restricted_insns_priority
1702 = (rs6000_sched_groups
? 1 : 0);
1704 /* Handle -msched-costly-dep option. */
1705 rs6000_sched_costly_dep
1706 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
1708 if (rs6000_sched_costly_dep_str
)
1710 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
1711 rs6000_sched_costly_dep
= no_dep_costly
;
1712 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
1713 rs6000_sched_costly_dep
= all_deps_costly
;
1714 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
1715 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
1716 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
1717 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
1719 rs6000_sched_costly_dep
= atoi (rs6000_sched_costly_dep_str
);
1722 /* Handle -minsert-sched-nops option. */
1723 rs6000_sched_insert_nops
1724 = (rs6000_sched_groups
? sched_finish_regroup_exact
: sched_finish_none
);
1726 if (rs6000_sched_insert_nops_str
)
1728 if (! strcmp (rs6000_sched_insert_nops_str
, "no"))
1729 rs6000_sched_insert_nops
= sched_finish_none
;
1730 else if (! strcmp (rs6000_sched_insert_nops_str
, "pad"))
1731 rs6000_sched_insert_nops
= sched_finish_pad_groups
;
1732 else if (! strcmp (rs6000_sched_insert_nops_str
, "regroup_exact"))
1733 rs6000_sched_insert_nops
= sched_finish_regroup_exact
;
1735 rs6000_sched_insert_nops
= atoi (rs6000_sched_insert_nops_str
);
1738 #ifdef TARGET_REGNAMES
1739 /* If the user desires alternate register names, copy in the
1740 alternate names now. */
1741 if (TARGET_REGNAMES
)
1742 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
1745 /* Set aix_struct_return last, after the ABI is determined.
1746 If -maix-struct-return or -msvr4-struct-return was explicitly
1747 used, don't override with the ABI default. */
1748 if (!rs6000_explicit_options
.aix_struct_ret
)
1749 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
1751 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
1752 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
1755 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
1757 /* We can only guarantee the availability of DI pseudo-ops when
1758 assembling for 64-bit targets. */
1761 targetm
.asm_out
.aligned_op
.di
= NULL
;
1762 targetm
.asm_out
.unaligned_op
.di
= NULL
;
1765 /* Set branch target alignment, if not optimizing for size. */
1768 /* Cell wants to be aligned 8byte for dual issue. */
1769 if (rs6000_cpu
== PROCESSOR_CELL
)
1771 if (align_functions
<= 0)
1772 align_functions
= 8;
1773 if (align_jumps
<= 0)
1775 if (align_loops
<= 0)
1778 if (rs6000_align_branch_targets
)
1780 if (align_functions
<= 0)
1781 align_functions
= 16;
1782 if (align_jumps
<= 0)
1784 if (align_loops
<= 0)
1787 if (align_jumps_max_skip
<= 0)
1788 align_jumps_max_skip
= 15;
1789 if (align_loops_max_skip
<= 0)
1790 align_loops_max_skip
= 15;
1793 /* Arrange to save and restore machine status around nested functions. */
1794 init_machine_status
= rs6000_init_machine_status
;
1796 /* We should always be splitting complex arguments, but we can't break
1797 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1798 if (DEFAULT_ABI
!= ABI_AIX
)
1799 targetm
.calls
.split_complex_arg
= NULL
;
1801 /* Initialize rs6000_cost with the appropriate target costs. */
1803 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
1807 case PROCESSOR_RIOS1
:
1808 rs6000_cost
= &rios1_cost
;
1811 case PROCESSOR_RIOS2
:
1812 rs6000_cost
= &rios2_cost
;
1815 case PROCESSOR_RS64A
:
1816 rs6000_cost
= &rs64a_cost
;
1819 case PROCESSOR_MPCCORE
:
1820 rs6000_cost
= &mpccore_cost
;
1823 case PROCESSOR_PPC403
:
1824 rs6000_cost
= &ppc403_cost
;
1827 case PROCESSOR_PPC405
:
1828 rs6000_cost
= &ppc405_cost
;
1831 case PROCESSOR_PPC440
:
1832 rs6000_cost
= &ppc440_cost
;
1835 case PROCESSOR_PPC601
:
1836 rs6000_cost
= &ppc601_cost
;
1839 case PROCESSOR_PPC603
:
1840 rs6000_cost
= &ppc603_cost
;
1843 case PROCESSOR_PPC604
:
1844 rs6000_cost
= &ppc604_cost
;
1847 case PROCESSOR_PPC604e
:
1848 rs6000_cost
= &ppc604e_cost
;
1851 case PROCESSOR_PPC620
:
1852 rs6000_cost
= &ppc620_cost
;
1855 case PROCESSOR_PPC630
:
1856 rs6000_cost
= &ppc630_cost
;
1859 case PROCESSOR_CELL
:
1860 rs6000_cost
= &ppccell_cost
;
1863 case PROCESSOR_PPC750
:
1864 case PROCESSOR_PPC7400
:
1865 rs6000_cost
= &ppc750_cost
;
1868 case PROCESSOR_PPC7450
:
1869 rs6000_cost
= &ppc7450_cost
;
1872 case PROCESSOR_PPC8540
:
1873 rs6000_cost
= &ppc8540_cost
;
1876 case PROCESSOR_PPCE300C2
:
1877 case PROCESSOR_PPCE300C3
:
1878 rs6000_cost
= &ppce300c2c3_cost
;
1881 case PROCESSOR_POWER4
:
1882 case PROCESSOR_POWER5
:
1883 rs6000_cost
= &power4_cost
;
1886 case PROCESSOR_POWER6
:
1887 rs6000_cost
= &power6_cost
;
1894 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES
))
1895 set_param_value ("simultaneous-prefetches",
1896 rs6000_cost
->simultaneous_prefetches
);
1897 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE
))
1898 set_param_value ("l1-cache-size", rs6000_cost
->l1_cache_size
);
1899 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE
))
1900 set_param_value ("l1-cache-line-size", rs6000_cost
->cache_line_size
);
1901 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE
))
1902 set_param_value ("l2-cache-size", rs6000_cost
->l2_cache_size
);
1904 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
1905 can be optimized to ap = __builtin_next_arg (0). */
1906 if (DEFAULT_ABI
!= ABI_V4
)
1907 targetm
.expand_builtin_va_start
= NULL
;
1910 /* Implement targetm.vectorize.builtin_mask_for_load. */
1912 rs6000_builtin_mask_for_load (void)
1915 return altivec_builtin_mask_for_load
;
1920 /* Implement targetm.vectorize.builtin_conversion. */
1922 rs6000_builtin_conversion (enum tree_code code
, tree type
)
1924 if (!TARGET_ALTIVEC
)
1930 switch (TYPE_MODE (type
))
1933 return TYPE_UNSIGNED (type
) ?
1934 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCFUX
] :
1935 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCFSX
];
1944 /* Implement targetm.vectorize.builtin_mul_widen_even. */
1946 rs6000_builtin_mul_widen_even (tree type
)
1948 if (!TARGET_ALTIVEC
)
1951 switch (TYPE_MODE (type
))
1954 return TYPE_UNSIGNED (type
) ?
1955 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUH
] :
1956 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESH
];
1959 return TYPE_UNSIGNED (type
) ?
1960 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUB
] :
1961 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESB
];
1967 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
1969 rs6000_builtin_mul_widen_odd (tree type
)
1971 if (!TARGET_ALTIVEC
)
1974 switch (TYPE_MODE (type
))
1977 return TYPE_UNSIGNED (type
) ?
1978 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUH
] :
1979 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSH
];
1982 return TYPE_UNSIGNED (type
) ?
1983 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUB
] :
1984 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSB
];
1991 /* Return true iff, data reference of TYPE can reach vector alignment (16)
1992 after applying N number of iterations. This routine does not determine
1993 how may iterations are required to reach desired alignment. */
1996 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED
, bool is_packed
)
2003 if (rs6000_alignment_flags
== MASK_ALIGN_NATURAL
)
2006 if (rs6000_alignment_flags
== MASK_ALIGN_POWER
)
2016 /* Assuming that all other types are naturally aligned. CHECKME! */
2021 /* Handle generic options of the form -mfoo=yes/no.
2022 NAME is the option name.
2023 VALUE is the option value.
2024 FLAG is the pointer to the flag where to store a 1 or 0, depending on
2025 whether the option value is 'yes' or 'no' respectively. */
2027 rs6000_parse_yes_no_option (const char *name
, const char *value
, int *flag
)
2031 else if (!strcmp (value
, "yes"))
2033 else if (!strcmp (value
, "no"))
2036 error ("unknown -m%s= option specified: '%s'", name
, value
);
2039 /* Validate and record the size specified with the -mtls-size option. */
2042 rs6000_parse_tls_size_option (void)
2044 if (rs6000_tls_size_string
== 0)
2046 else if (strcmp (rs6000_tls_size_string
, "16") == 0)
2047 rs6000_tls_size
= 16;
2048 else if (strcmp (rs6000_tls_size_string
, "32") == 0)
2049 rs6000_tls_size
= 32;
2050 else if (strcmp (rs6000_tls_size_string
, "64") == 0)
2051 rs6000_tls_size
= 64;
2053 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string
);
2057 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
2059 if (DEFAULT_ABI
== ABI_DARWIN
)
2060 /* The Darwin libraries never set errno, so we might as well
2061 avoid calling them when that's the only reason we would. */
2062 flag_errno_math
= 0;
2064 /* Double growth factor to counter reduced min jump length. */
2065 set_param_value ("max-grow-copy-bb-insns", 16);
2067 /* Enable section anchors by default.
2068 Skip section anchors for Objective C and Objective C++
2069 until front-ends fixed. */
2070 if (!TARGET_MACHO
&& lang_hooks
.name
[4] != 'O')
2071 flag_section_anchors
= 1;
2074 /* Implement TARGET_HANDLE_OPTION. */
2077 rs6000_handle_option (size_t code
, const char *arg
, int value
)
2082 target_flags
&= ~(MASK_POWER
| MASK_POWER2
2083 | MASK_MULTIPLE
| MASK_STRING
);
2084 target_flags_explicit
|= (MASK_POWER
| MASK_POWER2
2085 | MASK_MULTIPLE
| MASK_STRING
);
2087 case OPT_mno_powerpc
:
2088 target_flags
&= ~(MASK_POWERPC
| MASK_PPC_GPOPT
2089 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
2090 target_flags_explicit
|= (MASK_POWERPC
| MASK_PPC_GPOPT
2091 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
2094 target_flags
&= ~MASK_MINIMAL_TOC
;
2095 TARGET_NO_FP_IN_TOC
= 0;
2096 TARGET_NO_SUM_IN_TOC
= 0;
2097 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2098 #ifdef TARGET_USES_SYSV4_OPT
2099 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
2100 just the same as -mminimal-toc. */
2101 target_flags
|= MASK_MINIMAL_TOC
;
2102 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2106 #ifdef TARGET_USES_SYSV4_OPT
2108 /* Make -mtoc behave like -mminimal-toc. */
2109 target_flags
|= MASK_MINIMAL_TOC
;
2110 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2114 #ifdef TARGET_USES_AIX64_OPT
2119 target_flags
|= MASK_POWERPC64
| MASK_POWERPC
;
2120 target_flags
|= ~target_flags_explicit
& MASK_PPC_GFXOPT
;
2121 target_flags_explicit
|= MASK_POWERPC64
| MASK_POWERPC
;
2124 #ifdef TARGET_USES_AIX64_OPT
2129 target_flags
&= ~MASK_POWERPC64
;
2130 target_flags_explicit
|= MASK_POWERPC64
;
2133 case OPT_minsert_sched_nops_
:
2134 rs6000_sched_insert_nops_str
= arg
;
2137 case OPT_mminimal_toc
:
2140 TARGET_NO_FP_IN_TOC
= 0;
2141 TARGET_NO_SUM_IN_TOC
= 0;
2148 target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
2149 target_flags_explicit
|= (MASK_MULTIPLE
| MASK_STRING
);
2156 target_flags
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
2157 target_flags_explicit
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
2161 case OPT_mpowerpc_gpopt
:
2162 case OPT_mpowerpc_gfxopt
:
2165 target_flags
|= MASK_POWERPC
;
2166 target_flags_explicit
|= MASK_POWERPC
;
2170 case OPT_maix_struct_return
:
2171 case OPT_msvr4_struct_return
:
2172 rs6000_explicit_options
.aix_struct_ret
= true;
2176 rs6000_explicit_options
.vrsave
= true;
2177 rs6000_parse_yes_no_option ("vrsave", arg
, &(TARGET_ALTIVEC_VRSAVE
));
2181 rs6000_explicit_options
.isel
= true;
2182 rs6000_parse_yes_no_option ("isel", arg
, &(rs6000_isel
));
2186 rs6000_explicit_options
.spe
= true;
2187 rs6000_parse_yes_no_option ("spe", arg
, &(rs6000_spe
));
2191 rs6000_debug_name
= arg
;
2194 #ifdef TARGET_USES_SYSV4_OPT
2196 rs6000_abi_name
= arg
;
2200 rs6000_sdata_name
= arg
;
2203 case OPT_mtls_size_
:
2204 rs6000_tls_size_string
= arg
;
2207 case OPT_mrelocatable
:
2210 target_flags
|= MASK_MINIMAL_TOC
;
2211 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2212 TARGET_NO_FP_IN_TOC
= 1;
2216 case OPT_mrelocatable_lib
:
2219 target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
2220 target_flags_explicit
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
2221 TARGET_NO_FP_IN_TOC
= 1;
2225 target_flags
&= ~MASK_RELOCATABLE
;
2226 target_flags_explicit
|= MASK_RELOCATABLE
;
2232 if (!strcmp (arg
, "altivec"))
2234 rs6000_explicit_options
.altivec_abi
= true;
2235 rs6000_altivec_abi
= 1;
2237 /* Enabling the AltiVec ABI turns off the SPE ABI. */
2240 else if (! strcmp (arg
, "no-altivec"))
2242 rs6000_explicit_options
.altivec_abi
= true;
2243 rs6000_altivec_abi
= 0;
2245 else if (! strcmp (arg
, "spe"))
2247 rs6000_explicit_options
.spe_abi
= true;
2249 rs6000_altivec_abi
= 0;
2250 if (!TARGET_SPE_ABI
)
2251 error ("not configured for ABI: '%s'", arg
);
2253 else if (! strcmp (arg
, "no-spe"))
2255 rs6000_explicit_options
.spe_abi
= true;
2259 /* These are here for testing during development only, do not
2260 document in the manual please. */
2261 else if (! strcmp (arg
, "d64"))
2263 rs6000_darwin64_abi
= 1;
2264 warning (0, "Using darwin64 ABI");
2266 else if (! strcmp (arg
, "d32"))
2268 rs6000_darwin64_abi
= 0;
2269 warning (0, "Using old darwin ABI");
2272 else if (! strcmp (arg
, "ibmlongdouble"))
2274 rs6000_explicit_options
.ieee
= true;
2275 rs6000_ieeequad
= 0;
2276 warning (0, "Using IBM extended precision long double");
2278 else if (! strcmp (arg
, "ieeelongdouble"))
2280 rs6000_explicit_options
.ieee
= true;
2281 rs6000_ieeequad
= 1;
2282 warning (0, "Using IEEE extended precision long double");
2287 error ("unknown ABI specified: '%s'", arg
);
2293 rs6000_select
[1].string
= arg
;
2297 rs6000_select
[2].string
= arg
;
2300 case OPT_mtraceback_
:
2301 rs6000_traceback_name
= arg
;
2304 case OPT_mfloat_gprs_
:
2305 rs6000_explicit_options
.float_gprs
= true;
2306 if (! strcmp (arg
, "yes") || ! strcmp (arg
, "single"))
2307 rs6000_float_gprs
= 1;
2308 else if (! strcmp (arg
, "double"))
2309 rs6000_float_gprs
= 2;
2310 else if (! strcmp (arg
, "no"))
2311 rs6000_float_gprs
= 0;
2314 error ("invalid option for -mfloat-gprs: '%s'", arg
);
2319 case OPT_mlong_double_
:
2320 rs6000_explicit_options
.long_double
= true;
2321 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2322 if (value
!= 64 && value
!= 128)
2324 error ("Unknown switch -mlong-double-%s", arg
);
2325 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2329 rs6000_long_double_type_size
= value
;
2332 case OPT_msched_costly_dep_
:
2333 rs6000_sched_costly_dep_str
= arg
;
2337 rs6000_explicit_options
.alignment
= true;
2338 if (! strcmp (arg
, "power"))
2340 /* On 64-bit Darwin, power alignment is ABI-incompatible with
2341 some C library functions, so warn about it. The flag may be
2342 useful for performance studies from time to time though, so
2343 don't disable it entirely. */
2344 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
2345 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2346 " it is incompatible with the installed C and C++ libraries");
2347 rs6000_alignment_flags
= MASK_ALIGN_POWER
;
2349 else if (! strcmp (arg
, "natural"))
2350 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
2353 error ("unknown -malign-XXXXX option specified: '%s'", arg
);
2361 /* Do anything needed at the start of the asm file. */
2364 rs6000_file_start (void)
2368 const char *start
= buffer
;
2369 struct rs6000_cpu_select
*ptr
;
2370 const char *default_cpu
= TARGET_CPU_DEFAULT
;
2371 FILE *file
= asm_out_file
;
2373 default_file_start ();
2375 #ifdef TARGET_BI_ARCH
2376 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
2380 if (flag_verbose_asm
)
2382 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
2383 rs6000_select
[0].string
= default_cpu
;
2385 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
2387 ptr
= &rs6000_select
[i
];
2388 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
2390 fprintf (file
, "%s %s%s", start
, ptr
->name
, ptr
->string
);
2395 if (PPC405_ERRATUM77
)
2397 fprintf (file
, "%s PPC405CR_ERRATUM77", start
);
2401 #ifdef USING_ELFOS_H
2402 switch (rs6000_sdata
)
2404 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
2405 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
2406 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
2407 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
2410 if (rs6000_sdata
&& g_switch_value
)
2412 fprintf (file
, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED
, start
,
2422 #ifdef HAVE_AS_GNU_ATTRIBUTE
2423 if (TARGET_32BIT
&& DEFAULT_ABI
== ABI_V4
)
2425 fprintf (file
, "\t.gnu_attribute 4, %d\n",
2426 (TARGET_HARD_FLOAT
&& TARGET_FPRS
) ? 1 : 2);
2427 fprintf (file
, "\t.gnu_attribute 8, %d\n",
2428 (TARGET_ALTIVEC_ABI
? 2
2429 : TARGET_SPE_ABI
? 3
2434 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
2436 switch_to_section (toc_section
);
2437 switch_to_section (text_section
);
2442 /* Return nonzero if this function is known to have a null epilogue. */
2445 direct_return (void)
2447 if (reload_completed
)
2449 rs6000_stack_t
*info
= rs6000_stack_info ();
2451 if (info
->first_gp_reg_save
== 32
2452 && info
->first_fp_reg_save
== 64
2453 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
2454 && ! info
->lr_save_p
2455 && ! info
->cr_save_p
2456 && info
->vrsave_mask
== 0
2464 /* Return the number of instructions it takes to form a constant in an
2465 integer register. */
2468 num_insns_constant_wide (HOST_WIDE_INT value
)
2470 /* signed constant loadable with {cal|addi} */
2471 if ((unsigned HOST_WIDE_INT
) (value
+ 0x8000) < 0x10000)
2474 /* constant loadable with {cau|addis} */
2475 else if ((value
& 0xffff) == 0
2476 && (value
>> 31 == -1 || value
>> 31 == 0))
2479 #if HOST_BITS_PER_WIDE_INT == 64
2480 else if (TARGET_POWERPC64
)
2482 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
2483 HOST_WIDE_INT high
= value
>> 31;
2485 if (high
== 0 || high
== -1)
2491 return num_insns_constant_wide (high
) + 1;
2493 return (num_insns_constant_wide (high
)
2494 + num_insns_constant_wide (low
) + 1);
2503 num_insns_constant (rtx op
, enum machine_mode mode
)
2505 HOST_WIDE_INT low
, high
;
2507 switch (GET_CODE (op
))
2510 #if HOST_BITS_PER_WIDE_INT == 64
2511 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
2512 && mask64_operand (op
, mode
))
2516 return num_insns_constant_wide (INTVAL (op
));
2519 if (mode
== SFmode
|| mode
== SDmode
)
2524 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2525 if (DECIMAL_FLOAT_MODE_P (mode
))
2526 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
2528 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
2529 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
2532 if (mode
== VOIDmode
|| mode
== DImode
)
2534 high
= CONST_DOUBLE_HIGH (op
);
2535 low
= CONST_DOUBLE_LOW (op
);
2542 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2543 if (DECIMAL_FLOAT_MODE_P (mode
))
2544 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, l
);
2546 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
2547 high
= l
[WORDS_BIG_ENDIAN
== 0];
2548 low
= l
[WORDS_BIG_ENDIAN
!= 0];
2552 return (num_insns_constant_wide (low
)
2553 + num_insns_constant_wide (high
));
2556 if ((high
== 0 && low
>= 0)
2557 || (high
== -1 && low
< 0))
2558 return num_insns_constant_wide (low
);
2560 else if (mask64_operand (op
, mode
))
2564 return num_insns_constant_wide (high
) + 1;
2567 return (num_insns_constant_wide (high
)
2568 + num_insns_constant_wide (low
) + 1);
2576 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
2577 If the mode of OP is MODE_VECTOR_INT, this simply returns the
2578 corresponding element of the vector, but for V4SFmode and V2SFmode,
2579 the corresponding "float" is interpreted as an SImode integer. */
2581 static HOST_WIDE_INT
2582 const_vector_elt_as_int (rtx op
, unsigned int elt
)
2584 rtx tmp
= CONST_VECTOR_ELT (op
, elt
);
2585 if (GET_MODE (op
) == V4SFmode
2586 || GET_MODE (op
) == V2SFmode
)
2587 tmp
= gen_lowpart (SImode
, tmp
);
2588 return INTVAL (tmp
);
2591 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
2592 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2593 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2594 all items are set to the same value and contain COPIES replicas of the
2595 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2596 operand and the others are set to the value of the operand's msb. */
2599 vspltis_constant (rtx op
, unsigned step
, unsigned copies
)
2601 enum machine_mode mode
= GET_MODE (op
);
2602 enum machine_mode inner
= GET_MODE_INNER (mode
);
2605 unsigned nunits
= GET_MODE_NUNITS (mode
);
2606 unsigned bitsize
= GET_MODE_BITSIZE (inner
);
2607 unsigned mask
= GET_MODE_MASK (inner
);
2609 HOST_WIDE_INT val
= const_vector_elt_as_int (op
, nunits
- 1);
2610 HOST_WIDE_INT splat_val
= val
;
2611 HOST_WIDE_INT msb_val
= val
> 0 ? 0 : -1;
2613 /* Construct the value to be splatted, if possible. If not, return 0. */
2614 for (i
= 2; i
<= copies
; i
*= 2)
2616 HOST_WIDE_INT small_val
;
2618 small_val
= splat_val
>> bitsize
;
2620 if (splat_val
!= ((small_val
<< bitsize
) | (small_val
& mask
)))
2622 splat_val
= small_val
;
2625 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2626 if (EASY_VECTOR_15 (splat_val
))
2629 /* Also check if we can splat, and then add the result to itself. Do so if
2630 the value is positive, of if the splat instruction is using OP's mode;
2631 for splat_val < 0, the splat and the add should use the same mode. */
2632 else if (EASY_VECTOR_15_ADD_SELF (splat_val
)
2633 && (splat_val
>= 0 || (step
== 1 && copies
== 1)))
2639 /* Check if VAL is present in every STEP-th element, and the
2640 other elements are filled with its most significant bit. */
2641 for (i
= 0; i
< nunits
- 1; ++i
)
2643 HOST_WIDE_INT desired_val
;
2644 if (((i
+ 1) & (step
- 1)) == 0)
2647 desired_val
= msb_val
;
2649 if (desired_val
!= const_vector_elt_as_int (op
, i
))
2657 /* Return true if OP is of the given MODE and can be synthesized
2658 with a vspltisb, vspltish or vspltisw. */
2661 easy_altivec_constant (rtx op
, enum machine_mode mode
)
2663 unsigned step
, copies
;
2665 if (mode
== VOIDmode
)
2666 mode
= GET_MODE (op
);
2667 else if (mode
!= GET_MODE (op
))
2670 /* Start with a vspltisw. */
2671 step
= GET_MODE_NUNITS (mode
) / 4;
2674 if (vspltis_constant (op
, step
, copies
))
2677 /* Then try with a vspltish. */
2683 if (vspltis_constant (op
, step
, copies
))
2686 /* And finally a vspltisb. */
2692 if (vspltis_constant (op
, step
, copies
))
2698 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2699 result is OP. Abort if it is not possible. */
2702 gen_easy_altivec_constant (rtx op
)
2704 enum machine_mode mode
= GET_MODE (op
);
2705 int nunits
= GET_MODE_NUNITS (mode
);
2706 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
2707 unsigned step
= nunits
/ 4;
2708 unsigned copies
= 1;
2710 /* Start with a vspltisw. */
2711 if (vspltis_constant (op
, step
, copies
))
2712 return gen_rtx_VEC_DUPLICATE (V4SImode
, gen_lowpart (SImode
, last
));
2714 /* Then try with a vspltish. */
2720 if (vspltis_constant (op
, step
, copies
))
2721 return gen_rtx_VEC_DUPLICATE (V8HImode
, gen_lowpart (HImode
, last
));
2723 /* And finally a vspltisb. */
2729 if (vspltis_constant (op
, step
, copies
))
2730 return gen_rtx_VEC_DUPLICATE (V16QImode
, gen_lowpart (QImode
, last
));
2736 output_vec_const_move (rtx
*operands
)
2739 enum machine_mode mode
;
2744 mode
= GET_MODE (dest
);
2749 if (zero_constant (vec
, mode
))
2750 return "vxor %0,%0,%0";
2752 splat_vec
= gen_easy_altivec_constant (vec
);
2753 gcc_assert (GET_CODE (splat_vec
) == VEC_DUPLICATE
);
2754 operands
[1] = XEXP (splat_vec
, 0);
2755 if (!EASY_VECTOR_15 (INTVAL (operands
[1])))
2758 switch (GET_MODE (splat_vec
))
2761 return "vspltisw %0,%1";
2764 return "vspltish %0,%1";
2767 return "vspltisb %0,%1";
2774 gcc_assert (TARGET_SPE
);
2776 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2777 pattern of V1DI, V4HI, and V2SF.
2779 FIXME: We should probably return # and add post reload
2780 splitters for these, but this way is so easy ;-). */
2781 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
2782 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
2783 operands
[1] = CONST_VECTOR_ELT (vec
, 0);
2784 operands
[2] = CONST_VECTOR_ELT (vec
, 1);
2786 return "li %0,%1\n\tevmergelo %0,%0,%0";
2788 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
2791 /* Initialize TARGET of vector PAIRED to VALS. */
2794 paired_expand_vector_init (rtx target
, rtx vals
)
2796 enum machine_mode mode
= GET_MODE (target
);
2797 int n_elts
= GET_MODE_NUNITS (mode
);
2799 rtx x
, new, tmp
, constant_op
, op1
, op2
;
2802 for (i
= 0; i
< n_elts
; ++i
)
2804 x
= XVECEXP (vals
, 0, i
);
2805 if (!CONSTANT_P (x
))
2810 /* Load from constant pool. */
2811 emit_move_insn (target
, gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0)));
2817 /* The vector is initialized only with non-constants. */
2818 new = gen_rtx_VEC_CONCAT (V2SFmode
, XVECEXP (vals
, 0, 0),
2819 XVECEXP (vals
, 0, 1));
2821 emit_move_insn (target
, new);
2825 /* One field is non-constant and the other one is a constant. Load the
2826 constant from the constant pool and use ps_merge instruction to
2827 construct the whole vector. */
2828 op1
= XVECEXP (vals
, 0, 0);
2829 op2
= XVECEXP (vals
, 0, 1);
2831 constant_op
= (CONSTANT_P (op1
)) ? op1
: op2
;
2833 tmp
= gen_reg_rtx (GET_MODE (constant_op
));
2834 emit_move_insn (tmp
, constant_op
);
2836 if (CONSTANT_P (op1
))
2837 new = gen_rtx_VEC_CONCAT (V2SFmode
, tmp
, op2
);
2839 new = gen_rtx_VEC_CONCAT (V2SFmode
, op1
, tmp
);
2841 emit_move_insn (target
, new);
2845 paired_expand_vector_move (rtx operands
[])
2847 rtx op0
= operands
[0], op1
= operands
[1];
2849 emit_move_insn (op0
, op1
);
2852 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
2853 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
2854 operands for the relation operation COND. This is a recursive
2858 paired_emit_vector_compare (enum rtx_code rcode
,
2859 rtx dest
, rtx op0
, rtx op1
,
2860 rtx cc_op0
, rtx cc_op1
)
2862 rtx tmp
= gen_reg_rtx (V2SFmode
);
2863 rtx tmp1
, max
, min
, equal_zero
;
2865 gcc_assert (TARGET_PAIRED_FLOAT
);
2866 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
2872 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
2876 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
2877 emit_insn (gen_selv2sf4 (dest
, tmp
, op0
, op1
, CONST0_RTX (SFmode
)));
2881 paired_emit_vector_compare (GE
, dest
, op0
, op1
, cc_op1
, cc_op0
);
2884 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
2887 tmp1
= gen_reg_rtx (V2SFmode
);
2888 max
= gen_reg_rtx (V2SFmode
);
2889 min
= gen_reg_rtx (V2SFmode
);
2890 equal_zero
= gen_reg_rtx (V2SFmode
);
2892 emit_insn (gen_subv2sf3 (tmp
, cc_op0
, cc_op1
));
2893 emit_insn (gen_selv2sf4
2894 (max
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
2895 emit_insn (gen_subv2sf3 (tmp
, cc_op1
, cc_op0
));
2896 emit_insn (gen_selv2sf4
2897 (min
, tmp
, cc_op0
, cc_op1
, CONST0_RTX (SFmode
)));
2898 emit_insn (gen_subv2sf3 (tmp1
, min
, max
));
2899 emit_insn (gen_selv2sf4 (dest
, tmp1
, op0
, op1
, CONST0_RTX (SFmode
)));
2902 paired_emit_vector_compare (EQ
, dest
, op1
, op0
, cc_op0
, cc_op1
);
2905 paired_emit_vector_compare (LE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
2908 paired_emit_vector_compare (LT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
2911 paired_emit_vector_compare (GE
, dest
, op1
, op0
, cc_op0
, cc_op1
);
2914 paired_emit_vector_compare (GT
, dest
, op1
, op0
, cc_op0
, cc_op1
);
2923 /* Emit vector conditional expression.
2924 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
2925 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
2928 paired_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
2929 rtx cond
, rtx cc_op0
, rtx cc_op1
)
2931 enum rtx_code rcode
= GET_CODE (cond
);
2933 if (!TARGET_PAIRED_FLOAT
)
2936 paired_emit_vector_compare (rcode
, dest
, op1
, op2
, cc_op0
, cc_op1
);
2941 /* Initialize vector TARGET to VALS. */
2944 rs6000_expand_vector_init (rtx target
, rtx vals
)
2946 enum machine_mode mode
= GET_MODE (target
);
2947 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
2948 int n_elts
= GET_MODE_NUNITS (mode
);
2949 int n_var
= 0, one_var
= -1;
2950 bool all_same
= true, all_const_zero
= true;
2954 for (i
= 0; i
< n_elts
; ++i
)
2956 x
= XVECEXP (vals
, 0, i
);
2957 if (!CONSTANT_P (x
))
2958 ++n_var
, one_var
= i
;
2959 else if (x
!= CONST0_RTX (inner_mode
))
2960 all_const_zero
= false;
2962 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
2968 rtx const_vec
= gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0));
2969 if (mode
!= V4SFmode
&& all_const_zero
)
2971 /* Zero register. */
2972 emit_insn (gen_rtx_SET (VOIDmode
, target
,
2973 gen_rtx_XOR (mode
, target
, target
)));
2976 else if (mode
!= V4SFmode
&& easy_vector_constant (const_vec
, mode
))
2978 /* Splat immediate. */
2979 emit_insn (gen_rtx_SET (VOIDmode
, target
, const_vec
));
2983 ; /* Splat vector element. */
2986 /* Load from constant pool. */
2987 emit_move_insn (target
, const_vec
);
2992 /* Store value to stack temp. Load vector element. Splat. */
2995 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
2996 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0),
2997 XVECEXP (vals
, 0, 0));
2998 x
= gen_rtx_UNSPEC (VOIDmode
,
2999 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
3000 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3002 gen_rtx_SET (VOIDmode
,
3005 x
= gen_rtx_VEC_SELECT (inner_mode
, target
,
3006 gen_rtx_PARALLEL (VOIDmode
,
3007 gen_rtvec (1, const0_rtx
)));
3008 emit_insn (gen_rtx_SET (VOIDmode
, target
,
3009 gen_rtx_VEC_DUPLICATE (mode
, x
)));
3013 /* One field is non-constant. Load constant then overwrite
3017 rtx copy
= copy_rtx (vals
);
3019 /* Load constant part of vector, substitute neighboring value for
3021 XVECEXP (copy
, 0, one_var
) = XVECEXP (vals
, 0, (one_var
+ 1) % n_elts
);
3022 rs6000_expand_vector_init (target
, copy
);
3024 /* Insert variable. */
3025 rs6000_expand_vector_set (target
, XVECEXP (vals
, 0, one_var
), one_var
);
3029 /* Construct the vector in memory one field at a time
3030 and load the whole vector. */
3031 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
3032 for (i
= 0; i
< n_elts
; i
++)
3033 emit_move_insn (adjust_address_nv (mem
, inner_mode
,
3034 i
* GET_MODE_SIZE (inner_mode
)),
3035 XVECEXP (vals
, 0, i
));
3036 emit_move_insn (target
, mem
);
3039 /* Set field ELT of TARGET to VAL. */
3042 rs6000_expand_vector_set (rtx target
, rtx val
, int elt
)
3044 enum machine_mode mode
= GET_MODE (target
);
3045 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
3046 rtx reg
= gen_reg_rtx (mode
);
3048 int width
= GET_MODE_SIZE (inner_mode
);
3051 /* Load single variable value. */
3052 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
3053 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0), val
);
3054 x
= gen_rtx_UNSPEC (VOIDmode
,
3055 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
3056 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3058 gen_rtx_SET (VOIDmode
,
3062 /* Linear sequence. */
3063 mask
= gen_rtx_PARALLEL (V16QImode
, rtvec_alloc (16));
3064 for (i
= 0; i
< 16; ++i
)
3065 XVECEXP (mask
, 0, i
) = GEN_INT (i
);
3067 /* Set permute mask to insert element into target. */
3068 for (i
= 0; i
< width
; ++i
)
3069 XVECEXP (mask
, 0, elt
*width
+ i
)
3070 = GEN_INT (i
+ 0x10);
3071 x
= gen_rtx_CONST_VECTOR (V16QImode
, XVEC (mask
, 0));
3072 x
= gen_rtx_UNSPEC (mode
,
3073 gen_rtvec (3, target
, reg
,
3074 force_reg (V16QImode
, x
)),
3076 emit_insn (gen_rtx_SET (VOIDmode
, target
, x
));
3079 /* Extract field ELT from VEC into TARGET. */
3082 rs6000_expand_vector_extract (rtx target
, rtx vec
, int elt
)
3084 enum machine_mode mode
= GET_MODE (vec
);
3085 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
3088 /* Allocate mode-sized buffer. */
3089 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
3091 /* Add offset to field within buffer matching vector element. */
3092 mem
= adjust_address_nv (mem
, mode
, elt
* GET_MODE_SIZE (inner_mode
));
3094 /* Store single field into mode-sized buffer. */
3095 x
= gen_rtx_UNSPEC (VOIDmode
,
3096 gen_rtvec (1, const0_rtx
), UNSPEC_STVE
);
3097 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3099 gen_rtx_SET (VOIDmode
,
3102 emit_move_insn (target
, adjust_address_nv (mem
, inner_mode
, 0));
3105 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
3106 implement ANDing by the mask IN. */
3108 build_mask64_2_operands (rtx in
, rtx
*out
)
3110 #if HOST_BITS_PER_WIDE_INT >= 64
3111 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
3114 gcc_assert (GET_CODE (in
) == CONST_INT
);
3119 /* Assume c initially something like 0x00fff000000fffff. The idea
3120 is to rotate the word so that the middle ^^^^^^ group of zeros
3121 is at the MS end and can be cleared with an rldicl mask. We then
3122 rotate back and clear off the MS ^^ group of zeros with a
3124 c
= ~c
; /* c == 0xff000ffffff00000 */
3125 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
3126 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
3127 c
= ~c
; /* c == 0x00fff000000fffff */
3128 c
&= -lsb
; /* c == 0x00fff00000000000 */
3129 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
3130 c
= ~c
; /* c == 0xff000fffffffffff */
3131 c
&= -lsb
; /* c == 0xff00000000000000 */
3133 while ((lsb
>>= 1) != 0)
3134 shift
++; /* shift == 44 on exit from loop */
3135 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
3136 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
3137 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
3141 /* Assume c initially something like 0xff000f0000000000. The idea
3142 is to rotate the word so that the ^^^ middle group of zeros
3143 is at the LS end and can be cleared with an rldicr mask. We then
3144 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
3146 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
3147 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
3148 c
= ~c
; /* c == 0x00fff0ffffffffff */
3149 c
&= -lsb
; /* c == 0x00fff00000000000 */
3150 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
3151 c
= ~c
; /* c == 0xff000fffffffffff */
3152 c
&= -lsb
; /* c == 0xff00000000000000 */
3154 while ((lsb
>>= 1) != 0)
3155 shift
++; /* shift == 44 on exit from loop */
3156 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
3157 m1
>>= shift
; /* m1 == 0x0000000000000fff */
3158 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
3161 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
3162 masks will be all 1's. We are guaranteed more than one transition. */
3163 out
[0] = GEN_INT (64 - shift
);
3164 out
[1] = GEN_INT (m1
);
3165 out
[2] = GEN_INT (shift
);
3166 out
[3] = GEN_INT (m2
);
3174 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
3177 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
3179 if (TARGET_E500_DOUBLE
)
3181 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
3182 subreg:TI and reg:TF. */
3183 if (GET_CODE (op
) == SUBREG
3184 && (mode
== SImode
|| mode
== DImode
|| mode
== TImode
)
3185 && REG_P (SUBREG_REG (op
))
3186 && (GET_MODE (SUBREG_REG (op
)) == DFmode
3187 || GET_MODE (SUBREG_REG (op
)) == TFmode
3188 || GET_MODE (SUBREG_REG (op
)) == DDmode
3189 || GET_MODE (SUBREG_REG (op
)) == TDmode
))
3192 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
3194 if (GET_CODE (op
) == SUBREG
3195 && (mode
== DFmode
|| mode
== TFmode
3196 || mode
== DDmode
|| mode
== TDmode
)
3197 && REG_P (SUBREG_REG (op
))
3198 && (GET_MODE (SUBREG_REG (op
)) == DImode
3199 || GET_MODE (SUBREG_REG (op
)) == TImode
))
3204 && GET_CODE (op
) == SUBREG
3206 && REG_P (SUBREG_REG (op
))
3207 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op
))))
3213 /* AIX increases natural record alignment to doubleword if the first
3214 field is an FP double while the FP fields remain word aligned. */
3217 rs6000_special_round_type_align (tree type
, unsigned int computed
,
3218 unsigned int specified
)
3220 unsigned int align
= MAX (computed
, specified
);
3221 tree field
= TYPE_FIELDS (type
);
3223 /* Skip all non field decls */
3224 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
3225 field
= TREE_CHAIN (field
);
3227 if (field
!= NULL
&& field
!= type
)
3229 type
= TREE_TYPE (field
);
3230 while (TREE_CODE (type
) == ARRAY_TYPE
)
3231 type
= TREE_TYPE (type
);
3233 if (type
!= error_mark_node
&& TYPE_MODE (type
) == DFmode
)
3234 align
= MAX (align
, 64);
3240 /* Darwin increases record alignment to the natural alignment of
3244 darwin_rs6000_special_round_type_align (tree type
, unsigned int computed
,
3245 unsigned int specified
)
3247 unsigned int align
= MAX (computed
, specified
);
3249 if (TYPE_PACKED (type
))
3252 /* Find the first field, looking down into aggregates. */
3254 tree field
= TYPE_FIELDS (type
);
3255 /* Skip all non field decls */
3256 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
3257 field
= TREE_CHAIN (field
);
3260 type
= TREE_TYPE (field
);
3261 while (TREE_CODE (type
) == ARRAY_TYPE
)
3262 type
= TREE_TYPE (type
);
3263 } while (AGGREGATE_TYPE_P (type
));
3265 if (! AGGREGATE_TYPE_P (type
) && type
!= error_mark_node
)
3266 align
= MAX (align
, TYPE_ALIGN (type
));
3271 /* Return 1 for an operand in small memory on V.4/eabi. */
3274 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
3275 enum machine_mode mode ATTRIBUTE_UNUSED
)
3280 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
3283 if (DEFAULT_ABI
!= ABI_V4
)
3286 /* Vector and float memory instructions have a limited offset on the
3287 SPE, so using a vector or float variable directly as an operand is
3290 && (SPE_VECTOR_MODE (mode
) || FLOAT_MODE_P (mode
)))
3293 if (GET_CODE (op
) == SYMBOL_REF
)
3296 else if (GET_CODE (op
) != CONST
3297 || GET_CODE (XEXP (op
, 0)) != PLUS
3298 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
3299 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
3304 rtx sum
= XEXP (op
, 0);
3305 HOST_WIDE_INT summand
;
3307 /* We have to be careful here, because it is the referenced address
3308 that must be 32k from _SDA_BASE_, not just the symbol. */
3309 summand
= INTVAL (XEXP (sum
, 1));
3310 if (summand
< 0 || (unsigned HOST_WIDE_INT
) summand
> g_switch_value
)
3313 sym_ref
= XEXP (sum
, 0);
3316 return SYMBOL_REF_SMALL_P (sym_ref
);
3322 /* Return true if either operand is a general purpose register. */
3325 gpr_or_gpr_p (rtx op0
, rtx op1
)
3327 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
3328 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
3332 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
3335 constant_pool_expr_1 (rtx op
, int *have_sym
, int *have_toc
)
3337 switch (GET_CODE (op
))
3340 if (RS6000_SYMBOL_REF_TLS_P (op
))
3342 else if (CONSTANT_POOL_ADDRESS_P (op
))
3344 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op
), Pmode
))
3352 else if (! strcmp (XSTR (op
, 0), toc_label_name
))
3361 return (constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
)
3362 && constant_pool_expr_1 (XEXP (op
, 1), have_sym
, have_toc
));
3364 return constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
);
3373 constant_pool_expr_p (rtx op
)
3377 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_sym
;
3381 toc_relative_expr_p (rtx op
)
3385 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_toc
;
3389 legitimate_constant_pool_address_p (rtx x
)
3392 && GET_CODE (x
) == PLUS
3393 && GET_CODE (XEXP (x
, 0)) == REG
3394 && (TARGET_MINIMAL_TOC
|| REGNO (XEXP (x
, 0)) == TOC_REGISTER
)
3395 && constant_pool_expr_p (XEXP (x
, 1)));
3399 legitimate_small_data_p (enum machine_mode mode
, rtx x
)
3401 return (DEFAULT_ABI
== ABI_V4
3402 && !flag_pic
&& !TARGET_TOC
3403 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
3404 && small_data_operand (x
, mode
));
3407 /* SPE offset addressing is limited to 5-bits worth of double words. */
3408 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
3411 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
3413 unsigned HOST_WIDE_INT offset
, extra
;
3415 if (GET_CODE (x
) != PLUS
)
3417 if (GET_CODE (XEXP (x
, 0)) != REG
)
3419 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
3421 if (legitimate_constant_pool_address_p (x
))
3423 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
3426 offset
= INTVAL (XEXP (x
, 1));
3434 /* AltiVec vector modes. Only reg+reg addressing is valid and
3435 constant offset zero should not occur due to canonicalization. */
3442 /* Paired vector modes. Only reg+reg addressing is valid and
3443 constant offset zero should not occur due to canonicalization. */
3444 if (TARGET_PAIRED_FLOAT
)
3446 /* SPE vector modes. */
3447 return SPE_CONST_OFFSET_OK (offset
);
3451 if (TARGET_E500_DOUBLE
)
3452 return SPE_CONST_OFFSET_OK (offset
);
3455 /* On e500v2, we may have:
3457 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
3459 Which gets addressed with evldd instructions. */
3460 if (TARGET_E500_DOUBLE
)
3461 return SPE_CONST_OFFSET_OK (offset
);
3463 if (mode
== DFmode
|| mode
== DDmode
|| !TARGET_POWERPC64
)
3465 else if (offset
& 3)
3471 if (TARGET_E500_DOUBLE
)
3472 return (SPE_CONST_OFFSET_OK (offset
)
3473 && SPE_CONST_OFFSET_OK (offset
+ 8));
3476 if (mode
== TFmode
|| mode
== TDmode
|| !TARGET_POWERPC64
)
3478 else if (offset
& 3)
3489 return (offset
< 0x10000) && (offset
+ extra
< 0x10000);
3493 legitimate_indexed_address_p (rtx x
, int strict
)
3497 if (GET_CODE (x
) != PLUS
)
3503 /* Recognize the rtl generated by reload which we know will later be
3504 replaced with proper base and index regs. */
3506 && reload_in_progress
3507 && (REG_P (op0
) || GET_CODE (op0
) == PLUS
)
3511 return (REG_P (op0
) && REG_P (op1
)
3512 && ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
3513 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
3514 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
3515 && INT_REG_OK_FOR_INDEX_P (op0
, strict
))));
3519 legitimate_indirect_address_p (rtx x
, int strict
)
3521 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
3525 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
3527 if (!TARGET_MACHO
|| !flag_pic
3528 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
3532 if (GET_CODE (x
) != LO_SUM
)
3534 if (GET_CODE (XEXP (x
, 0)) != REG
)
3536 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
3540 return CONSTANT_P (x
);
3544 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
3546 if (GET_CODE (x
) != LO_SUM
)
3548 if (GET_CODE (XEXP (x
, 0)) != REG
)
3550 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
3552 /* Restrict addressing for DI because of our SUBREG hackery. */
3553 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3554 || mode
== DDmode
|| mode
== TDmode
3559 if (TARGET_ELF
|| TARGET_MACHO
)
3561 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
3565 if (GET_MODE_NUNITS (mode
) != 1)
3567 if (GET_MODE_BITSIZE (mode
) > 64
3568 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
3569 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
3570 && (mode
== DFmode
|| mode
== DDmode
))))
3573 return CONSTANT_P (x
);
3580 /* Try machine-dependent ways of modifying an illegitimate address
3581 to be legitimate. If we find one, return the new, valid address.
3582 This is used from only one place: `memory_address' in explow.c.
3584 OLDX is the address as it was before break_out_memory_refs was
3585 called. In some cases it is useful to look at this to decide what
3588 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
3590 It is always safe for this function to do nothing. It exists to
3591 recognize opportunities to optimize the output.
3593 On RS/6000, first check for the sum of a register with a constant
3594 integer that is out of range. If so, generate code to add the
3595 constant with the low-order 16 bits masked to the register and force
3596 this result into another register (this can be done with `cau').
3597 Then generate an address of REG+(CONST&0xffff), allowing for the
3598 possibility of bit 16 being a one.
3600 Then check for the sum of a register and something not constant, try to
3601 load the other things into a register and return the sum. */
3604 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3605 enum machine_mode mode
)
3607 if (GET_CODE (x
) == SYMBOL_REF
)
3609 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
3611 return rs6000_legitimize_tls_address (x
, model
);
3614 if (GET_CODE (x
) == PLUS
3615 && GET_CODE (XEXP (x
, 0)) == REG
3616 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3617 && (unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000) >= 0x10000
3618 && !(SPE_VECTOR_MODE (mode
)
3619 || ALTIVEC_VECTOR_MODE (mode
)
3620 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3621 || mode
== DImode
))))
3623 HOST_WIDE_INT high_int
, low_int
;
3625 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
3626 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
3627 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
3628 GEN_INT (high_int
)), 0);
3629 return gen_rtx_PLUS (Pmode
, sum
, GEN_INT (low_int
));
3631 else if (GET_CODE (x
) == PLUS
3632 && GET_CODE (XEXP (x
, 0)) == REG
3633 && GET_CODE (XEXP (x
, 1)) != CONST_INT
3634 && GET_MODE_NUNITS (mode
) == 1
3635 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
3637 || ((mode
!= DImode
&& mode
!= DFmode
&& mode
!= DDmode
)
3638 || TARGET_E500_DOUBLE
))
3639 && (TARGET_POWERPC64
|| mode
!= DImode
)
3644 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
3645 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
3647 else if (ALTIVEC_VECTOR_MODE (mode
))
3651 /* Make sure both operands are registers. */
3652 if (GET_CODE (x
) == PLUS
)
3653 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, XEXP (x
, 0)),
3654 force_reg (Pmode
, XEXP (x
, 1)));
3656 reg
= force_reg (Pmode
, x
);
3659 else if (SPE_VECTOR_MODE (mode
)
3660 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3661 || mode
== DDmode
|| mode
== TDmode
3662 || mode
== DImode
)))
3666 /* We accept [reg + reg] and [reg + OFFSET]. */
3668 if (GET_CODE (x
) == PLUS
)
3670 rtx op1
= XEXP (x
, 0);
3671 rtx op2
= XEXP (x
, 1);
3674 op1
= force_reg (Pmode
, op1
);
3676 if (GET_CODE (op2
) != REG
3677 && (GET_CODE (op2
) != CONST_INT
3678 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))
3679 || (GET_MODE_SIZE (mode
) > 8
3680 && !SPE_CONST_OFFSET_OK (INTVAL (op2
) + 8))))
3681 op2
= force_reg (Pmode
, op2
);
3683 /* We can't always do [reg + reg] for these, because [reg +
3684 reg + offset] is not a legitimate addressing mode. */
3685 y
= gen_rtx_PLUS (Pmode
, op1
, op2
);
3687 if (GET_MODE_SIZE (mode
) > 8 && REG_P (op2
))
3688 return force_reg (Pmode
, y
);
3693 return force_reg (Pmode
, x
);
3699 && GET_CODE (x
) != CONST_INT
3700 && GET_CODE (x
) != CONST_DOUBLE
3702 && GET_MODE_NUNITS (mode
) == 1
3703 && (GET_MODE_BITSIZE (mode
) <= 32
3704 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
3705 && (mode
== DFmode
|| mode
== DDmode
))))
3707 rtx reg
= gen_reg_rtx (Pmode
);
3708 emit_insn (gen_elf_high (reg
, x
));
3709 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
3711 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
3714 && ! MACHO_DYNAMIC_NO_PIC_P
3716 && GET_CODE (x
) != CONST_INT
3717 && GET_CODE (x
) != CONST_DOUBLE
3719 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
3720 || (mode
!= DFmode
&& mode
!= DDmode
))
3724 rtx reg
= gen_reg_rtx (Pmode
);
3725 emit_insn (gen_macho_high (reg
, x
));
3726 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
3729 && constant_pool_expr_p (x
)
3730 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
3732 return create_TOC_reference (x
);
3738 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
3739 We need to emit DTP-relative relocations. */
3742 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
3747 fputs ("\t.long\t", file
);
3750 fputs (DOUBLE_INT_ASM_OP
, file
);
3755 output_addr_const (file
, x
);
3756 fputs ("@dtprel+0x8000", file
);
3759 /* Construct the SYMBOL_REF for the tls_get_addr function. */
3761 static GTY(()) rtx rs6000_tls_symbol
;
3763 rs6000_tls_get_addr (void)
3765 if (!rs6000_tls_symbol
)
3766 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
3768 return rs6000_tls_symbol
;
3771 /* Construct the SYMBOL_REF for TLS GOT references. */
3773 static GTY(()) rtx rs6000_got_symbol
;
3775 rs6000_got_sym (void)
3777 if (!rs6000_got_symbol
)
3779 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
3780 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
3781 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
3784 return rs6000_got_symbol
;
3787 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3788 this (thread-local) address. */
3791 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
3795 dest
= gen_reg_rtx (Pmode
);
3796 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
3802 tlsreg
= gen_rtx_REG (Pmode
, 13);
3803 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
3807 tlsreg
= gen_rtx_REG (Pmode
, 2);
3808 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
3812 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
3816 tmp
= gen_reg_rtx (Pmode
);
3819 tlsreg
= gen_rtx_REG (Pmode
, 13);
3820 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
3824 tlsreg
= gen_rtx_REG (Pmode
, 2);
3825 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
3829 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
3831 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
3836 rtx r3
, got
, tga
, tmp1
, tmp2
, eqv
;
3838 /* We currently use relocations like @got@tlsgd for tls, which
3839 means the linker will handle allocation of tls entries, placing
3840 them in the .got section. So use a pointer to the .got section,
3841 not one to secondary TOC sections used by 64-bit -mminimal-toc,
3842 or to secondary GOT sections used by 32-bit -fPIC. */
3844 got
= gen_rtx_REG (Pmode
, 2);
3848 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
3851 rtx gsym
= rs6000_got_sym ();
3852 got
= gen_reg_rtx (Pmode
);
3854 rs6000_emit_move (got
, gsym
, Pmode
);
3860 tmp1
= gen_reg_rtx (Pmode
);
3861 tmp2
= gen_reg_rtx (Pmode
);
3862 tmp3
= gen_reg_rtx (Pmode
);
3863 mem
= gen_const_mem (Pmode
, tmp1
);
3865 first
= emit_insn (gen_load_toc_v4_PIC_1b (gsym
));
3866 emit_move_insn (tmp1
,
3867 gen_rtx_REG (Pmode
, LR_REGNO
));
3868 emit_move_insn (tmp2
, mem
);
3869 emit_insn (gen_addsi3 (tmp3
, tmp1
, tmp2
));
3870 last
= emit_move_insn (got
, tmp3
);
3871 set_unique_reg_note (last
, REG_EQUAL
, gsym
);
3872 maybe_encapsulate_block (first
, last
, gsym
);
3877 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
3879 r3
= gen_rtx_REG (Pmode
, 3);
3881 insn
= gen_tls_gd_64 (r3
, got
, addr
);
3883 insn
= gen_tls_gd_32 (r3
, got
, addr
);
3886 tga
= gen_rtx_MEM (Pmode
, rs6000_tls_get_addr ());
3887 insn
= gen_call_value (r3
, tga
, const0_rtx
, const0_rtx
);
3888 insn
= emit_call_insn (insn
);
3889 CONST_OR_PURE_CALL_P (insn
) = 1;
3890 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
3891 insn
= get_insns ();
3893 emit_libcall_block (insn
, dest
, r3
, addr
);
3895 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
3897 r3
= gen_rtx_REG (Pmode
, 3);
3899 insn
= gen_tls_ld_64 (r3
, got
);
3901 insn
= gen_tls_ld_32 (r3
, got
);
3904 tga
= gen_rtx_MEM (Pmode
, rs6000_tls_get_addr ());
3905 insn
= gen_call_value (r3
, tga
, const0_rtx
, const0_rtx
);
3906 insn
= emit_call_insn (insn
);
3907 CONST_OR_PURE_CALL_P (insn
) = 1;
3908 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
3909 insn
= get_insns ();
3911 tmp1
= gen_reg_rtx (Pmode
);
3912 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
),
3914 emit_libcall_block (insn
, tmp1
, r3
, eqv
);
3915 if (rs6000_tls_size
== 16)
3918 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
3920 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
3922 else if (rs6000_tls_size
== 32)
3924 tmp2
= gen_reg_rtx (Pmode
);
3926 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
3928 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
3931 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
3933 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
3937 tmp2
= gen_reg_rtx (Pmode
);
3939 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
3941 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
3943 insn
= gen_rtx_SET (Pmode
, dest
,
3944 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
3950 /* IE, or 64-bit offset LE. */
3951 tmp2
= gen_reg_rtx (Pmode
);
3953 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
3955 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
3958 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
3960 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
3968 /* Return 1 if X contains a thread-local symbol. */
3971 rs6000_tls_referenced_p (rtx x
)
3973 if (! TARGET_HAVE_TLS
)
3976 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
3979 /* Return 1 if *X is a thread-local symbol. This is the same as
3980 rs6000_tls_symbol_ref except for the type of the unused argument. */
3983 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
3985 return RS6000_SYMBOL_REF_TLS_P (*x
);
3988 /* The convention appears to be to define this wherever it is used.
3989 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
3990 is now used here. */
3991 #ifndef REG_MODE_OK_FOR_BASE_P
3992 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
3995 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
3996 replace the input X, or the original X if no replacement is called for.
3997 The output parameter *WIN is 1 if the calling macro should goto WIN,
4000 For RS/6000, we wish to handle large displacements off a base
4001 register by splitting the addend across an addiu/addis and the mem insn.
4002 This cuts number of extra insns needed from 3 to 1.
4004 On Darwin, we use this to generate code for floating point constants.
4005 A movsf_low is generated so we wind up with 2 instructions rather than 3.
4006 The Darwin code is inside #if TARGET_MACHO because only then is
4007 machopic_function_base_name() defined. */
4009 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
4010 int opnum
, int type
,
4011 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
4013 /* We must recognize output that we have already generated ourselves. */
4014 if (GET_CODE (x
) == PLUS
4015 && GET_CODE (XEXP (x
, 0)) == PLUS
4016 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
4017 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
4018 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
4020 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4021 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
4022 opnum
, (enum reload_type
)type
);
4028 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
4029 && GET_CODE (x
) == LO_SUM
4030 && GET_CODE (XEXP (x
, 0)) == PLUS
4031 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
4032 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
4033 && GET_CODE (XEXP (XEXP (XEXP (x
, 0), 1), 0)) == CONST
4034 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
4035 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == MINUS
4036 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 0)) == SYMBOL_REF
4037 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 1)) == SYMBOL_REF
)
4039 /* Result of previous invocation of this function on Darwin
4040 floating point constant. */
4041 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4042 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
4043 opnum
, (enum reload_type
)type
);
4049 /* Force ld/std non-word aligned offset into base register by wrapping
4051 if (GET_CODE (x
) == PLUS
4052 && GET_CODE (XEXP (x
, 0)) == REG
4053 && REGNO (XEXP (x
, 0)) < 32
4054 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
4055 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4056 && (INTVAL (XEXP (x
, 1)) & 3) != 0
4057 && !ALTIVEC_VECTOR_MODE (mode
)
4058 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
4059 && TARGET_POWERPC64
)
4061 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
4062 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4063 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
4064 opnum
, (enum reload_type
) type
);
4069 if (GET_CODE (x
) == PLUS
4070 && GET_CODE (XEXP (x
, 0)) == REG
4071 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
4072 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
4073 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4074 && !SPE_VECTOR_MODE (mode
)
4075 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
4076 || mode
== DDmode
|| mode
== TDmode
4078 && !ALTIVEC_VECTOR_MODE (mode
))
4080 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
4081 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
4083 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
4085 /* Check for 32-bit overflow. */
4086 if (high
+ low
!= val
)
4092 /* Reload the high part into a base reg; leave the low part
4093 in the mem directly. */
4095 x
= gen_rtx_PLUS (GET_MODE (x
),
4096 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
4100 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4101 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
4102 opnum
, (enum reload_type
)type
);
4107 if (GET_CODE (x
) == SYMBOL_REF
4108 && !ALTIVEC_VECTOR_MODE (mode
)
4109 && !SPE_VECTOR_MODE (mode
)
4111 && DEFAULT_ABI
== ABI_DARWIN
4112 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
4114 && DEFAULT_ABI
== ABI_V4
4117 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
4118 The same goes for DImode without 64-bit gprs and DFmode and DDmode
4122 && (mode
!= DImode
|| TARGET_POWERPC64
)
4123 && ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_POWERPC64
4124 || (TARGET_FPRS
&& TARGET_HARD_FLOAT
)))
4129 rtx offset
= gen_rtx_CONST (Pmode
,
4130 gen_rtx_MINUS (Pmode
, x
,
4131 machopic_function_base_sym ()));
4132 x
= gen_rtx_LO_SUM (GET_MODE (x
),
4133 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
4134 gen_rtx_HIGH (Pmode
, offset
)), offset
);
4138 x
= gen_rtx_LO_SUM (GET_MODE (x
),
4139 gen_rtx_HIGH (Pmode
, x
), x
);
4141 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
4142 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
4143 opnum
, (enum reload_type
)type
);
4148 /* Reload an offset address wrapped by an AND that represents the
4149 masking of the lower bits. Strip the outer AND and let reload
4150 convert the offset address into an indirect address. */
4152 && ALTIVEC_VECTOR_MODE (mode
)
4153 && GET_CODE (x
) == AND
4154 && GET_CODE (XEXP (x
, 0)) == PLUS
4155 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
4156 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
4157 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4158 && INTVAL (XEXP (x
, 1)) == -16)
4166 && constant_pool_expr_p (x
)
4167 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
4169 x
= create_TOC_reference (x
);
4177 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
4178 that is a valid memory address for an instruction.
4179 The MODE argument is the machine mode for the MEM expression
4180 that wants to use this address.
4182 On the RS/6000, there are four valid address: a SYMBOL_REF that
4183 refers to a constant pool entry of an address (or the sum of it
4184 plus a constant), a short (16-bit signed) constant plus a register,
4185 the sum of two registers, or a register indirect, possibly with an
4186 auto-increment. For DFmode, DDmode and DImode with a constant plus
4187 register, we must ensure that both words are addressable or PowerPC64
4188 with offset word aligned.
4190 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
4191 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
4192 because adjacent memory cells are accessed by adding word-sized offsets
4193 during assembly output. */
4195 rs6000_legitimate_address (enum machine_mode mode
, rtx x
, int reg_ok_strict
)
4197 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
4199 && ALTIVEC_VECTOR_MODE (mode
)
4200 && GET_CODE (x
) == AND
4201 && GET_CODE (XEXP (x
, 1)) == CONST_INT
4202 && INTVAL (XEXP (x
, 1)) == -16)
4205 if (RS6000_SYMBOL_REF_TLS_P (x
))
4207 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
4209 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
4210 && !ALTIVEC_VECTOR_MODE (mode
)
4211 && !SPE_VECTOR_MODE (mode
)
4214 /* Restrict addressing for DI because of our SUBREG hackery. */
4215 && !(TARGET_E500_DOUBLE
4216 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
4218 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
4220 if (legitimate_small_data_p (mode
, x
))
4222 if (legitimate_constant_pool_address_p (x
))
4224 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
4226 && GET_CODE (x
) == PLUS
4227 && GET_CODE (XEXP (x
, 0)) == REG
4228 && (XEXP (x
, 0) == virtual_stack_vars_rtx
4229 || XEXP (x
, 0) == arg_pointer_rtx
)
4230 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
4232 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
4237 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
4239 || ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_E500_DOUBLE
))
4240 && (TARGET_POWERPC64
|| mode
!= DImode
)
4241 && legitimate_indexed_address_p (x
, reg_ok_strict
))
4243 if (GET_CODE (x
) == PRE_MODIFY
4247 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
4249 || ((mode
!= DFmode
&& mode
!= DDmode
) || TARGET_E500_DOUBLE
))
4250 && (TARGET_POWERPC64
|| mode
!= DImode
)
4251 && !ALTIVEC_VECTOR_MODE (mode
)
4252 && !SPE_VECTOR_MODE (mode
)
4253 /* Restrict addressing for DI because of our SUBREG hackery. */
4254 && !(TARGET_E500_DOUBLE
4255 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DImode
))
4257 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
)
4258 && (rs6000_legitimate_offset_address_p (mode
, XEXP (x
, 1), reg_ok_strict
)
4259 || legitimate_indexed_address_p (XEXP (x
, 1), reg_ok_strict
))
4260 && rtx_equal_p (XEXP (XEXP (x
, 1), 0), XEXP (x
, 0)))
4262 if (legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
4267 /* Go to LABEL if ADDR (a legitimate address expression)
4268 has an effect that depends on the machine mode it is used for.
4270 On the RS/6000 this is true of all integral offsets (since AltiVec
4271 modes don't allow them) or is a pre-increment or decrement.
4273 ??? Except that due to conceptual problems in offsettable_address_p
4274 we can't really report the problems of integral offsets. So leave
4275 this assuming that the adjustable offset must be valid for the
4276 sub-words of a TFmode operand, which is what we had before. */
4279 rs6000_mode_dependent_address (rtx addr
)
4281 switch (GET_CODE (addr
))
4284 if (GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
4286 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
4287 return val
+ 12 + 0x8000 >= 0x10000;
4297 return TARGET_UPDATE
;
4306 /* More elaborate version of recog's offsettable_memref_p predicate
4307 that works around the ??? note of rs6000_mode_dependent_address.
4308 In particular it accepts
4310 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
4312 in 32-bit mode, that the recog predicate rejects. */
4315 rs6000_offsettable_memref_p (rtx op
)
4320 /* First mimic offsettable_memref_p. */
4321 if (offsettable_address_p (1, GET_MODE (op
), XEXP (op
, 0)))
4324 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
4325 the latter predicate knows nothing about the mode of the memory
4326 reference and, therefore, assumes that it is the largest supported
4327 mode (TFmode). As a consequence, legitimate offsettable memory
4328 references are rejected. rs6000_legitimate_offset_address_p contains
4329 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
4330 return rs6000_legitimate_offset_address_p (GET_MODE (op
), XEXP (op
, 0), 1);
4333 /* Return number of consecutive hard regs needed starting at reg REGNO
4334 to hold something of mode MODE.
4335 This is ordinarily the length in words of a value of mode MODE
4336 but can be less for certain modes in special long registers.
4338 For the SPE, GPRs are 64 bits but only 32 bits are visible in
4339 scalar instructions. The upper 32 bits are only available to the
4342 POWER and PowerPC GPRs hold 32 bits worth;
4343 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
4346 rs6000_hard_regno_nregs (int regno
, enum machine_mode mode
)
4348 if (FP_REGNO_P (regno
))
4349 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
4351 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
4352 return (GET_MODE_SIZE (mode
) + UNITS_PER_SPE_WORD
- 1) / UNITS_PER_SPE_WORD
;
4354 if (ALTIVEC_REGNO_P (regno
))
4356 (GET_MODE_SIZE (mode
) + UNITS_PER_ALTIVEC_WORD
- 1) / UNITS_PER_ALTIVEC_WORD
;
4358 /* The value returned for SCmode in the E500 double case is 2 for
4359 ABI compatibility; storing an SCmode value in a single register
4360 would require function_arg and rs6000_spe_function_arg to handle
4361 SCmode so as to pass the value correctly in a pair of
4363 if (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
) && mode
!= SCmode
)
4364 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
4366 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
4369 /* Change register usage conditional on target flags. */
4371 rs6000_conditional_register_usage (void)
4375 /* Set MQ register fixed (already call_used) if not POWER
4376 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
4381 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
4383 fixed_regs
[13] = call_used_regs
[13]
4384 = call_really_used_regs
[13] = 1;
4386 /* Conditionally disable FPRs. */
4387 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
4388 for (i
= 32; i
< 64; i
++)
4389 fixed_regs
[i
] = call_used_regs
[i
]
4390 = call_really_used_regs
[i
] = 1;
4392 /* The TOC register is not killed across calls in a way that is
4393 visible to the compiler. */
4394 if (DEFAULT_ABI
== ABI_AIX
)
4395 call_really_used_regs
[2] = 0;
4397 if (DEFAULT_ABI
== ABI_V4
4398 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
4400 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4402 if (DEFAULT_ABI
== ABI_V4
4403 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
4405 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4406 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4407 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4409 if (DEFAULT_ABI
== ABI_DARWIN
4410 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
4411 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4412 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4413 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4415 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
4416 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
4417 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
4421 global_regs
[SPEFSCR_REGNO
] = 1;
4422 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
4423 registers in prologues and epilogues. We no longer use r14
4424 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
4425 pool for link-compatibility with older versions of GCC. Once
4426 "old" code has died out, we can return r14 to the allocation
4429 = call_used_regs
[14]
4430 = call_really_used_regs
[14] = 1;
4433 if (!TARGET_ALTIVEC
)
4435 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
4436 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4437 call_really_used_regs
[VRSAVE_REGNO
] = 1;
4441 global_regs
[VSCR_REGNO
] = 1;
4443 if (TARGET_ALTIVEC_ABI
)
4445 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
4446 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4448 /* AIX reserves VR20:31 in non-extended ABI mode. */
4450 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
< FIRST_ALTIVEC_REGNO
+ 32; ++i
)
4451 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4455 /* Try to output insns to set TARGET equal to the constant C if it can
4456 be done in less than N insns. Do all computations in MODE.
4457 Returns the place where the output has been placed if it can be
4458 done and the insns have been emitted. If it would take more than N
4459 insns, zero is returned and no insns and emitted. */
4462 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
4463 rtx source
, int n ATTRIBUTE_UNUSED
)
4465 rtx result
, insn
, set
;
4466 HOST_WIDE_INT c0
, c1
;
4473 dest
= gen_reg_rtx (mode
);
4474 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
4478 result
= !can_create_pseudo_p () ? dest
: gen_reg_rtx (SImode
);
4480 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (result
),
4481 GEN_INT (INTVAL (source
)
4482 & (~ (HOST_WIDE_INT
) 0xffff))));
4483 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
4484 gen_rtx_IOR (SImode
, copy_rtx (result
),
4485 GEN_INT (INTVAL (source
) & 0xffff))));
4490 switch (GET_CODE (source
))
4493 c0
= INTVAL (source
);
4498 #if HOST_BITS_PER_WIDE_INT >= 64
4499 c0
= CONST_DOUBLE_LOW (source
);
4502 c0
= CONST_DOUBLE_LOW (source
);
4503 c1
= CONST_DOUBLE_HIGH (source
);
4511 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
4518 insn
= get_last_insn ();
4519 set
= single_set (insn
);
4520 if (! CONSTANT_P (SET_SRC (set
)))
4521 set_unique_reg_note (insn
, REG_EQUAL
, source
);
4526 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
4527 fall back to a straight forward decomposition. We do this to avoid
4528 exponential run times encountered when looking for longer sequences
4529 with rs6000_emit_set_const. */
4531 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
4533 if (!TARGET_POWERPC64
)
4535 rtx operand1
, operand2
;
4537 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
4539 operand2
= operand_subword_force (copy_rtx (dest
), WORDS_BIG_ENDIAN
!= 0,
4541 emit_move_insn (operand1
, GEN_INT (c1
));
4542 emit_move_insn (operand2
, GEN_INT (c2
));
4546 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
4549 ud2
= (c1
& 0xffff0000) >> 16;
4550 #if HOST_BITS_PER_WIDE_INT >= 64
4554 ud4
= (c2
& 0xffff0000) >> 16;
4556 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
4557 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
4560 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
4562 emit_move_insn (dest
, GEN_INT (ud1
));
4565 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
4566 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
4569 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
4572 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
4574 emit_move_insn (copy_rtx (dest
),
4575 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4578 else if ((ud4
== 0xffff && (ud3
& 0x8000))
4579 || (ud4
== 0 && ! (ud3
& 0x8000)))
4582 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
4585 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
4588 emit_move_insn (copy_rtx (dest
),
4589 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4591 emit_move_insn (copy_rtx (dest
),
4592 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
4595 emit_move_insn (copy_rtx (dest
),
4596 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4602 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
4605 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
4608 emit_move_insn (copy_rtx (dest
),
4609 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4612 emit_move_insn (copy_rtx (dest
),
4613 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
4616 emit_move_insn (copy_rtx (dest
),
4617 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4618 GEN_INT (ud2
<< 16)));
4620 emit_move_insn (copy_rtx (dest
),
4621 gen_rtx_IOR (DImode
, copy_rtx (dest
), GEN_INT (ud1
)));
4627 /* Helper for the following. Get rid of [r+r] memory refs
4628 in cases where it won't work (TImode, TFmode, TDmode). */
4631 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
4633 if (GET_CODE (operands
[0]) == MEM
4634 && GET_CODE (XEXP (operands
[0], 0)) != REG
4635 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0))
4636 && ! reload_in_progress
)
4638 = replace_equiv_address (operands
[0],
4639 copy_addr_to_reg (XEXP (operands
[0], 0)));
4641 if (GET_CODE (operands
[1]) == MEM
4642 && GET_CODE (XEXP (operands
[1], 0)) != REG
4643 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0))
4644 && ! reload_in_progress
)
4646 = replace_equiv_address (operands
[1],
4647 copy_addr_to_reg (XEXP (operands
[1], 0)));
4650 /* Emit a move from SOURCE to DEST in mode MODE. */
4652 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
4656 operands
[1] = source
;
4658 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
4659 if (GET_CODE (operands
[1]) == CONST_DOUBLE
4660 && ! FLOAT_MODE_P (mode
)
4661 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
4663 /* FIXME. This should never happen. */
4664 /* Since it seems that it does, do the safe thing and convert
4666 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
4668 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
4669 || FLOAT_MODE_P (mode
)
4670 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
4671 || CONST_DOUBLE_LOW (operands
[1]) < 0)
4672 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
4673 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
4675 /* Check if GCC is setting up a block move that will end up using FP
4676 registers as temporaries. We must make sure this is acceptable. */
4677 if (GET_CODE (operands
[0]) == MEM
4678 && GET_CODE (operands
[1]) == MEM
4680 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
4681 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
4682 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
4683 ? 32 : MEM_ALIGN (operands
[0])))
4684 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
4686 : MEM_ALIGN (operands
[1]))))
4687 && ! MEM_VOLATILE_P (operands
[0])
4688 && ! MEM_VOLATILE_P (operands
[1]))
4690 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
4691 adjust_address (operands
[1], SImode
, 0));
4692 emit_move_insn (adjust_address (copy_rtx (operands
[0]), SImode
, 4),
4693 adjust_address (copy_rtx (operands
[1]), SImode
, 4));
4697 if (can_create_pseudo_p () && GET_CODE (operands
[0]) == MEM
4698 && !gpc_reg_operand (operands
[1], mode
))
4699 operands
[1] = force_reg (mode
, operands
[1]);
4701 if (mode
== SFmode
&& ! TARGET_POWERPC
4702 && TARGET_HARD_FLOAT
&& TARGET_FPRS
4703 && GET_CODE (operands
[0]) == MEM
)
4707 if (reload_in_progress
|| reload_completed
)
4708 regnum
= true_regnum (operands
[1]);
4709 else if (GET_CODE (operands
[1]) == REG
)
4710 regnum
= REGNO (operands
[1]);
4714 /* If operands[1] is a register, on POWER it may have
4715 double-precision data in it, so truncate it to single
4717 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
4720 newreg
= (!can_create_pseudo_p () ? copy_rtx (operands
[1])
4721 : gen_reg_rtx (mode
));
4722 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
4723 operands
[1] = newreg
;
4727 /* Recognize the case where operand[1] is a reference to thread-local
4728 data and load its address to a register. */
4729 if (rs6000_tls_referenced_p (operands
[1]))
4731 enum tls_model model
;
4732 rtx tmp
= operands
[1];
4735 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
4737 addend
= XEXP (XEXP (tmp
, 0), 1);
4738 tmp
= XEXP (XEXP (tmp
, 0), 0);
4741 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
4742 model
= SYMBOL_REF_TLS_MODEL (tmp
);
4743 gcc_assert (model
!= 0);
4745 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
4748 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
4749 tmp
= force_operand (tmp
, operands
[0]);
4754 /* Handle the case where reload calls us with an invalid address. */
4755 if (reload_in_progress
&& mode
== Pmode
4756 && (! general_operand (operands
[1], mode
)
4757 || ! nonimmediate_operand (operands
[0], mode
)))
4760 /* 128-bit constant floating-point values on Darwin should really be
4761 loaded as two parts. */
4762 if (!TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
4763 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
4765 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
4766 know how to get a DFmode SUBREG of a TFmode. */
4767 enum machine_mode imode
= (TARGET_E500_DOUBLE
? DFmode
: DImode
);
4768 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
, 0),
4769 simplify_gen_subreg (imode
, operands
[1], mode
, 0),
4771 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
,
4772 GET_MODE_SIZE (imode
)),
4773 simplify_gen_subreg (imode
, operands
[1], mode
,
4774 GET_MODE_SIZE (imode
)),
4779 if (reload_in_progress
&& cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
4780 cfun
->machine
->sdmode_stack_slot
=
4781 eliminate_regs (cfun
->machine
->sdmode_stack_slot
, VOIDmode
, NULL_RTX
);
4783 if (reload_in_progress
4785 && MEM_P (operands
[0])
4786 && rtx_equal_p (operands
[0], cfun
->machine
->sdmode_stack_slot
)
4787 && REG_P (operands
[1]))
4789 if (FP_REGNO_P (REGNO (operands
[1])))
4791 rtx mem
= adjust_address_nv (operands
[0], DDmode
, 0);
4792 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
4793 emit_insn (gen_movsd_store (mem
, operands
[1]));
4795 else if (INT_REGNO_P (REGNO (operands
[1])))
4797 rtx mem
= adjust_address_nv (operands
[0], mode
, 4);
4798 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
4799 emit_insn (gen_movsd_hardfloat (mem
, operands
[1]));
4805 if (reload_in_progress
4807 && REG_P (operands
[0])
4808 && MEM_P (operands
[1])
4809 && rtx_equal_p (operands
[1], cfun
->machine
->sdmode_stack_slot
))
4811 if (FP_REGNO_P (REGNO (operands
[0])))
4813 rtx mem
= adjust_address_nv (operands
[1], DDmode
, 0);
4814 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
4815 emit_insn (gen_movsd_load (operands
[0], mem
));
4817 else if (INT_REGNO_P (REGNO (operands
[0])))
4819 rtx mem
= adjust_address_nv (operands
[1], mode
, 4);
4820 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
4821 emit_insn (gen_movsd_hardfloat (operands
[0], mem
));
4828 /* FIXME: In the long term, this switch statement should go away
4829 and be replaced by a sequence of tests based on things like
4835 if (CONSTANT_P (operands
[1])
4836 && GET_CODE (operands
[1]) != CONST_INT
)
4837 operands
[1] = force_const_mem (mode
, operands
[1]);
4842 rs6000_eliminate_indexed_memrefs (operands
);
4849 if (CONSTANT_P (operands
[1])
4850 && ! easy_fp_constant (operands
[1], mode
))
4851 operands
[1] = force_const_mem (mode
, operands
[1]);
4862 if (CONSTANT_P (operands
[1])
4863 && !easy_vector_constant (operands
[1], mode
))
4864 operands
[1] = force_const_mem (mode
, operands
[1]);
4869 /* Use default pattern for address of ELF small data */
4872 && DEFAULT_ABI
== ABI_V4
4873 && (GET_CODE (operands
[1]) == SYMBOL_REF
4874 || GET_CODE (operands
[1]) == CONST
)
4875 && small_data_operand (operands
[1], mode
))
4877 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
4881 if (DEFAULT_ABI
== ABI_V4
4882 && mode
== Pmode
&& mode
== SImode
4883 && flag_pic
== 1 && got_operand (operands
[1], mode
))
4885 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
4889 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
4893 && CONSTANT_P (operands
[1])
4894 && GET_CODE (operands
[1]) != HIGH
4895 && GET_CODE (operands
[1]) != CONST_INT
)
4897 rtx target
= (!can_create_pseudo_p ()
4899 : gen_reg_rtx (mode
));
4901 /* If this is a function address on -mcall-aixdesc,
4902 convert it to the address of the descriptor. */
4903 if (DEFAULT_ABI
== ABI_AIX
4904 && GET_CODE (operands
[1]) == SYMBOL_REF
4905 && XSTR (operands
[1], 0)[0] == '.')
4907 const char *name
= XSTR (operands
[1], 0);
4909 while (*name
== '.')
4911 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
4912 CONSTANT_POOL_ADDRESS_P (new_ref
)
4913 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
4914 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
4915 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
4916 SYMBOL_REF_DATA (new_ref
) = SYMBOL_REF_DATA (operands
[1]);
4917 operands
[1] = new_ref
;
4920 if (DEFAULT_ABI
== ABI_DARWIN
)
4923 if (MACHO_DYNAMIC_NO_PIC_P
)
4925 /* Take care of any required data indirection. */
4926 operands
[1] = rs6000_machopic_legitimize_pic_address (
4927 operands
[1], mode
, operands
[0]);
4928 if (operands
[0] != operands
[1])
4929 emit_insn (gen_rtx_SET (VOIDmode
,
4930 operands
[0], operands
[1]));
4934 emit_insn (gen_macho_high (target
, operands
[1]));
4935 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
4939 emit_insn (gen_elf_high (target
, operands
[1]));
4940 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
4944 /* If this is a SYMBOL_REF that refers to a constant pool entry,
4945 and we have put it in the TOC, we just need to make a TOC-relative
4948 && GET_CODE (operands
[1]) == SYMBOL_REF
4949 && constant_pool_expr_p (operands
[1])
4950 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
4951 get_pool_mode (operands
[1])))
4953 operands
[1] = create_TOC_reference (operands
[1]);
4955 else if (mode
== Pmode
4956 && CONSTANT_P (operands
[1])
4957 && ((GET_CODE (operands
[1]) != CONST_INT
4958 && ! easy_fp_constant (operands
[1], mode
))
4959 || (GET_CODE (operands
[1]) == CONST_INT
4960 && num_insns_constant (operands
[1], mode
) > 2)
4961 || (GET_CODE (operands
[0]) == REG
4962 && FP_REGNO_P (REGNO (operands
[0]))))
4963 && GET_CODE (operands
[1]) != HIGH
4964 && ! legitimate_constant_pool_address_p (operands
[1])
4965 && ! toc_relative_expr_p (operands
[1]))
4967 /* Emit a USE operation so that the constant isn't deleted if
4968 expensive optimizations are turned on because nobody
4969 references it. This should only be done for operands that
4970 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
4971 This should not be done for operands that contain LABEL_REFs.
4972 For now, we just handle the obvious case. */
4973 if (GET_CODE (operands
[1]) != LABEL_REF
)
4974 emit_insn (gen_rtx_USE (VOIDmode
, operands
[1]));
4977 /* Darwin uses a special PIC legitimizer. */
4978 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
4981 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
4983 if (operands
[0] != operands
[1])
4984 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
4989 /* If we are to limit the number of things we put in the TOC and
4990 this is a symbol plus a constant we can add in one insn,
4991 just put the symbol in the TOC and add the constant. Don't do
4992 this if reload is in progress. */
4993 if (GET_CODE (operands
[1]) == CONST
4994 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
4995 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
4996 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
4997 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
4998 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
4999 && ! side_effects_p (operands
[0]))
5002 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
5003 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
5005 sym
= force_reg (mode
, sym
);
5007 emit_insn (gen_addsi3 (operands
[0], sym
, other
));
5009 emit_insn (gen_adddi3 (operands
[0], sym
, other
));
5013 operands
[1] = force_const_mem (mode
, operands
[1]);
5016 && constant_pool_expr_p (XEXP (operands
[1], 0))
5017 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
5018 get_pool_constant (XEXP (operands
[1], 0)),
5019 get_pool_mode (XEXP (operands
[1], 0))))
5022 = gen_const_mem (mode
,
5023 create_TOC_reference (XEXP (operands
[1], 0)));
5024 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
5030 rs6000_eliminate_indexed_memrefs (operands
);
5034 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
5036 gen_rtx_SET (VOIDmode
,
5037 operands
[0], operands
[1]),
5038 gen_rtx_CLOBBER (VOIDmode
,
5039 gen_rtx_SCRATCH (SImode
)))));
5048 /* Above, we may have called force_const_mem which may have returned
5049 an invalid address. If we can, fix this up; otherwise, reload will
5050 have to deal with it. */
5051 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
5052 operands
[1] = validize_mem (operands
[1]);
5055 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
5058 /* Nonzero if we can use a floating-point register to pass this arg. */
5059 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
5060 (SCALAR_FLOAT_MODE_P (MODE) \
5061 && (CUM)->fregno <= FP_ARG_MAX_REG \
5062 && TARGET_HARD_FLOAT && TARGET_FPRS)
5064 /* Nonzero if we can use an AltiVec register to pass this arg. */
5065 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
5066 (ALTIVEC_VECTOR_MODE (MODE) \
5067 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
5068 && TARGET_ALTIVEC_ABI \
5071 /* Return a nonzero value to say to return the function value in
5072 memory, just as large structures are always returned. TYPE will be
5073 the data type of the value, and FNTYPE will be the type of the
5074 function doing the returning, or @code{NULL} for libcalls.
5076 The AIX ABI for the RS/6000 specifies that all structures are
5077 returned in memory. The Darwin ABI does the same. The SVR4 ABI
5078 specifies that structures <= 8 bytes are returned in r3/r4, but a
5079 draft put them in memory, and GCC used to implement the draft
5080 instead of the final standard. Therefore, aix_struct_return
5081 controls this instead of DEFAULT_ABI; V.4 targets needing backward
5082 compatibility can change DRAFT_V4_STRUCT_RET to override the
5083 default, and -m switches get the final word. See
5084 rs6000_override_options for more details.
5086 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
5087 long double support is enabled. These values are returned in memory.
5089 int_size_in_bytes returns -1 for variable size objects, which go in
5090 memory always. The cast to unsigned makes -1 > 8. */
5093 rs6000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
5095 /* In the darwin64 abi, try to use registers for larger structs
5097 if (rs6000_darwin64_abi
5098 && TREE_CODE (type
) == RECORD_TYPE
5099 && int_size_in_bytes (type
) > 0)
5101 CUMULATIVE_ARGS valcum
;
5105 valcum
.fregno
= FP_ARG_MIN_REG
;
5106 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
5107 /* Do a trial code generation as if this were going to be passed
5108 as an argument; if any part goes in memory, we return NULL. */
5109 valret
= rs6000_darwin64_record_arg (&valcum
, type
, 1, true);
5112 /* Otherwise fall through to more conventional ABI rules. */
5115 if (AGGREGATE_TYPE_P (type
)
5116 && (aix_struct_return
5117 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
5120 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5121 modes only exist for GCC vector types if -maltivec. */
5122 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
5123 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
5126 /* Return synthetic vectors in memory. */
5127 if (TREE_CODE (type
) == VECTOR_TYPE
5128 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
5130 static bool warned_for_return_big_vectors
= false;
5131 if (!warned_for_return_big_vectors
)
5133 warning (0, "GCC vector returned by reference: "
5134 "non-standard ABI extension with no compatibility guarantee");
5135 warned_for_return_big_vectors
= true;
5140 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& TYPE_MODE (type
) == TFmode
)
5146 /* Initialize a variable CUM of type CUMULATIVE_ARGS
5147 for a call to a function whose data type is FNTYPE.
5148 For a library call, FNTYPE is 0.
5150 For incoming args we set the number of arguments in the prototype large
5151 so we never return a PARALLEL. */
5154 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
5155 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
5156 int libcall
, int n_named_args
)
5158 static CUMULATIVE_ARGS zero_cumulative
;
5160 *cum
= zero_cumulative
;
5162 cum
->fregno
= FP_ARG_MIN_REG
;
5163 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
5164 cum
->prototype
= (fntype
&& TYPE_ARG_TYPES (fntype
));
5165 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
5166 ? CALL_LIBCALL
: CALL_NORMAL
);
5167 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
5168 cum
->stdarg
= fntype
5169 && (TYPE_ARG_TYPES (fntype
) != 0
5170 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
5171 != void_type_node
));
5173 cum
->nargs_prototype
= 0;
5174 if (incoming
|| cum
->prototype
)
5175 cum
->nargs_prototype
= n_named_args
;
5177 /* Check for a longcall attribute. */
5178 if ((!fntype
&& rs6000_default_long_calls
)
5180 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
5181 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
5182 cum
->call_cookie
|= CALL_LONG
;
5184 if (TARGET_DEBUG_ARG
)
5186 fprintf (stderr
, "\ninit_cumulative_args:");
5189 tree ret_type
= TREE_TYPE (fntype
);
5190 fprintf (stderr
, " ret code = %s,",
5191 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
5194 if (cum
->call_cookie
& CALL_LONG
)
5195 fprintf (stderr
, " longcall,");
5197 fprintf (stderr
, " proto = %d, nargs = %d\n",
5198 cum
->prototype
, cum
->nargs_prototype
);
5203 && TARGET_ALTIVEC_ABI
5204 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
5206 error ("cannot return value in vector register because"
5207 " altivec instructions are disabled, use -maltivec"
5212 /* Return true if TYPE must be passed on the stack and not in registers. */
5215 rs6000_must_pass_in_stack (enum machine_mode mode
, const_tree type
)
5217 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
5218 return must_pass_in_stack_var_size (mode
, type
);
5220 return must_pass_in_stack_var_size_or_pad (mode
, type
);
5223 /* If defined, a C expression which determines whether, and in which
5224 direction, to pad out an argument with extra space. The value
5225 should be of type `enum direction': either `upward' to pad above
5226 the argument, `downward' to pad below, or `none' to inhibit
5229 For the AIX ABI structs are always stored left shifted in their
5233 function_arg_padding (enum machine_mode mode
, const_tree type
)
5235 #ifndef AGGREGATE_PADDING_FIXED
5236 #define AGGREGATE_PADDING_FIXED 0
5238 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
5239 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
5242 if (!AGGREGATE_PADDING_FIXED
)
5244 /* GCC used to pass structures of the same size as integer types as
5245 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
5246 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
5247 passed padded downward, except that -mstrict-align further
5248 muddied the water in that multi-component structures of 2 and 4
5249 bytes in size were passed padded upward.
5251 The following arranges for best compatibility with previous
5252 versions of gcc, but removes the -mstrict-align dependency. */
5253 if (BYTES_BIG_ENDIAN
)
5255 HOST_WIDE_INT size
= 0;
5257 if (mode
== BLKmode
)
5259 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
5260 size
= int_size_in_bytes (type
);
5263 size
= GET_MODE_SIZE (mode
);
5265 if (size
== 1 || size
== 2 || size
== 4)
5271 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
5273 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
5277 /* Fall back to the default. */
5278 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
5281 /* If defined, a C expression that gives the alignment boundary, in bits,
5282 of an argument with the specified mode and type. If it is not defined,
5283 PARM_BOUNDARY is used for all arguments.
5285 V.4 wants long longs and doubles to be double word aligned. Just
5286 testing the mode size is a boneheaded way to do this as it means
5287 that other types such as complex int are also double word aligned.
5288 However, we're stuck with this because changing the ABI might break
5289 existing library interfaces.
5291 Doubleword align SPE vectors.
5292 Quadword align Altivec vectors.
5293 Quadword align large synthetic vector types. */
5296 function_arg_boundary (enum machine_mode mode
, tree type
)
5298 if (DEFAULT_ABI
== ABI_V4
5299 && (GET_MODE_SIZE (mode
) == 8
5300 || (TARGET_HARD_FLOAT
5302 && (mode
== TFmode
|| mode
== TDmode
))))
5304 else if (SPE_VECTOR_MODE (mode
)
5305 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5306 && int_size_in_bytes (type
) >= 8
5307 && int_size_in_bytes (type
) < 16))
5309 else if (ALTIVEC_VECTOR_MODE (mode
)
5310 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5311 && int_size_in_bytes (type
) >= 16))
5313 else if (rs6000_darwin64_abi
&& mode
== BLKmode
5314 && type
&& TYPE_ALIGN (type
) > 64)
5317 return PARM_BOUNDARY
;
5320 /* For a function parm of MODE and TYPE, return the starting word in
5321 the parameter area. NWORDS of the parameter area are already used. */
5324 rs6000_parm_start (enum machine_mode mode
, tree type
, unsigned int nwords
)
5327 unsigned int parm_offset
;
5329 align
= function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
5330 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
5331 return nwords
+ (-(parm_offset
+ nwords
) & align
);
5334 /* Compute the size (in words) of a function argument. */
5336 static unsigned long
5337 rs6000_arg_size (enum machine_mode mode
, tree type
)
5341 if (mode
!= BLKmode
)
5342 size
= GET_MODE_SIZE (mode
);
5344 size
= int_size_in_bytes (type
);
5347 return (size
+ 3) >> 2;
5349 return (size
+ 7) >> 3;
5352 /* Use this to flush pending int fields. */
5355 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
5356 HOST_WIDE_INT bitpos
)
5358 unsigned int startbit
, endbit
;
5359 int intregs
, intoffset
;
5360 enum machine_mode mode
;
5362 if (cum
->intoffset
== -1)
5365 intoffset
= cum
->intoffset
;
5366 cum
->intoffset
= -1;
5368 if (intoffset
% BITS_PER_WORD
!= 0)
5370 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
5372 if (mode
== BLKmode
)
5374 /* We couldn't find an appropriate mode, which happens,
5375 e.g., in packed structs when there are 3 bytes to load.
5376 Back intoffset back to the beginning of the word in this
5378 intoffset
= intoffset
& -BITS_PER_WORD
;
5382 startbit
= intoffset
& -BITS_PER_WORD
;
5383 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
5384 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
5385 cum
->words
+= intregs
;
5388 /* The darwin64 ABI calls for us to recurse down through structs,
5389 looking for elements passed in registers. Unfortunately, we have
5390 to track int register count here also because of misalignments
5391 in powerpc alignment mode. */
5394 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
5396 HOST_WIDE_INT startbitpos
)
5400 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
5401 if (TREE_CODE (f
) == FIELD_DECL
)
5403 HOST_WIDE_INT bitpos
= startbitpos
;
5404 tree ftype
= TREE_TYPE (f
);
5405 enum machine_mode mode
;
5406 if (ftype
== error_mark_node
)
5408 mode
= TYPE_MODE (ftype
);
5410 if (DECL_SIZE (f
) != 0
5411 && host_integerp (bit_position (f
), 1))
5412 bitpos
+= int_bit_position (f
);
5414 /* ??? FIXME: else assume zero offset. */
5416 if (TREE_CODE (ftype
) == RECORD_TYPE
)
5417 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
5418 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
5420 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
5421 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5422 cum
->words
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5424 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
5426 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
5430 else if (cum
->intoffset
== -1)
5431 cum
->intoffset
= bitpos
;
5435 /* Update the data in CUM to advance over an argument
5436 of mode MODE and data type TYPE.
5437 (TYPE is null for libcalls where that information may not be available.)
5439 Note that for args passed by reference, function_arg will be called
5440 with MODE and TYPE set to that of the pointer to the arg, not the arg
5444 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5445 tree type
, int named
, int depth
)
5449 /* Only tick off an argument if we're not recursing. */
5451 cum
->nargs_prototype
--;
5453 if (TARGET_ALTIVEC_ABI
5454 && (ALTIVEC_VECTOR_MODE (mode
)
5455 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5456 && int_size_in_bytes (type
) == 16)))
5460 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
5463 if (!TARGET_ALTIVEC
)
5464 error ("cannot pass argument in vector register because"
5465 " altivec instructions are disabled, use -maltivec"
5468 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
5469 even if it is going to be passed in a vector register.
5470 Darwin does the same for variable-argument functions. */
5471 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
5472 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
5482 /* Vector parameters must be 16-byte aligned. This places
5483 them at 2 mod 4 in terms of words in 32-bit mode, since
5484 the parameter save area starts at offset 24 from the
5485 stack. In 64-bit mode, they just have to start on an
5486 even word, since the parameter save area is 16-byte
5487 aligned. Space for GPRs is reserved even if the argument
5488 will be passed in memory. */
5490 align
= (2 - cum
->words
) & 3;
5492 align
= cum
->words
& 1;
5493 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
5495 if (TARGET_DEBUG_ARG
)
5497 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
5499 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
5500 cum
->nargs_prototype
, cum
->prototype
,
5501 GET_MODE_NAME (mode
));
5505 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
5507 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
5510 else if (rs6000_darwin64_abi
5512 && TREE_CODE (type
) == RECORD_TYPE
5513 && (size
= int_size_in_bytes (type
)) > 0)
5515 /* Variable sized types have size == -1 and are
5516 treated as if consisting entirely of ints.
5517 Pad to 16 byte boundary if needed. */
5518 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
5519 && (cum
->words
% 2) != 0)
5521 /* For varargs, we can just go up by the size of the struct. */
5523 cum
->words
+= (size
+ 7) / 8;
5526 /* It is tempting to say int register count just goes up by
5527 sizeof(type)/8, but this is wrong in a case such as
5528 { int; double; int; } [powerpc alignment]. We have to
5529 grovel through the fields for these too. */
5531 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
5532 rs6000_darwin64_record_arg_advance_flush (cum
,
5533 size
* BITS_PER_UNIT
);
5536 else if (DEFAULT_ABI
== ABI_V4
)
5538 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5539 && (mode
== SFmode
|| mode
== DFmode
5540 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
5541 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)))
5543 /* _Decimal128 must use an even/odd register pair. This assumes
5544 that the register number is odd when fregno is odd. */
5545 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
5548 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
5549 <= FP_ARG_V4_MAX_REG
)
5550 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5553 cum
->fregno
= FP_ARG_V4_MAX_REG
+ 1;
5554 if (mode
== DFmode
|| mode
== TFmode
5555 || mode
== DDmode
|| mode
== TDmode
)
5556 cum
->words
+= cum
->words
& 1;
5557 cum
->words
+= rs6000_arg_size (mode
, type
);
5562 int n_words
= rs6000_arg_size (mode
, type
);
5563 int gregno
= cum
->sysv_gregno
;
5565 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5566 (r7,r8) or (r9,r10). As does any other 2 word item such
5567 as complex int due to a historical mistake. */
5569 gregno
+= (1 - gregno
) & 1;
5571 /* Multi-reg args are not split between registers and stack. */
5572 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5574 /* Long long and SPE vectors are aligned on the stack.
5575 So are other 2 word items such as complex int due to
5576 a historical mistake. */
5578 cum
->words
+= cum
->words
& 1;
5579 cum
->words
+= n_words
;
5582 /* Note: continuing to accumulate gregno past when we've started
5583 spilling to the stack indicates the fact that we've started
5584 spilling to the stack to expand_builtin_saveregs. */
5585 cum
->sysv_gregno
= gregno
+ n_words
;
5588 if (TARGET_DEBUG_ARG
)
5590 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
5591 cum
->words
, cum
->fregno
);
5592 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
5593 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
5594 fprintf (stderr
, "mode = %4s, named = %d\n",
5595 GET_MODE_NAME (mode
), named
);
5600 int n_words
= rs6000_arg_size (mode
, type
);
5601 int start_words
= cum
->words
;
5602 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
5604 cum
->words
= align_words
+ n_words
;
5606 if (SCALAR_FLOAT_MODE_P (mode
)
5607 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
5609 /* _Decimal128 must be passed in an even/odd float register pair.
5610 This assumes that the register number is odd when fregno is
5612 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
5614 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5617 if (TARGET_DEBUG_ARG
)
5619 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
5620 cum
->words
, cum
->fregno
);
5621 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
5622 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
5623 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
5624 named
, align_words
- start_words
, depth
);
5630 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
5638 r1
= gen_rtx_REG (DImode
, gregno
);
5639 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5640 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
5645 r1
= gen_rtx_REG (DImode
, gregno
);
5646 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5647 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
5648 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
5649 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
5652 r1
= gen_rtx_REG (DImode
, gregno
);
5653 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5654 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
5655 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
5656 r5
= gen_rtx_REG (DImode
, gregno
+ 4);
5657 r5
= gen_rtx_EXPR_LIST (VOIDmode
, r5
, GEN_INT (16));
5658 r7
= gen_rtx_REG (DImode
, gregno
+ 6);
5659 r7
= gen_rtx_EXPR_LIST (VOIDmode
, r7
, GEN_INT (24));
5660 return gen_rtx_PARALLEL (mode
, gen_rtvec (4, r1
, r3
, r5
, r7
));
5667 /* Determine where to put a SIMD argument on the SPE. */
5669 rs6000_spe_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5672 int gregno
= cum
->sysv_gregno
;
5674 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
5675 are passed and returned in a pair of GPRs for ABI compatibility. */
5676 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
5677 || mode
== DDmode
|| mode
== TDmode
5678 || mode
== DCmode
|| mode
== TCmode
))
5680 int n_words
= rs6000_arg_size (mode
, type
);
5682 /* Doubles go in an odd/even register pair (r5/r6, etc). */
5683 if (mode
== DFmode
|| mode
== DDmode
)
5684 gregno
+= (1 - gregno
) & 1;
5686 /* Multi-reg args are not split between registers and stack. */
5687 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5690 return spe_build_register_parallel (mode
, gregno
);
5694 int n_words
= rs6000_arg_size (mode
, type
);
5696 /* SPE vectors are put in odd registers. */
5697 if (n_words
== 2 && (gregno
& 1) == 0)
5700 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
5703 enum machine_mode m
= SImode
;
5705 r1
= gen_rtx_REG (m
, gregno
);
5706 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
5707 r2
= gen_rtx_REG (m
, gregno
+ 1);
5708 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
5709 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
5716 if (gregno
<= GP_ARG_MAX_REG
)
5717 return gen_rtx_REG (mode
, gregno
);
5723 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
5724 structure between cum->intoffset and bitpos to integer registers. */
5727 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
5728 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
5730 enum machine_mode mode
;
5732 unsigned int startbit
, endbit
;
5733 int this_regno
, intregs
, intoffset
;
5736 if (cum
->intoffset
== -1)
5739 intoffset
= cum
->intoffset
;
5740 cum
->intoffset
= -1;
5742 /* If this is the trailing part of a word, try to only load that
5743 much into the register. Otherwise load the whole register. Note
5744 that in the latter case we may pick up unwanted bits. It's not a
5745 problem at the moment but may wish to revisit. */
5747 if (intoffset
% BITS_PER_WORD
!= 0)
5749 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
5751 if (mode
== BLKmode
)
5753 /* We couldn't find an appropriate mode, which happens,
5754 e.g., in packed structs when there are 3 bytes to load.
5755 Back intoffset back to the beginning of the word in this
5757 intoffset
= intoffset
& -BITS_PER_WORD
;
5764 startbit
= intoffset
& -BITS_PER_WORD
;
5765 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
5766 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
5767 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
5769 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
5772 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
5776 intoffset
/= BITS_PER_UNIT
;
5779 regno
= GP_ARG_MIN_REG
+ this_regno
;
5780 reg
= gen_rtx_REG (mode
, regno
);
5782 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
5785 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
5789 while (intregs
> 0);
5792 /* Recursive workhorse for the following. */
5795 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, const_tree type
,
5796 HOST_WIDE_INT startbitpos
, rtx rvec
[],
5801 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
5802 if (TREE_CODE (f
) == FIELD_DECL
)
5804 HOST_WIDE_INT bitpos
= startbitpos
;
5805 tree ftype
= TREE_TYPE (f
);
5806 enum machine_mode mode
;
5807 if (ftype
== error_mark_node
)
5809 mode
= TYPE_MODE (ftype
);
5811 if (DECL_SIZE (f
) != 0
5812 && host_integerp (bit_position (f
), 1))
5813 bitpos
+= int_bit_position (f
);
5815 /* ??? FIXME: else assume zero offset. */
5817 if (TREE_CODE (ftype
) == RECORD_TYPE
)
5818 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
5819 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
5824 case SCmode
: mode
= SFmode
; break;
5825 case DCmode
: mode
= DFmode
; break;
5826 case TCmode
: mode
= TFmode
; break;
5830 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
5832 = gen_rtx_EXPR_LIST (VOIDmode
,
5833 gen_rtx_REG (mode
, cum
->fregno
++),
5834 GEN_INT (bitpos
/ BITS_PER_UNIT
));
5835 if (mode
== TFmode
|| mode
== TDmode
)
5838 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
5840 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
5842 = gen_rtx_EXPR_LIST (VOIDmode
,
5843 gen_rtx_REG (mode
, cum
->vregno
++),
5844 GEN_INT (bitpos
/ BITS_PER_UNIT
));
5846 else if (cum
->intoffset
== -1)
5847 cum
->intoffset
= bitpos
;
5851 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
5852 the register(s) to be used for each field and subfield of a struct
5853 being passed by value, along with the offset of where the
5854 register's value may be found in the block. FP fields go in FP
5855 register, vector fields go in vector registers, and everything
5856 else goes in int registers, packed as in memory.
5858 This code is also used for function return values. RETVAL indicates
5859 whether this is the case.
5861 Much of this is taken from the SPARC V9 port, which has a similar
5862 calling convention. */
5865 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, const_tree type
,
5866 int named
, bool retval
)
5868 rtx rvec
[FIRST_PSEUDO_REGISTER
];
5869 int k
= 1, kbase
= 1;
5870 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
5871 /* This is a copy; modifications are not visible to our caller. */
5872 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
5873 CUMULATIVE_ARGS
*cum
= ©_cum
;
5875 /* Pad to 16 byte boundary if needed. */
5876 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
5877 && (cum
->words
% 2) != 0)
5884 /* Put entries into rvec[] for individual FP and vector fields, and
5885 for the chunks of memory that go in int regs. Note we start at
5886 element 1; 0 is reserved for an indication of using memory, and
5887 may or may not be filled in below. */
5888 rs6000_darwin64_record_arg_recurse (cum
, type
, 0, rvec
, &k
);
5889 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
5891 /* If any part of the struct went on the stack put all of it there.
5892 This hack is because the generic code for
5893 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
5894 parts of the struct are not at the beginning. */
5898 return NULL_RTX
; /* doesn't go in registers at all */
5900 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
5902 if (k
> 1 || cum
->use_stack
)
5903 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
5908 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
5911 rs6000_mixed_function_arg (enum machine_mode mode
, tree type
, int align_words
)
5915 rtx rvec
[GP_ARG_NUM_REG
+ 1];
5917 if (align_words
>= GP_ARG_NUM_REG
)
5920 n_units
= rs6000_arg_size (mode
, type
);
5922 /* Optimize the simple case where the arg fits in one gpr, except in
5923 the case of BLKmode due to assign_parms assuming that registers are
5924 BITS_PER_WORD wide. */
5926 || (n_units
== 1 && mode
!= BLKmode
))
5927 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5930 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
5931 /* Not all of the arg fits in gprs. Say that it goes in memory too,
5932 using a magic NULL_RTX component.
5933 This is not strictly correct. Only some of the arg belongs in
5934 memory, not all of it. However, the normal scheme using
5935 function_arg_partial_nregs can result in unusual subregs, eg.
5936 (subreg:SI (reg:DF) 4), which are not handled well. The code to
5937 store the whole arg to memory is often more efficient than code
5938 to store pieces, and we know that space is available in the right
5939 place for the whole arg. */
5940 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
5945 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
5946 rtx off
= GEN_INT (i
++ * 4);
5947 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
5949 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
5951 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
5954 /* Determine where to put an argument to a function.
5955 Value is zero to push the argument on the stack,
5956 or a hard register in which to store the argument.
5958 MODE is the argument's machine mode.
5959 TYPE is the data type of the argument (as a tree).
5960 This is null for libcalls where that information may
5962 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5963 the preceding args and about the function being called. It is
5964 not modified in this routine.
5965 NAMED is nonzero if this argument is a named parameter
5966 (otherwise it is an extra parameter matching an ellipsis).
5968 On RS/6000 the first eight words of non-FP are normally in registers
5969 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
5970 Under V.4, the first 8 FP args are in registers.
5972 If this is floating-point and no prototype is specified, we use
5973 both an FP and integer register (or possibly FP reg and stack). Library
5974 functions (when CALL_LIBCALL is set) always have the proper types for args,
5975 so we can pass the FP value just in one register. emit_library_function
5976 doesn't support PARALLEL anyway.
5978 Note that for args passed by reference, function_arg will be called
5979 with MODE and TYPE set to that of the pointer to the arg, not the arg
5983 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5984 tree type
, int named
)
5986 enum rs6000_abi abi
= DEFAULT_ABI
;
5988 /* Return a marker to indicate whether CR1 needs to set or clear the
5989 bit that V.4 uses to say fp args were passed in registers.
5990 Assume that we don't need the marker for software floating point,
5991 or compiler generated library calls. */
5992 if (mode
== VOIDmode
)
5995 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
5997 || (cum
->nargs_prototype
< 0
5998 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))))
6000 /* For the SPE, we need to crxor CR6 always. */
6002 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
6003 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
6004 return GEN_INT (cum
->call_cookie
6005 | ((cum
->fregno
== FP_ARG_MIN_REG
)
6006 ? CALL_V4_SET_FP_ARGS
6007 : CALL_V4_CLEAR_FP_ARGS
));
6010 return GEN_INT (cum
->call_cookie
);
6013 if (rs6000_darwin64_abi
&& mode
== BLKmode
6014 && TREE_CODE (type
) == RECORD_TYPE
)
6016 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, false);
6017 if (rslt
!= NULL_RTX
)
6019 /* Else fall through to usual handling. */
6022 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
6023 if (TARGET_64BIT
&& ! cum
->prototype
)
6025 /* Vector parameters get passed in vector register
6026 and also in GPRs or memory, in absence of prototype. */
6029 align_words
= (cum
->words
+ 1) & ~1;
6031 if (align_words
>= GP_ARG_NUM_REG
)
6037 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6039 return gen_rtx_PARALLEL (mode
,
6041 gen_rtx_EXPR_LIST (VOIDmode
,
6043 gen_rtx_EXPR_LIST (VOIDmode
,
6044 gen_rtx_REG (mode
, cum
->vregno
),
6048 return gen_rtx_REG (mode
, cum
->vregno
);
6049 else if (TARGET_ALTIVEC_ABI
6050 && (ALTIVEC_VECTOR_MODE (mode
)
6051 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
6052 && int_size_in_bytes (type
) == 16)))
6054 if (named
|| abi
== ABI_V4
)
6058 /* Vector parameters to varargs functions under AIX or Darwin
6059 get passed in memory and possibly also in GPRs. */
6060 int align
, align_words
, n_words
;
6061 enum machine_mode part_mode
;
6063 /* Vector parameters must be 16-byte aligned. This places them at
6064 2 mod 4 in terms of words in 32-bit mode, since the parameter
6065 save area starts at offset 24 from the stack. In 64-bit mode,
6066 they just have to start on an even word, since the parameter
6067 save area is 16-byte aligned. */
6069 align
= (2 - cum
->words
) & 3;
6071 align
= cum
->words
& 1;
6072 align_words
= cum
->words
+ align
;
6074 /* Out of registers? Memory, then. */
6075 if (align_words
>= GP_ARG_NUM_REG
)
6078 if (TARGET_32BIT
&& TARGET_POWERPC64
)
6079 return rs6000_mixed_function_arg (mode
, type
, align_words
);
6081 /* The vector value goes in GPRs. Only the part of the
6082 value in GPRs is reported here. */
6084 n_words
= rs6000_arg_size (mode
, type
);
6085 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
6086 /* Fortunately, there are only two possibilities, the value
6087 is either wholly in GPRs or half in GPRs and half not. */
6090 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
6093 else if (TARGET_SPE_ABI
&& TARGET_SPE
6094 && (SPE_VECTOR_MODE (mode
)
6095 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
6100 || mode
== TCmode
))))
6101 return rs6000_spe_function_arg (cum
, mode
, type
);
6103 else if (abi
== ABI_V4
)
6105 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
6106 && (mode
== SFmode
|| mode
== DFmode
6107 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
6108 || mode
== SDmode
|| mode
== DDmode
|| mode
== TDmode
))
6110 /* _Decimal128 must use an even/odd register pair. This assumes
6111 that the register number is odd when fregno is odd. */
6112 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
6115 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
6116 <= FP_ARG_V4_MAX_REG
)
6117 return gen_rtx_REG (mode
, cum
->fregno
);
6123 int n_words
= rs6000_arg_size (mode
, type
);
6124 int gregno
= cum
->sysv_gregno
;
6126 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
6127 (r7,r8) or (r9,r10). As does any other 2 word item such
6128 as complex int due to a historical mistake. */
6130 gregno
+= (1 - gregno
) & 1;
6132 /* Multi-reg args are not split between registers and stack. */
6133 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
6136 if (TARGET_32BIT
&& TARGET_POWERPC64
)
6137 return rs6000_mixed_function_arg (mode
, type
,
6138 gregno
- GP_ARG_MIN_REG
);
6139 return gen_rtx_REG (mode
, gregno
);
6144 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
6146 /* _Decimal128 must be passed in an even/odd float register pair.
6147 This assumes that the register number is odd when fregno is odd. */
6148 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
6151 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
6153 rtx rvec
[GP_ARG_NUM_REG
+ 1];
6157 enum machine_mode fmode
= mode
;
6158 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
6160 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
6162 /* Currently, we only ever need one reg here because complex
6163 doubles are split. */
6164 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
6165 && (fmode
== TFmode
|| fmode
== TDmode
));
6167 /* Long double or _Decimal128 split over regs and memory. */
6168 fmode
= DECIMAL_FLOAT_MODE_P (fmode
) ? DDmode
: DFmode
;
6171 /* Do we also need to pass this arg in the parameter save
6174 && (cum
->nargs_prototype
<= 0
6175 || (DEFAULT_ABI
== ABI_AIX
6177 && align_words
>= GP_ARG_NUM_REG
)));
6179 if (!needs_psave
&& mode
== fmode
)
6180 return gen_rtx_REG (fmode
, cum
->fregno
);
6185 /* Describe the part that goes in gprs or the stack.
6186 This piece must come first, before the fprs. */
6187 if (align_words
< GP_ARG_NUM_REG
)
6189 unsigned long n_words
= rs6000_arg_size (mode
, type
);
6191 if (align_words
+ n_words
> GP_ARG_NUM_REG
6192 || (TARGET_32BIT
&& TARGET_POWERPC64
))
6194 /* If this is partially on the stack, then we only
6195 include the portion actually in registers here. */
6196 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
6199 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
6200 /* Not all of the arg fits in gprs. Say that it
6201 goes in memory too, using a magic NULL_RTX
6202 component. Also see comment in
6203 rs6000_mixed_function_arg for why the normal
6204 function_arg_partial_nregs scheme doesn't work
6206 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
6210 r
= gen_rtx_REG (rmode
,
6211 GP_ARG_MIN_REG
+ align_words
);
6212 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
6213 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
6215 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
6219 /* The whole arg fits in gprs. */
6220 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6221 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
6225 /* It's entirely in memory. */
6226 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
6229 /* Describe where this piece goes in the fprs. */
6230 r
= gen_rtx_REG (fmode
, cum
->fregno
);
6231 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
6233 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
6235 else if (align_words
< GP_ARG_NUM_REG
)
6237 if (TARGET_32BIT
&& TARGET_POWERPC64
)
6238 return rs6000_mixed_function_arg (mode
, type
, align_words
);
6240 if (mode
== BLKmode
)
6243 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
6250 /* For an arg passed partly in registers and partly in memory, this is
6251 the number of bytes passed in registers. For args passed entirely in
6252 registers or entirely in memory, zero. When an arg is described by a
6253 PARALLEL, perhaps using more than one register type, this function
6254 returns the number of bytes used by the first element of the PARALLEL. */
6257 rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6258 tree type
, bool named
)
6263 if (DEFAULT_ABI
== ABI_V4
)
6266 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
6267 && cum
->nargs_prototype
>= 0)
6270 /* In this complicated case we just disable the partial_nregs code. */
6271 if (rs6000_darwin64_abi
&& mode
== BLKmode
6272 && TREE_CODE (type
) == RECORD_TYPE
6273 && int_size_in_bytes (type
) > 0)
6276 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
6278 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
6280 /* If we are passing this arg in the fixed parameter save area
6281 (gprs or memory) as well as fprs, then this function should
6282 return the number of partial bytes passed in the parameter
6283 save area rather than partial bytes passed in fprs. */
6285 && (cum
->nargs_prototype
<= 0
6286 || (DEFAULT_ABI
== ABI_AIX
6288 && align_words
>= GP_ARG_NUM_REG
)))
6290 else if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3)
6291 > FP_ARG_MAX_REG
+ 1)
6292 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
6293 else if (cum
->nargs_prototype
>= 0)
6297 if (align_words
< GP_ARG_NUM_REG
6298 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
6299 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
6301 if (ret
!= 0 && TARGET_DEBUG_ARG
)
6302 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
6307 /* A C expression that indicates when an argument must be passed by
6308 reference. If nonzero for an argument, a copy of that argument is
6309 made in memory and a pointer to the argument is passed instead of
6310 the argument itself. The pointer is passed in whatever way is
6311 appropriate for passing a pointer to that type.
6313 Under V.4, aggregates and long double are passed by reference.
6315 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
6316 reference unless the AltiVec vector extension ABI is in force.
6318 As an extension to all ABIs, variable sized types are passed by
6322 rs6000_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
6323 enum machine_mode mode
, const_tree type
,
6324 bool named ATTRIBUTE_UNUSED
)
6326 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& mode
== TFmode
)
6328 if (TARGET_DEBUG_ARG
)
6329 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
6336 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
6338 if (TARGET_DEBUG_ARG
)
6339 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
6343 if (int_size_in_bytes (type
) < 0)
6345 if (TARGET_DEBUG_ARG
)
6346 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
6350 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6351 modes only exist for GCC vector types if -maltivec. */
6352 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
6354 if (TARGET_DEBUG_ARG
)
6355 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
6359 /* Pass synthetic vectors in memory. */
6360 if (TREE_CODE (type
) == VECTOR_TYPE
6361 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
6363 static bool warned_for_pass_big_vectors
= false;
6364 if (TARGET_DEBUG_ARG
)
6365 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
6366 if (!warned_for_pass_big_vectors
)
6368 warning (0, "GCC vector passed by reference: "
6369 "non-standard ABI extension with no compatibility guarantee");
6370 warned_for_pass_big_vectors
= true;
6379 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
6382 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
6387 for (i
= 0; i
< nregs
; i
++)
6389 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
6390 if (reload_completed
)
6392 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
6395 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
6396 i
* GET_MODE_SIZE (reg_mode
));
6399 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
6403 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
6407 /* Perform any needed actions needed for a function that is receiving a
6408 variable number of arguments.
6412 MODE and TYPE are the mode and type of the current parameter.
6414 PRETEND_SIZE is a variable that should be set to the amount of stack
6415 that must be pushed by the prolog to pretend that our caller pushed
6418 Normally, this macro will push all remaining incoming registers on the
6419 stack and set PRETEND_SIZE to the length of the registers pushed. */
6422 setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6423 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
6426 CUMULATIVE_ARGS next_cum
;
6427 int reg_size
= TARGET_32BIT
? 4 : 8;
6428 rtx save_area
= NULL_RTX
, mem
;
6429 int first_reg_offset
;
6432 /* Skip the last named argument. */
6434 function_arg_advance (&next_cum
, mode
, type
, 1, 0);
6436 if (DEFAULT_ABI
== ABI_V4
)
6438 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
6442 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
6443 HOST_WIDE_INT offset
= 0;
6445 /* Try to optimize the size of the varargs save area.
6446 The ABI requires that ap.reg_save_area is doubleword
6447 aligned, but we don't need to allocate space for all
6448 the bytes, only those to which we actually will save
6450 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
6451 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
6452 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
6453 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
6454 && cfun
->va_list_fpr_size
)
6457 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
6458 * UNITS_PER_FP_WORD
;
6459 if (cfun
->va_list_fpr_size
6460 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
6461 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
6463 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
6464 * UNITS_PER_FP_WORD
;
6468 offset
= -((first_reg_offset
* reg_size
) & ~7);
6469 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
6471 gpr_reg_num
= cfun
->va_list_gpr_size
;
6472 if (reg_size
== 4 && (first_reg_offset
& 1))
6475 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
6478 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
6480 - (int) (GP_ARG_NUM_REG
* reg_size
);
6482 if (gpr_size
+ fpr_size
)
6485 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
6486 gcc_assert (GET_CODE (reg_save_area
) == MEM
);
6487 reg_save_area
= XEXP (reg_save_area
, 0);
6488 if (GET_CODE (reg_save_area
) == PLUS
)
6490 gcc_assert (XEXP (reg_save_area
, 0)
6491 == virtual_stack_vars_rtx
);
6492 gcc_assert (GET_CODE (XEXP (reg_save_area
, 1)) == CONST_INT
);
6493 offset
+= INTVAL (XEXP (reg_save_area
, 1));
6496 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
6499 cfun
->machine
->varargs_save_offset
= offset
;
6500 save_area
= plus_constant (virtual_stack_vars_rtx
, offset
);
6505 first_reg_offset
= next_cum
.words
;
6506 save_area
= virtual_incoming_args_rtx
;
6508 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
6509 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
6512 set
= get_varargs_alias_set ();
6513 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
6514 && cfun
->va_list_gpr_size
)
6516 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
6518 if (va_list_gpr_counter_field
)
6520 /* V4 va_list_gpr_size counts number of registers needed. */
6521 if (nregs
> cfun
->va_list_gpr_size
)
6522 nregs
= cfun
->va_list_gpr_size
;
6526 /* char * va_list instead counts number of bytes needed. */
6527 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
6528 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
6531 mem
= gen_rtx_MEM (BLKmode
,
6532 plus_constant (save_area
,
6533 first_reg_offset
* reg_size
));
6534 MEM_NOTRAP_P (mem
) = 1;
6535 set_mem_alias_set (mem
, set
);
6536 set_mem_align (mem
, BITS_PER_WORD
);
6538 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
6542 /* Save FP registers if needed. */
6543 if (DEFAULT_ABI
== ABI_V4
6544 && TARGET_HARD_FLOAT
&& TARGET_FPRS
6546 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
6547 && cfun
->va_list_fpr_size
)
6549 int fregno
= next_cum
.fregno
, nregs
;
6550 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
6551 rtx lab
= gen_label_rtx ();
6552 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
6553 * UNITS_PER_FP_WORD
);
6556 (gen_rtx_SET (VOIDmode
,
6558 gen_rtx_IF_THEN_ELSE (VOIDmode
,
6559 gen_rtx_NE (VOIDmode
, cr1
,
6561 gen_rtx_LABEL_REF (VOIDmode
, lab
),
6565 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
6566 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
6568 mem
= gen_rtx_MEM (DFmode
, plus_constant (save_area
, off
));
6569 MEM_NOTRAP_P (mem
) = 1;
6570 set_mem_alias_set (mem
, set
);
6571 set_mem_align (mem
, GET_MODE_ALIGNMENT (DFmode
));
6572 emit_move_insn (mem
, gen_rtx_REG (DFmode
, fregno
));
6579 /* Create the va_list data type. */
6582 rs6000_build_builtin_va_list (void)
6584 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
6586 /* For AIX, prefer 'char *' because that's what the system
6587 header files like. */
6588 if (DEFAULT_ABI
!= ABI_V4
)
6589 return build_pointer_type (char_type_node
);
6591 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
6592 type_decl
= build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
6594 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("gpr"),
6595 unsigned_char_type_node
);
6596 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("fpr"),
6597 unsigned_char_type_node
);
6598 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
6600 f_res
= build_decl (FIELD_DECL
, get_identifier ("reserved"),
6601 short_unsigned_type_node
);
6602 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("overflow_arg_area"),
6604 f_sav
= build_decl (FIELD_DECL
, get_identifier ("reg_save_area"),
6607 va_list_gpr_counter_field
= f_gpr
;
6608 va_list_fpr_counter_field
= f_fpr
;
6610 DECL_FIELD_CONTEXT (f_gpr
) = record
;
6611 DECL_FIELD_CONTEXT (f_fpr
) = record
;
6612 DECL_FIELD_CONTEXT (f_res
) = record
;
6613 DECL_FIELD_CONTEXT (f_ovf
) = record
;
6614 DECL_FIELD_CONTEXT (f_sav
) = record
;
6616 TREE_CHAIN (record
) = type_decl
;
6617 TYPE_NAME (record
) = type_decl
;
6618 TYPE_FIELDS (record
) = f_gpr
;
6619 TREE_CHAIN (f_gpr
) = f_fpr
;
6620 TREE_CHAIN (f_fpr
) = f_res
;
6621 TREE_CHAIN (f_res
) = f_ovf
;
6622 TREE_CHAIN (f_ovf
) = f_sav
;
6624 layout_type (record
);
6626 /* The correct type is an array type of one element. */
6627 return build_array_type (record
, build_index_type (size_zero_node
));
6630 /* Implement va_start. */
6633 rs6000_va_start (tree valist
, rtx nextarg
)
6635 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
6636 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
6637 tree gpr
, fpr
, ovf
, sav
, t
;
6639 /* Only SVR4 needs something special. */
6640 if (DEFAULT_ABI
!= ABI_V4
)
6642 std_expand_builtin_va_start (valist
, nextarg
);
6646 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6647 f_fpr
= TREE_CHAIN (f_gpr
);
6648 f_res
= TREE_CHAIN (f_fpr
);
6649 f_ovf
= TREE_CHAIN (f_res
);
6650 f_sav
= TREE_CHAIN (f_ovf
);
6652 valist
= build_va_arg_indirect_ref (valist
);
6653 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6654 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
6655 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
6656 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
6658 /* Count number of gp and fp argument registers used. */
6659 words
= crtl
->args
.info
.words
;
6660 n_gpr
= MIN (crtl
->args
.info
.sysv_gregno
- GP_ARG_MIN_REG
,
6662 n_fpr
= MIN (crtl
->args
.info
.fregno
- FP_ARG_MIN_REG
,
6665 if (TARGET_DEBUG_ARG
)
6666 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
6667 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
6668 words
, n_gpr
, n_fpr
);
6670 if (cfun
->va_list_gpr_size
)
6672 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (gpr
), gpr
,
6673 build_int_cst (NULL_TREE
, n_gpr
));
6674 TREE_SIDE_EFFECTS (t
) = 1;
6675 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6678 if (cfun
->va_list_fpr_size
)
6680 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (fpr
), fpr
,
6681 build_int_cst (NULL_TREE
, n_fpr
));
6682 TREE_SIDE_EFFECTS (t
) = 1;
6683 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6686 /* Find the overflow area. */
6687 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
6689 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ovf
), t
,
6690 size_int (words
* UNITS_PER_WORD
));
6691 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (ovf
), ovf
, t
);
6692 TREE_SIDE_EFFECTS (t
) = 1;
6693 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6695 /* If there were no va_arg invocations, don't set up the register
6697 if (!cfun
->va_list_gpr_size
6698 && !cfun
->va_list_fpr_size
6699 && n_gpr
< GP_ARG_NUM_REG
6700 && n_fpr
< FP_ARG_V4_MAX_REG
)
6703 /* Find the register save area. */
6704 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
6705 if (cfun
->machine
->varargs_save_offset
)
6706 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (sav
), t
,
6707 size_int (cfun
->machine
->varargs_save_offset
));
6708 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (sav
), sav
, t
);
6709 TREE_SIDE_EFFECTS (t
) = 1;
6710 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6713 /* Implement va_arg. */
6716 rs6000_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
6718 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
6719 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
6720 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
6721 tree lab_false
, lab_over
, addr
;
6723 tree ptrtype
= build_pointer_type (type
);
6726 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
6728 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
6729 return build_va_arg_indirect_ref (t
);
6732 if (DEFAULT_ABI
!= ABI_V4
)
6734 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
6736 tree elem_type
= TREE_TYPE (type
);
6737 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
6738 int elem_size
= GET_MODE_SIZE (elem_mode
);
6740 if (elem_size
< UNITS_PER_WORD
)
6742 tree real_part
, imag_part
;
6743 tree post
= NULL_TREE
;
6745 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
6747 /* Copy the value into a temporary, lest the formal temporary
6748 be reused out from under us. */
6749 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
6750 append_to_statement_list (post
, pre_p
);
6752 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
6755 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
6759 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
6762 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6763 f_fpr
= TREE_CHAIN (f_gpr
);
6764 f_res
= TREE_CHAIN (f_fpr
);
6765 f_ovf
= TREE_CHAIN (f_res
);
6766 f_sav
= TREE_CHAIN (f_ovf
);
6768 valist
= build_va_arg_indirect_ref (valist
);
6769 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6770 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
6771 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
6772 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
6774 size
= int_size_in_bytes (type
);
6775 rsize
= (size
+ 3) / 4;
6778 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
6779 && (TYPE_MODE (type
) == SFmode
6780 || TYPE_MODE (type
) == DFmode
6781 || TYPE_MODE (type
) == TFmode
6782 || TYPE_MODE (type
) == SDmode
6783 || TYPE_MODE (type
) == DDmode
6784 || TYPE_MODE (type
) == TDmode
))
6786 /* FP args go in FP registers, if present. */
6788 n_reg
= (size
+ 7) / 8;
6791 if (TYPE_MODE (type
) != SFmode
&& TYPE_MODE (type
) != SDmode
)
6796 /* Otherwise into GP registers. */
6805 /* Pull the value out of the saved registers.... */
6808 addr
= create_tmp_var (ptr_type_node
, "addr");
6809 DECL_POINTER_ALIAS_SET (addr
) = get_varargs_alias_set ();
6811 /* AltiVec vectors never go in registers when -mabi=altivec. */
6812 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
6816 lab_false
= create_artificial_label ();
6817 lab_over
= create_artificial_label ();
6819 /* Long long and SPE vectors are aligned in the registers.
6820 As are any other 2 gpr item such as complex int due to a
6821 historical mistake. */
6823 if (n_reg
== 2 && reg
== gpr
)
6826 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), reg
,
6827 build_int_cst (TREE_TYPE (reg
), n_reg
- 1));
6828 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), reg
, u
);
6830 /* _Decimal128 is passed in even/odd fpr pairs; the stored
6831 reg number is 0 for f1, so we want to make it odd. */
6832 else if (reg
== fpr
&& TYPE_MODE (type
) == TDmode
)
6835 t
= build2 (BIT_IOR_EXPR
, TREE_TYPE (reg
), reg
,
6836 build_int_cst (TREE_TYPE (reg
), 1));
6837 u
= build2 (MODIFY_EXPR
, void_type_node
, reg
, t
);
6840 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
6841 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
6842 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
6843 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
6844 gimplify_and_add (t
, pre_p
);
6848 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, sav
, size_int (sav_ofs
));
6850 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), reg
,
6851 build_int_cst (TREE_TYPE (reg
), n_reg
));
6852 u
= fold_convert (sizetype
, u
);
6853 u
= build2 (MULT_EXPR
, sizetype
, u
, size_int (sav_scale
));
6854 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
, u
);
6856 /* _Decimal32 varargs are located in the second word of the 64-bit
6857 FP register for 32-bit binaries. */
6858 if (!TARGET_POWERPC64
&& TYPE_MODE (type
) == SDmode
)
6859 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
6861 t
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, addr
, t
);
6862 gimplify_and_add (t
, pre_p
);
6864 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
6865 gimplify_and_add (t
, pre_p
);
6867 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
6868 append_to_statement_list (t
, pre_p
);
6870 if ((n_reg
== 2 && !regalign
) || n_reg
> 2)
6872 /* Ensure that we don't find any more args in regs.
6873 Alignment has taken care of for special cases. */
6874 t
= build_gimple_modify_stmt (reg
,
6875 build_int_cst (TREE_TYPE (reg
), 8));
6876 gimplify_and_add (t
, pre_p
);
6880 /* ... otherwise out of the overflow area. */
6882 /* Care for on-stack alignment if needed. */
6886 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (align
- 1));
6887 t
= fold_convert (sizetype
, t
);
6888 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
6890 t
= fold_convert (TREE_TYPE (ovf
), t
);
6892 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
6894 u
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, addr
, t
);
6895 gimplify_and_add (u
, pre_p
);
6897 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
6898 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (ovf
), ovf
, t
);
6899 gimplify_and_add (t
, pre_p
);
6903 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
6904 append_to_statement_list (t
, pre_p
);
6907 if (STRICT_ALIGNMENT
6908 && (TYPE_ALIGN (type
)
6909 > (unsigned) BITS_PER_UNIT
* (align
< 4 ? 4 : align
)))
6911 /* The value (of type complex double, for example) may not be
6912 aligned in memory in the saved registers, so copy via a
6913 temporary. (This is the same code as used for SPARC.) */
6914 tree tmp
= create_tmp_var (type
, "va_arg_tmp");
6915 tree dest_addr
= build_fold_addr_expr (tmp
);
6917 tree copy
= build_call_expr (implicit_built_in_decls
[BUILT_IN_MEMCPY
],
6918 3, dest_addr
, addr
, size_int (rsize
* 4));
6920 gimplify_and_add (copy
, pre_p
);
6924 addr
= fold_convert (ptrtype
, addr
);
6925 return build_va_arg_indirect_ref (addr
);
6931 def_builtin (int mask
, const char *name
, tree type
, int code
)
6933 if ((mask
& target_flags
) || TARGET_PAIRED_FLOAT
)
6935 if (rs6000_builtin_decls
[code
])
6938 rs6000_builtin_decls
[code
] =
6939 add_builtin_function (name
, type
, code
, BUILT_IN_MD
,
6944 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
6946 static const struct builtin_description bdesc_3arg
[] =
6948 { MASK_ALTIVEC
, CODE_FOR_altivec_vmaddfp
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
6949 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
6950 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
6951 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
6952 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
6953 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
6954 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
6955 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
6956 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
6957 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
6958 { MASK_ALTIVEC
, CODE_FOR_altivec_vnmsubfp
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
6959 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
6960 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
6961 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
6962 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
6963 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
6964 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
6965 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
6966 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
6967 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
6968 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
6969 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
6970 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
6972 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
6973 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
6974 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
6975 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
6976 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
6977 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
6978 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
6979 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
6980 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
6981 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
6982 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
6983 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
6984 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
6985 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
6986 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
6988 { 0, CODE_FOR_paired_msub
, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB
},
6989 { 0, CODE_FOR_paired_madd
, "__builtin_paired_madd", PAIRED_BUILTIN_MADD
},
6990 { 0, CODE_FOR_paired_madds0
, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0
},
6991 { 0, CODE_FOR_paired_madds1
, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1
},
6992 { 0, CODE_FOR_paired_nmsub
, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB
},
6993 { 0, CODE_FOR_paired_nmadd
, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD
},
6994 { 0, CODE_FOR_paired_sum0
, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0
},
6995 { 0, CODE_FOR_paired_sum1
, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1
},
6996 { 0, CODE_FOR_selv2sf4
, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4
},
6999 /* DST operations: void foo (void *, const int, const char). */
7001 static const struct builtin_description bdesc_dst
[] =
7003 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
7004 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
7005 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
7006 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
7008 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
7009 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
7010 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
7011 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
7014 /* Simple binary operations: VECc = foo (VECa, VECb). */
7016 static struct builtin_description bdesc_2arg
[] =
7018 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
7019 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
7020 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
7021 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
7022 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
7023 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
7024 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
7025 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
7026 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
7027 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
7028 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
7029 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
7030 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
7031 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
7032 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
7033 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
7034 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
7035 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
7036 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
7037 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
7038 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
7039 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
7040 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequb
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
7041 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequh
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
7042 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequw
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
7043 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpeqfp
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
7044 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgefp
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
7045 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtub
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
7046 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsb
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
7047 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuh
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
7048 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsh
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
7049 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuw
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
7050 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsw
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
7051 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtfp
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
7052 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
7053 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
7054 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
7055 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
7056 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
7057 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
7058 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
7059 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
7060 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
7061 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
7062 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
7063 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
7064 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
7065 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
7066 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
7067 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
7068 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
7069 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
7070 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
7071 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
7072 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
7073 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
7074 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
7075 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
7076 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
7077 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
7078 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
7079 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
7080 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
7081 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
7082 { MASK_ALTIVEC
, CODE_FOR_altivec_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
7083 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
7084 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
7085 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
7086 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
7087 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
7088 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
7089 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
7090 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
7091 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
7092 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
7093 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlb
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
7094 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlh
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
7095 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlw
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
7096 { MASK_ALTIVEC
, CODE_FOR_ashlv16qi3
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
7097 { MASK_ALTIVEC
, CODE_FOR_ashlv8hi3
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
7098 { MASK_ALTIVEC
, CODE_FOR_ashlv4si3
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
7099 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
7100 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
7101 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
7102 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
7103 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
7104 { MASK_ALTIVEC
, CODE_FOR_lshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
7105 { MASK_ALTIVEC
, CODE_FOR_lshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
7106 { MASK_ALTIVEC
, CODE_FOR_lshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
7107 { MASK_ALTIVEC
, CODE_FOR_ashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
7108 { MASK_ALTIVEC
, CODE_FOR_ashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
7109 { MASK_ALTIVEC
, CODE_FOR_ashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
7110 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
7111 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
7112 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
7113 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
7114 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
7115 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
7116 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
7117 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
7118 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
7119 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
7120 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
7121 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
7122 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
7123 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
7124 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
7125 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
7126 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
7127 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
7128 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
7130 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
7131 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
7132 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
7133 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
7134 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
7135 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
7136 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
7137 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
7138 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
7139 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
7140 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
7141 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
7142 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
7143 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
7144 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
7145 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
7146 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
7147 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
7148 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
7149 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
7150 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
7151 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
7152 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
7153 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
7154 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
7155 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
7156 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
7157 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
7158 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
7159 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
7160 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
7161 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
7162 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
7163 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
7164 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
7165 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
7166 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
7167 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
7168 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
7169 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
7170 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
7171 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
7172 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
7173 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
7174 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
7175 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
7176 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
7177 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
7178 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
7179 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
7180 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
7181 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
7182 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
7183 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
7184 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
7185 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
7186 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
7187 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
7188 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
7189 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
7190 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
7191 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
7192 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
7193 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
7194 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
7195 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
7196 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
7197 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
7198 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
7199 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
7200 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
7201 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
7202 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
7203 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
7204 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
7205 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
7206 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
7207 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
7208 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
7209 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
7210 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
7211 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
7212 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
7213 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
7214 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
7215 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
7216 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
7217 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
7218 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
7219 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
7220 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
7221 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
7222 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
7223 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
7224 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
7225 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
7226 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
7227 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
7228 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
7229 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
7230 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
7231 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
7232 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
7233 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
7234 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
7235 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
7236 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
7237 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
7238 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
7239 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
7240 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
7241 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
7242 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
7243 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
7244 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
7245 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
7246 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
7247 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
7248 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
7249 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
7250 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
7251 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
7252 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
7253 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
7254 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
7255 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
7256 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
7258 { 0, CODE_FOR_divv2sf3
, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3
},
7259 { 0, CODE_FOR_addv2sf3
, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3
},
7260 { 0, CODE_FOR_subv2sf3
, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3
},
7261 { 0, CODE_FOR_mulv2sf3
, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3
},
7262 { 0, CODE_FOR_paired_muls0
, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0
},
7263 { 0, CODE_FOR_paired_muls1
, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1
},
7264 { 0, CODE_FOR_paired_merge00
, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00
},
7265 { 0, CODE_FOR_paired_merge01
, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01
},
7266 { 0, CODE_FOR_paired_merge10
, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10
},
7267 { 0, CODE_FOR_paired_merge11
, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11
},
7269 /* Place holder, leave as first spe builtin. */
7270 { 0, CODE_FOR_spe_evaddw
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
7271 { 0, CODE_FOR_spe_evand
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
7272 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
7273 { 0, CODE_FOR_spe_evdivws
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
7274 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
7275 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
7276 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
7277 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
7278 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
7279 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
7280 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
7281 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
7282 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
7283 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
7284 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
7285 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
7286 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
7287 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
7288 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
7289 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
7290 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
7291 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
7292 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
7293 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
7294 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
7295 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
7296 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
7297 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
7298 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
7299 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
7300 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
7301 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
7302 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
7303 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
7304 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
7305 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
7306 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
7307 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
7308 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
7309 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
7310 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
7311 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
7312 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
7313 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
7314 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
7315 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
7316 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
7317 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
7318 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
7319 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
7320 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
7321 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
7322 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
7323 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
7324 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
7325 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
7326 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
7327 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
7328 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
7329 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
7330 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
7331 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
7332 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
7333 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
7334 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
7335 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
7336 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
7337 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
7338 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
7339 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
7340 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
7341 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
7342 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
7343 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
7344 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
7345 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
7346 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
7347 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
7348 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
7349 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
7350 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
7351 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
7352 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
7353 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
7354 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
7355 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
7356 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
7357 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
7358 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
7359 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
7360 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
7361 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
7362 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
7363 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
7364 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
7365 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
7366 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
7367 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
7368 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
7369 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
7370 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
7371 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
7372 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
7373 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
7374 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
7375 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
7376 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
7377 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
7378 { 0, CODE_FOR_spe_evsubfw
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
7380 /* SPE binary operations expecting a 5-bit unsigned literal. */
7381 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
7383 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
7384 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
7385 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
7386 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
7387 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
7388 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
7389 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
7390 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
7391 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
7392 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
7393 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
7394 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
7395 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
7396 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
7397 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
7398 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
7399 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
7400 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
7401 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
7402 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
7403 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
7404 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
7405 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
7406 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
7407 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
7408 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
7410 /* Place-holder. Leave as last binary SPE builtin. */
7411 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
7414 /* AltiVec predicates. */
7416 struct builtin_description_predicates
7418 const unsigned int mask
;
7419 const enum insn_code icode
;
7421 const char *const name
;
7422 const enum rs6000_builtins code
;
7425 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
7427 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P
},
7428 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
7429 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
7430 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
7431 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P
},
7432 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P
},
7433 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P
},
7434 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P
},
7435 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P
},
7436 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P
},
7437 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P
},
7438 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P
},
7439 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P
},
7441 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P
},
7442 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P
},
7443 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P
}
7446 /* SPE predicates. */
7447 static struct builtin_description bdesc_spe_predicates
[] =
7449 /* Place-holder. Leave as first. */
7450 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
7451 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
7452 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
7453 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
7454 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
7455 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
7456 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
7457 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
7458 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
7459 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
7460 /* Place-holder. Leave as last. */
7461 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
7464 /* SPE evsel predicates. */
7465 static struct builtin_description bdesc_spe_evsel
[] =
7467 /* Place-holder. Leave as first. */
7468 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
7469 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
7470 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
7471 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
7472 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
7473 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
7474 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
7475 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
7476 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
7477 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
7478 /* Place-holder. Leave as last. */
7479 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
7482 /* PAIRED predicates. */
7483 static const struct builtin_description bdesc_paired_preds
[] =
7485 /* Place-holder. Leave as first. */
7486 { 0, CODE_FOR_paired_cmpu0
, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0
},
7487 /* Place-holder. Leave as last. */
7488 { 0, CODE_FOR_paired_cmpu1
, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1
},
7491 /* ABS* operations. */
7493 static const struct builtin_description bdesc_abs
[] =
7495 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
7496 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
7497 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
7498 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
7499 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
7500 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
7501 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
}
7504 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
7507 static struct builtin_description bdesc_1arg
[] =
7509 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
7510 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
7511 { MASK_ALTIVEC
, CODE_FOR_altivec_vrefp
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
7512 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfim
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
7513 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
7514 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfip
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
7515 { MASK_ALTIVEC
, CODE_FOR_ftruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
7516 { MASK_ALTIVEC
, CODE_FOR_altivec_vrsqrtefp
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
7517 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
7518 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
7519 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
7520 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
7521 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
7522 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
7523 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
7524 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
7525 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
7527 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
7528 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
7529 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
7530 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
7531 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
7532 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
7533 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
7534 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
7535 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
7536 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
7537 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
7538 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
7539 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
7540 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
7541 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
7542 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
7543 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
7544 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
7545 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
7547 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
7548 end with SPE_BUILTIN_EVSUBFUSIAAW. */
7549 { 0, CODE_FOR_spe_evabs
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
7550 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
7551 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
7552 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
7553 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
7554 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
7555 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
7556 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
7557 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
7558 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
7559 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
7560 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
7561 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
7562 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
7563 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
7564 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
7565 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
7566 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
7567 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
7568 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
7569 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
7570 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
7571 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
7572 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
7573 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
7574 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
7575 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
7576 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
7578 /* Place-holder. Leave as last unary SPE builtin. */
7579 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
},
7581 { 0, CODE_FOR_absv2sf2
, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2
},
7582 { 0, CODE_FOR_nabsv2sf2
, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2
},
7583 { 0, CODE_FOR_negv2sf2
, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2
},
7584 { 0, CODE_FOR_sqrtv2sf2
, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2
},
7585 { 0, CODE_FOR_resv2sf2
, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2
}
7589 rs6000_expand_unop_builtin (enum insn_code icode
, tree exp
, rtx target
)
7592 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7593 rtx op0
= expand_normal (arg0
);
7594 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7595 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7597 if (icode
== CODE_FOR_nothing
)
7598 /* Builtin not supported on this processor. */
7601 /* If we got invalid arguments bail out before generating bad rtl. */
7602 if (arg0
== error_mark_node
)
7605 if (icode
== CODE_FOR_altivec_vspltisb
7606 || icode
== CODE_FOR_altivec_vspltish
7607 || icode
== CODE_FOR_altivec_vspltisw
7608 || icode
== CODE_FOR_spe_evsplatfi
7609 || icode
== CODE_FOR_spe_evsplati
)
7611 /* Only allow 5-bit *signed* literals. */
7612 if (GET_CODE (op0
) != CONST_INT
7613 || INTVAL (op0
) > 15
7614 || INTVAL (op0
) < -16)
7616 error ("argument 1 must be a 5-bit signed literal");
7622 || GET_MODE (target
) != tmode
7623 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7624 target
= gen_reg_rtx (tmode
);
7626 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7627 op0
= copy_to_mode_reg (mode0
, op0
);
7629 pat
= GEN_FCN (icode
) (target
, op0
);
7638 altivec_expand_abs_builtin (enum insn_code icode
, tree exp
, rtx target
)
7640 rtx pat
, scratch1
, scratch2
;
7641 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7642 rtx op0
= expand_normal (arg0
);
7643 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7644 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7646 /* If we have invalid arguments, bail out before generating bad rtl. */
7647 if (arg0
== error_mark_node
)
7651 || GET_MODE (target
) != tmode
7652 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7653 target
= gen_reg_rtx (tmode
);
7655 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7656 op0
= copy_to_mode_reg (mode0
, op0
);
7658 scratch1
= gen_reg_rtx (mode0
);
7659 scratch2
= gen_reg_rtx (mode0
);
7661 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
7670 rs6000_expand_binop_builtin (enum insn_code icode
, tree exp
, rtx target
)
7673 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7674 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7675 rtx op0
= expand_normal (arg0
);
7676 rtx op1
= expand_normal (arg1
);
7677 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7678 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7679 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7681 if (icode
== CODE_FOR_nothing
)
7682 /* Builtin not supported on this processor. */
7685 /* If we got invalid arguments bail out before generating bad rtl. */
7686 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7689 if (icode
== CODE_FOR_altivec_vcfux
7690 || icode
== CODE_FOR_altivec_vcfsx
7691 || icode
== CODE_FOR_altivec_vctsxs
7692 || icode
== CODE_FOR_altivec_vctuxs
7693 || icode
== CODE_FOR_altivec_vspltb
7694 || icode
== CODE_FOR_altivec_vsplth
7695 || icode
== CODE_FOR_altivec_vspltw
7696 || icode
== CODE_FOR_spe_evaddiw
7697 || icode
== CODE_FOR_spe_evldd
7698 || icode
== CODE_FOR_spe_evldh
7699 || icode
== CODE_FOR_spe_evldw
7700 || icode
== CODE_FOR_spe_evlhhesplat
7701 || icode
== CODE_FOR_spe_evlhhossplat
7702 || icode
== CODE_FOR_spe_evlhhousplat
7703 || icode
== CODE_FOR_spe_evlwhe
7704 || icode
== CODE_FOR_spe_evlwhos
7705 || icode
== CODE_FOR_spe_evlwhou
7706 || icode
== CODE_FOR_spe_evlwhsplat
7707 || icode
== CODE_FOR_spe_evlwwsplat
7708 || icode
== CODE_FOR_spe_evrlwi
7709 || icode
== CODE_FOR_spe_evslwi
7710 || icode
== CODE_FOR_spe_evsrwis
7711 || icode
== CODE_FOR_spe_evsubifw
7712 || icode
== CODE_FOR_spe_evsrwiu
)
7714 /* Only allow 5-bit unsigned literals. */
7716 if (TREE_CODE (arg1
) != INTEGER_CST
7717 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
7719 error ("argument 2 must be a 5-bit unsigned literal");
7725 || GET_MODE (target
) != tmode
7726 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7727 target
= gen_reg_rtx (tmode
);
7729 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7730 op0
= copy_to_mode_reg (mode0
, op0
);
7731 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7732 op1
= copy_to_mode_reg (mode1
, op1
);
7734 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
7743 altivec_expand_predicate_builtin (enum insn_code icode
, const char *opcode
,
7744 tree exp
, rtx target
)
7747 tree cr6_form
= CALL_EXPR_ARG (exp
, 0);
7748 tree arg0
= CALL_EXPR_ARG (exp
, 1);
7749 tree arg1
= CALL_EXPR_ARG (exp
, 2);
7750 rtx op0
= expand_normal (arg0
);
7751 rtx op1
= expand_normal (arg1
);
7752 enum machine_mode tmode
= SImode
;
7753 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7754 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7757 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
7759 error ("argument 1 of __builtin_altivec_predicate must be a constant");
7763 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
7765 gcc_assert (mode0
== mode1
);
7767 /* If we have invalid arguments, bail out before generating bad rtl. */
7768 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7772 || GET_MODE (target
) != tmode
7773 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7774 target
= gen_reg_rtx (tmode
);
7776 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7777 op0
= copy_to_mode_reg (mode0
, op0
);
7778 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7779 op1
= copy_to_mode_reg (mode1
, op1
);
7781 scratch
= gen_reg_rtx (mode0
);
7783 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
,
7784 gen_rtx_SYMBOL_REF (Pmode
, opcode
));
7789 /* The vec_any* and vec_all* predicates use the same opcodes for two
7790 different operations, but the bits in CR6 will be different
7791 depending on what information we want. So we have to play tricks
7792 with CR6 to get the right bits out.
7794 If you think this is disgusting, look at the specs for the
7795 AltiVec predicates. */
7797 switch (cr6_form_int
)
7800 emit_insn (gen_cr6_test_for_zero (target
));
7803 emit_insn (gen_cr6_test_for_zero_reverse (target
));
7806 emit_insn (gen_cr6_test_for_lt (target
));
7809 emit_insn (gen_cr6_test_for_lt_reverse (target
));
7812 error ("argument 1 of __builtin_altivec_predicate is out of range");
7820 paired_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
)
7823 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7824 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7825 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7826 enum machine_mode mode0
= Pmode
;
7827 enum machine_mode mode1
= Pmode
;
7828 rtx op0
= expand_normal (arg0
);
7829 rtx op1
= expand_normal (arg1
);
7831 if (icode
== CODE_FOR_nothing
)
7832 /* Builtin not supported on this processor. */
7835 /* If we got invalid arguments bail out before generating bad rtl. */
7836 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7840 || GET_MODE (target
) != tmode
7841 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7842 target
= gen_reg_rtx (tmode
);
7844 op1
= copy_to_mode_reg (mode1
, op1
);
7846 if (op0
== const0_rtx
)
7848 addr
= gen_rtx_MEM (tmode
, op1
);
7852 op0
= copy_to_mode_reg (mode0
, op0
);
7853 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
7856 pat
= GEN_FCN (icode
) (target
, addr
);
7866 altivec_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
)
7869 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7870 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7871 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7872 enum machine_mode mode0
= Pmode
;
7873 enum machine_mode mode1
= Pmode
;
7874 rtx op0
= expand_normal (arg0
);
7875 rtx op1
= expand_normal (arg1
);
7877 if (icode
== CODE_FOR_nothing
)
7878 /* Builtin not supported on this processor. */
7881 /* If we got invalid arguments bail out before generating bad rtl. */
7882 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7886 || GET_MODE (target
) != tmode
7887 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7888 target
= gen_reg_rtx (tmode
);
7890 op1
= copy_to_mode_reg (mode1
, op1
);
7892 if (op0
== const0_rtx
)
7894 addr
= gen_rtx_MEM (tmode
, op1
);
7898 op0
= copy_to_mode_reg (mode0
, op0
);
7899 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
7902 pat
= GEN_FCN (icode
) (target
, addr
);
7912 spe_expand_stv_builtin (enum insn_code icode
, tree exp
)
7914 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7915 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7916 tree arg2
= CALL_EXPR_ARG (exp
, 2);
7917 rtx op0
= expand_normal (arg0
);
7918 rtx op1
= expand_normal (arg1
);
7919 rtx op2
= expand_normal (arg2
);
7921 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
7922 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
7923 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
7925 /* Invalid arguments. Bail before doing anything stoopid! */
7926 if (arg0
== error_mark_node
7927 || arg1
== error_mark_node
7928 || arg2
== error_mark_node
)
7931 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
7932 op0
= copy_to_mode_reg (mode2
, op0
);
7933 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
7934 op1
= copy_to_mode_reg (mode0
, op1
);
7935 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
7936 op2
= copy_to_mode_reg (mode1
, op2
);
7938 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
7945 paired_expand_stv_builtin (enum insn_code icode
, tree exp
)
7947 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7948 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7949 tree arg2
= CALL_EXPR_ARG (exp
, 2);
7950 rtx op0
= expand_normal (arg0
);
7951 rtx op1
= expand_normal (arg1
);
7952 rtx op2
= expand_normal (arg2
);
7954 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7955 enum machine_mode mode1
= Pmode
;
7956 enum machine_mode mode2
= Pmode
;
7958 /* Invalid arguments. Bail before doing anything stoopid! */
7959 if (arg0
== error_mark_node
7960 || arg1
== error_mark_node
7961 || arg2
== error_mark_node
)
7964 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
7965 op0
= copy_to_mode_reg (tmode
, op0
);
7967 op2
= copy_to_mode_reg (mode2
, op2
);
7969 if (op1
== const0_rtx
)
7971 addr
= gen_rtx_MEM (tmode
, op2
);
7975 op1
= copy_to_mode_reg (mode1
, op1
);
7976 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
7979 pat
= GEN_FCN (icode
) (addr
, op0
);
7986 altivec_expand_stv_builtin (enum insn_code icode
, tree exp
)
7988 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7989 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7990 tree arg2
= CALL_EXPR_ARG (exp
, 2);
7991 rtx op0
= expand_normal (arg0
);
7992 rtx op1
= expand_normal (arg1
);
7993 rtx op2
= expand_normal (arg2
);
7995 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7996 enum machine_mode mode1
= Pmode
;
7997 enum machine_mode mode2
= Pmode
;
7999 /* Invalid arguments. Bail before doing anything stoopid! */
8000 if (arg0
== error_mark_node
8001 || arg1
== error_mark_node
8002 || arg2
== error_mark_node
)
8005 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
8006 op0
= copy_to_mode_reg (tmode
, op0
);
8008 op2
= copy_to_mode_reg (mode2
, op2
);
8010 if (op1
== const0_rtx
)
8012 addr
= gen_rtx_MEM (tmode
, op2
);
8016 op1
= copy_to_mode_reg (mode1
, op1
);
8017 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
8020 pat
= GEN_FCN (icode
) (addr
, op0
);
8027 rs6000_expand_ternop_builtin (enum insn_code icode
, tree exp
, rtx target
)
8030 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8031 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8032 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8033 rtx op0
= expand_normal (arg0
);
8034 rtx op1
= expand_normal (arg1
);
8035 rtx op2
= expand_normal (arg2
);
8036 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8037 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8038 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8039 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
8041 if (icode
== CODE_FOR_nothing
)
8042 /* Builtin not supported on this processor. */
8045 /* If we got invalid arguments bail out before generating bad rtl. */
8046 if (arg0
== error_mark_node
8047 || arg1
== error_mark_node
8048 || arg2
== error_mark_node
)
8051 if (icode
== CODE_FOR_altivec_vsldoi_v4sf
8052 || icode
== CODE_FOR_altivec_vsldoi_v4si
8053 || icode
== CODE_FOR_altivec_vsldoi_v8hi
8054 || icode
== CODE_FOR_altivec_vsldoi_v16qi
)
8056 /* Only allow 4-bit unsigned literals. */
8058 if (TREE_CODE (arg2
) != INTEGER_CST
8059 || TREE_INT_CST_LOW (arg2
) & ~0xf)
8061 error ("argument 3 must be a 4-bit unsigned literal");
8067 || GET_MODE (target
) != tmode
8068 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8069 target
= gen_reg_rtx (tmode
);
8071 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8072 op0
= copy_to_mode_reg (mode0
, op0
);
8073 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
8074 op1
= copy_to_mode_reg (mode1
, op1
);
8075 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
8076 op2
= copy_to_mode_reg (mode2
, op2
);
8078 if (TARGET_PAIRED_FLOAT
&& icode
== CODE_FOR_selv2sf4
)
8079 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
, CONST0_RTX (SFmode
));
8081 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
8089 /* Expand the lvx builtins. */
8091 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
8093 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8094 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8096 enum machine_mode tmode
, mode0
;
8098 enum insn_code icode
;
8102 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
8103 icode
= CODE_FOR_altivec_lvx_v16qi
;
8105 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
8106 icode
= CODE_FOR_altivec_lvx_v8hi
;
8108 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
8109 icode
= CODE_FOR_altivec_lvx_v4si
;
8111 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
8112 icode
= CODE_FOR_altivec_lvx_v4sf
;
8121 arg0
= CALL_EXPR_ARG (exp
, 0);
8122 op0
= expand_normal (arg0
);
8123 tmode
= insn_data
[icode
].operand
[0].mode
;
8124 mode0
= insn_data
[icode
].operand
[1].mode
;
8127 || GET_MODE (target
) != tmode
8128 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8129 target
= gen_reg_rtx (tmode
);
8131 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8132 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
8134 pat
= GEN_FCN (icode
) (target
, op0
);
8141 /* Expand the stvx builtins. */
8143 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
8146 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8147 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8149 enum machine_mode mode0
, mode1
;
8151 enum insn_code icode
;
8155 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
8156 icode
= CODE_FOR_altivec_stvx_v16qi
;
8158 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
8159 icode
= CODE_FOR_altivec_stvx_v8hi
;
8161 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
8162 icode
= CODE_FOR_altivec_stvx_v4si
;
8164 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
8165 icode
= CODE_FOR_altivec_stvx_v4sf
;
8172 arg0
= CALL_EXPR_ARG (exp
, 0);
8173 arg1
= CALL_EXPR_ARG (exp
, 1);
8174 op0
= expand_normal (arg0
);
8175 op1
= expand_normal (arg1
);
8176 mode0
= insn_data
[icode
].operand
[0].mode
;
8177 mode1
= insn_data
[icode
].operand
[1].mode
;
8179 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8180 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
8181 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
8182 op1
= copy_to_mode_reg (mode1
, op1
);
8184 pat
= GEN_FCN (icode
) (op0
, op1
);
8192 /* Expand the dst builtins. */
8194 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
8197 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8198 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8199 tree arg0
, arg1
, arg2
;
8200 enum machine_mode mode0
, mode1
, mode2
;
8201 rtx pat
, op0
, op1
, op2
;
8202 const struct builtin_description
*d
;
8207 /* Handle DST variants. */
8209 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
8210 if (d
->code
== fcode
)
8212 arg0
= CALL_EXPR_ARG (exp
, 0);
8213 arg1
= CALL_EXPR_ARG (exp
, 1);
8214 arg2
= CALL_EXPR_ARG (exp
, 2);
8215 op0
= expand_normal (arg0
);
8216 op1
= expand_normal (arg1
);
8217 op2
= expand_normal (arg2
);
8218 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8219 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
8220 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
8222 /* Invalid arguments, bail out before generating bad rtl. */
8223 if (arg0
== error_mark_node
8224 || arg1
== error_mark_node
8225 || arg2
== error_mark_node
)
8230 if (TREE_CODE (arg2
) != INTEGER_CST
8231 || TREE_INT_CST_LOW (arg2
) & ~0x3)
8233 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
8237 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
8238 op0
= copy_to_mode_reg (Pmode
, op0
);
8239 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
8240 op1
= copy_to_mode_reg (mode1
, op1
);
8242 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
8252 /* Expand vec_init builtin. */
8254 altivec_expand_vec_init_builtin (tree type
, tree exp
, rtx target
)
8256 enum machine_mode tmode
= TYPE_MODE (type
);
8257 enum machine_mode inner_mode
= GET_MODE_INNER (tmode
);
8258 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
8259 rtvec v
= rtvec_alloc (n_elt
);
8261 gcc_assert (VECTOR_MODE_P (tmode
));
8262 gcc_assert (n_elt
== call_expr_nargs (exp
));
8264 for (i
= 0; i
< n_elt
; ++i
)
8266 rtx x
= expand_normal (CALL_EXPR_ARG (exp
, i
));
8267 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
8270 if (!target
|| !register_operand (target
, tmode
))
8271 target
= gen_reg_rtx (tmode
);
8273 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
8277 /* Return the integer constant in ARG. Constrain it to be in the range
8278 of the subparts of VEC_TYPE; issue an error if not. */
8281 get_element_number (tree vec_type
, tree arg
)
8283 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
8285 if (!host_integerp (arg
, 1)
8286 || (elt
= tree_low_cst (arg
, 1), elt
> max
))
8288 error ("selector must be an integer constant in the range 0..%wi", max
);
8295 /* Expand vec_set builtin. */
8297 altivec_expand_vec_set_builtin (tree exp
)
8299 enum machine_mode tmode
, mode1
;
8300 tree arg0
, arg1
, arg2
;
8304 arg0
= CALL_EXPR_ARG (exp
, 0);
8305 arg1
= CALL_EXPR_ARG (exp
, 1);
8306 arg2
= CALL_EXPR_ARG (exp
, 2);
8308 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
8309 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
8310 gcc_assert (VECTOR_MODE_P (tmode
));
8312 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, 0);
8313 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, 0);
8314 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
8316 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
8317 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
8319 op0
= force_reg (tmode
, op0
);
8320 op1
= force_reg (mode1
, op1
);
8322 rs6000_expand_vector_set (op0
, op1
, elt
);
8327 /* Expand vec_ext builtin. */
8329 altivec_expand_vec_ext_builtin (tree exp
, rtx target
)
8331 enum machine_mode tmode
, mode0
;
8336 arg0
= CALL_EXPR_ARG (exp
, 0);
8337 arg1
= CALL_EXPR_ARG (exp
, 1);
8339 op0
= expand_normal (arg0
);
8340 elt
= get_element_number (TREE_TYPE (arg0
), arg1
);
8342 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
8343 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
8344 gcc_assert (VECTOR_MODE_P (mode0
));
8346 op0
= force_reg (mode0
, op0
);
8348 if (optimize
|| !target
|| !register_operand (target
, tmode
))
8349 target
= gen_reg_rtx (tmode
);
8351 rs6000_expand_vector_extract (target
, op0
, elt
);
8356 /* Expand the builtin in EXP and store the result in TARGET. Store
8357 true in *EXPANDEDP if we found a builtin to expand. */
8359 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
8361 const struct builtin_description
*d
;
8362 const struct builtin_description_predicates
*dp
;
8364 enum insn_code icode
;
8365 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8368 enum machine_mode tmode
, mode0
;
8369 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8371 if (fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8372 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
8375 error ("unresolved overload for Altivec builtin %qF", fndecl
);
8379 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
8383 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
8387 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
8395 case ALTIVEC_BUILTIN_STVX
:
8396 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx
, exp
);
8397 case ALTIVEC_BUILTIN_STVEBX
:
8398 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, exp
);
8399 case ALTIVEC_BUILTIN_STVEHX
:
8400 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, exp
);
8401 case ALTIVEC_BUILTIN_STVEWX
:
8402 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, exp
);
8403 case ALTIVEC_BUILTIN_STVXL
:
8404 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, exp
);
8406 case ALTIVEC_BUILTIN_MFVSCR
:
8407 icode
= CODE_FOR_altivec_mfvscr
;
8408 tmode
= insn_data
[icode
].operand
[0].mode
;
8411 || GET_MODE (target
) != tmode
8412 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8413 target
= gen_reg_rtx (tmode
);
8415 pat
= GEN_FCN (icode
) (target
);
8421 case ALTIVEC_BUILTIN_MTVSCR
:
8422 icode
= CODE_FOR_altivec_mtvscr
;
8423 arg0
= CALL_EXPR_ARG (exp
, 0);
8424 op0
= expand_normal (arg0
);
8425 mode0
= insn_data
[icode
].operand
[0].mode
;
8427 /* If we got invalid arguments bail out before generating bad rtl. */
8428 if (arg0
== error_mark_node
)
8431 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8432 op0
= copy_to_mode_reg (mode0
, op0
);
8434 pat
= GEN_FCN (icode
) (op0
);
8439 case ALTIVEC_BUILTIN_DSSALL
:
8440 emit_insn (gen_altivec_dssall ());
8443 case ALTIVEC_BUILTIN_DSS
:
8444 icode
= CODE_FOR_altivec_dss
;
8445 arg0
= CALL_EXPR_ARG (exp
, 0);
8447 op0
= expand_normal (arg0
);
8448 mode0
= insn_data
[icode
].operand
[0].mode
;
8450 /* If we got invalid arguments bail out before generating bad rtl. */
8451 if (arg0
== error_mark_node
)
8454 if (TREE_CODE (arg0
) != INTEGER_CST
8455 || TREE_INT_CST_LOW (arg0
) & ~0x3)
8457 error ("argument to dss must be a 2-bit unsigned literal");
8461 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8462 op0
= copy_to_mode_reg (mode0
, op0
);
8464 emit_insn (gen_altivec_dss (op0
));
8467 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
8468 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
8469 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
8470 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
8471 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), exp
, target
);
8473 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
8474 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
8475 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
8476 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
8477 return altivec_expand_vec_set_builtin (exp
);
8479 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
8480 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
8481 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
8482 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
8483 return altivec_expand_vec_ext_builtin (exp
, target
);
8490 /* Expand abs* operations. */
8492 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
8493 if (d
->code
== fcode
)
8494 return altivec_expand_abs_builtin (d
->icode
, exp
, target
);
8496 /* Expand the AltiVec predicates. */
8497 dp
= bdesc_altivec_preds
;
8498 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
8499 if (dp
->code
== fcode
)
8500 return altivec_expand_predicate_builtin (dp
->icode
, dp
->opcode
,
8503 /* LV* are funky. We initialized them differently. */
8506 case ALTIVEC_BUILTIN_LVSL
:
8507 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
8509 case ALTIVEC_BUILTIN_LVSR
:
8510 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
8512 case ALTIVEC_BUILTIN_LVEBX
:
8513 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
8515 case ALTIVEC_BUILTIN_LVEHX
:
8516 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
8518 case ALTIVEC_BUILTIN_LVEWX
:
8519 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
8521 case ALTIVEC_BUILTIN_LVXL
:
8522 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
8524 case ALTIVEC_BUILTIN_LVX
:
8525 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx
,
8536 /* Expand the builtin in EXP and store the result in TARGET. Store
8537 true in *EXPANDEDP if we found a builtin to expand. */
8539 paired_expand_builtin (tree exp
, rtx target
, bool * expandedp
)
8541 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8542 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8543 const struct builtin_description
*d
;
8550 case PAIRED_BUILTIN_STX
:
8551 return paired_expand_stv_builtin (CODE_FOR_paired_stx
, exp
);
8552 case PAIRED_BUILTIN_LX
:
8553 return paired_expand_lv_builtin (CODE_FOR_paired_lx
, exp
, target
);
8559 /* Expand the paired predicates. */
8560 d
= bdesc_paired_preds
;
8561 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); i
++, d
++)
8562 if (d
->code
== fcode
)
8563 return paired_expand_predicate_builtin (d
->icode
, exp
, target
);
8569 /* Binops that need to be initialized manually, but can be expanded
8570 automagically by rs6000_expand_binop_builtin. */
8571 static struct builtin_description bdesc_2arg_spe
[] =
8573 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
8574 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
8575 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
8576 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
8577 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
8578 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
8579 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
8580 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
8581 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
8582 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
8583 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
8584 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
8585 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
8586 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
8587 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
8588 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
8589 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
8590 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
8591 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
8592 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
8593 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
8594 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
8597 /* Expand the builtin in EXP and store the result in TARGET. Store
8598 true in *EXPANDEDP if we found a builtin to expand.
8600 This expands the SPE builtins that are not simple unary and binary
8603 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
8605 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8607 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8608 enum insn_code icode
;
8609 enum machine_mode tmode
, mode0
;
8611 struct builtin_description
*d
;
8616 /* Syntax check for a 5-bit unsigned immediate. */
8619 case SPE_BUILTIN_EVSTDD
:
8620 case SPE_BUILTIN_EVSTDH
:
8621 case SPE_BUILTIN_EVSTDW
:
8622 case SPE_BUILTIN_EVSTWHE
:
8623 case SPE_BUILTIN_EVSTWHO
:
8624 case SPE_BUILTIN_EVSTWWE
:
8625 case SPE_BUILTIN_EVSTWWO
:
8626 arg1
= CALL_EXPR_ARG (exp
, 2);
8627 if (TREE_CODE (arg1
) != INTEGER_CST
8628 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
8630 error ("argument 2 must be a 5-bit unsigned literal");
8638 /* The evsplat*i instructions are not quite generic. */
8641 case SPE_BUILTIN_EVSPLATFI
:
8642 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
8644 case SPE_BUILTIN_EVSPLATI
:
8645 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
8651 d
= (struct builtin_description
*) bdesc_2arg_spe
;
8652 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
8653 if (d
->code
== fcode
)
8654 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
8656 d
= (struct builtin_description
*) bdesc_spe_predicates
;
8657 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
8658 if (d
->code
== fcode
)
8659 return spe_expand_predicate_builtin (d
->icode
, exp
, target
);
8661 d
= (struct builtin_description
*) bdesc_spe_evsel
;
8662 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
8663 if (d
->code
== fcode
)
8664 return spe_expand_evsel_builtin (d
->icode
, exp
, target
);
8668 case SPE_BUILTIN_EVSTDDX
:
8669 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, exp
);
8670 case SPE_BUILTIN_EVSTDHX
:
8671 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, exp
);
8672 case SPE_BUILTIN_EVSTDWX
:
8673 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, exp
);
8674 case SPE_BUILTIN_EVSTWHEX
:
8675 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, exp
);
8676 case SPE_BUILTIN_EVSTWHOX
:
8677 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, exp
);
8678 case SPE_BUILTIN_EVSTWWEX
:
8679 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, exp
);
8680 case SPE_BUILTIN_EVSTWWOX
:
8681 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, exp
);
8682 case SPE_BUILTIN_EVSTDD
:
8683 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, exp
);
8684 case SPE_BUILTIN_EVSTDH
:
8685 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, exp
);
8686 case SPE_BUILTIN_EVSTDW
:
8687 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, exp
);
8688 case SPE_BUILTIN_EVSTWHE
:
8689 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, exp
);
8690 case SPE_BUILTIN_EVSTWHO
:
8691 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, exp
);
8692 case SPE_BUILTIN_EVSTWWE
:
8693 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, exp
);
8694 case SPE_BUILTIN_EVSTWWO
:
8695 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, exp
);
8696 case SPE_BUILTIN_MFSPEFSCR
:
8697 icode
= CODE_FOR_spe_mfspefscr
;
8698 tmode
= insn_data
[icode
].operand
[0].mode
;
8701 || GET_MODE (target
) != tmode
8702 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8703 target
= gen_reg_rtx (tmode
);
8705 pat
= GEN_FCN (icode
) (target
);
8710 case SPE_BUILTIN_MTSPEFSCR
:
8711 icode
= CODE_FOR_spe_mtspefscr
;
8712 arg0
= CALL_EXPR_ARG (exp
, 0);
8713 op0
= expand_normal (arg0
);
8714 mode0
= insn_data
[icode
].operand
[0].mode
;
8716 if (arg0
== error_mark_node
)
8719 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8720 op0
= copy_to_mode_reg (mode0
, op0
);
8722 pat
= GEN_FCN (icode
) (op0
);
8735 paired_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
8737 rtx pat
, scratch
, tmp
;
8738 tree form
= CALL_EXPR_ARG (exp
, 0);
8739 tree arg0
= CALL_EXPR_ARG (exp
, 1);
8740 tree arg1
= CALL_EXPR_ARG (exp
, 2);
8741 rtx op0
= expand_normal (arg0
);
8742 rtx op1
= expand_normal (arg1
);
8743 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8744 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8748 if (TREE_CODE (form
) != INTEGER_CST
)
8750 error ("argument 1 of __builtin_paired_predicate must be a constant");
8754 form_int
= TREE_INT_CST_LOW (form
);
8756 gcc_assert (mode0
== mode1
);
8758 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
8762 || GET_MODE (target
) != SImode
8763 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
8764 target
= gen_reg_rtx (SImode
);
8765 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8766 op0
= copy_to_mode_reg (mode0
, op0
);
8767 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
8768 op1
= copy_to_mode_reg (mode1
, op1
);
8770 scratch
= gen_reg_rtx (CCFPmode
);
8772 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
8794 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
8797 error ("argument 1 of __builtin_paired_predicate is out of range");
8801 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
8802 emit_move_insn (target
, tmp
);
8807 spe_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
8809 rtx pat
, scratch
, tmp
;
8810 tree form
= CALL_EXPR_ARG (exp
, 0);
8811 tree arg0
= CALL_EXPR_ARG (exp
, 1);
8812 tree arg1
= CALL_EXPR_ARG (exp
, 2);
8813 rtx op0
= expand_normal (arg0
);
8814 rtx op1
= expand_normal (arg1
);
8815 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8816 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8820 if (TREE_CODE (form
) != INTEGER_CST
)
8822 error ("argument 1 of __builtin_spe_predicate must be a constant");
8826 form_int
= TREE_INT_CST_LOW (form
);
8828 gcc_assert (mode0
== mode1
);
8830 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
8834 || GET_MODE (target
) != SImode
8835 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
8836 target
= gen_reg_rtx (SImode
);
8838 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8839 op0
= copy_to_mode_reg (mode0
, op0
);
8840 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
8841 op1
= copy_to_mode_reg (mode1
, op1
);
8843 scratch
= gen_reg_rtx (CCmode
);
8845 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
8850 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
8851 _lower_. We use one compare, but look in different bits of the
8852 CR for each variant.
8854 There are 2 elements in each SPE simd type (upper/lower). The CR
8855 bits are set as follows:
8857 BIT0 | BIT 1 | BIT 2 | BIT 3
8858 U | L | (U | L) | (U & L)
8860 So, for an "all" relationship, BIT 3 would be set.
8861 For an "any" relationship, BIT 2 would be set. Etc.
8863 Following traditional nomenclature, these bits map to:
8865 BIT0 | BIT 1 | BIT 2 | BIT 3
8868 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
8873 /* All variant. OV bit. */
8875 /* We need to get to the OV bit, which is the ORDERED bit. We
8876 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
8877 that's ugly and will make validate_condition_mode die.
8878 So let's just use another pattern. */
8879 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
8881 /* Any variant. EQ bit. */
8885 /* Upper variant. LT bit. */
8889 /* Lower variant. GT bit. */
8894 error ("argument 1 of __builtin_spe_predicate is out of range");
8898 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
8899 emit_move_insn (target
, tmp
);
8904 /* The evsel builtins look like this:
8906 e = __builtin_spe_evsel_OP (a, b, c, d);
8910 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
8911 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
8915 spe_expand_evsel_builtin (enum insn_code icode
, tree exp
, rtx target
)
8918 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8919 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8920 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8921 tree arg3
= CALL_EXPR_ARG (exp
, 3);
8922 rtx op0
= expand_normal (arg0
);
8923 rtx op1
= expand_normal (arg1
);
8924 rtx op2
= expand_normal (arg2
);
8925 rtx op3
= expand_normal (arg3
);
8926 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8927 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8929 gcc_assert (mode0
== mode1
);
8931 if (arg0
== error_mark_node
|| arg1
== error_mark_node
8932 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
8936 || GET_MODE (target
) != mode0
8937 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
8938 target
= gen_reg_rtx (mode0
);
8940 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8941 op0
= copy_to_mode_reg (mode0
, op0
);
8942 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
8943 op1
= copy_to_mode_reg (mode0
, op1
);
8944 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
8945 op2
= copy_to_mode_reg (mode0
, op2
);
8946 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
8947 op3
= copy_to_mode_reg (mode0
, op3
);
8949 /* Generate the compare. */
8950 scratch
= gen_reg_rtx (CCmode
);
8951 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
8956 if (mode0
== V2SImode
)
8957 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
8959 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
8964 /* Expand an expression EXP that calls a built-in function,
8965 with result going to TARGET if that's convenient
8966 (and in mode MODE if that's convenient).
8967 SUBTARGET may be used as the target for computing one of EXP's operands.
8968 IGNORE is nonzero if the value is to be ignored. */
8971 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
8972 enum machine_mode mode ATTRIBUTE_UNUSED
,
8973 int ignore ATTRIBUTE_UNUSED
)
8975 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8976 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8977 const struct builtin_description
*d
;
8982 if (fcode
== RS6000_BUILTIN_RECIP
)
8983 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3
, exp
, target
);
8985 if (fcode
== RS6000_BUILTIN_RECIPF
)
8986 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3
, exp
, target
);
8988 if (fcode
== RS6000_BUILTIN_RSQRTF
)
8989 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2
, exp
, target
);
8991 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_LOAD
8992 || fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
8994 int icode
= (int) CODE_FOR_altivec_lvsr
;
8995 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8996 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
9000 gcc_assert (TARGET_ALTIVEC
);
9002 arg
= CALL_EXPR_ARG (exp
, 0);
9003 gcc_assert (TREE_CODE (TREE_TYPE (arg
)) == POINTER_TYPE
);
9004 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
9005 addr
= memory_address (mode
, op
);
9006 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
9010 /* For the load case need to negate the address. */
9011 op
= gen_reg_rtx (GET_MODE (addr
));
9012 emit_insn (gen_rtx_SET (VOIDmode
, op
,
9013 gen_rtx_NEG (GET_MODE (addr
), addr
)));
9015 op
= gen_rtx_MEM (mode
, op
);
9018 || GET_MODE (target
) != tmode
9019 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
9020 target
= gen_reg_rtx (tmode
);
9022 /*pat = gen_altivec_lvsr (target, op);*/
9023 pat
= GEN_FCN (icode
) (target
, op
);
9031 /* FIXME: There's got to be a nicer way to handle this case than
9032 constructing a new CALL_EXPR. */
9033 if (fcode
== ALTIVEC_BUILTIN_VCFUX
9034 || fcode
== ALTIVEC_BUILTIN_VCFSX
)
9036 if (call_expr_nargs (exp
) == 1)
9037 exp
= build_call_nary (TREE_TYPE (exp
), CALL_EXPR_FN (exp
),
9038 2, CALL_EXPR_ARG (exp
, 0), integer_zero_node
);
9043 ret
= altivec_expand_builtin (exp
, target
, &success
);
9050 ret
= spe_expand_builtin (exp
, target
, &success
);
9055 if (TARGET_PAIRED_FLOAT
)
9057 ret
= paired_expand_builtin (exp
, target
, &success
);
9063 gcc_assert (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
);
9065 /* Handle simple unary operations. */
9066 d
= (struct builtin_description
*) bdesc_1arg
;
9067 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
9068 if (d
->code
== fcode
)
9069 return rs6000_expand_unop_builtin (d
->icode
, exp
, target
);
9071 /* Handle simple binary operations. */
9072 d
= (struct builtin_description
*) bdesc_2arg
;
9073 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
9074 if (d
->code
== fcode
)
9075 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
9077 /* Handle simple ternary operations. */
9079 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
9080 if (d
->code
== fcode
)
9081 return rs6000_expand_ternop_builtin (d
->icode
, exp
, target
);
9087 build_opaque_vector_type (tree node
, int nunits
)
9089 node
= copy_node (node
);
9090 TYPE_MAIN_VARIANT (node
) = node
;
9091 return build_vector_type (node
, nunits
);
9095 rs6000_init_builtins (void)
9097 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
9098 V2SF_type_node
= build_vector_type (float_type_node
, 2);
9099 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
9100 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
9101 V4SF_type_node
= build_vector_type (float_type_node
, 4);
9102 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
9103 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
9105 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
9106 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
9107 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
9109 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
9110 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
9111 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
9112 opaque_V4SI_type_node
= copy_node (V4SI_type_node
);
9114 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
9115 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
9116 'vector unsigned short'. */
9118 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
9119 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
9120 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
9121 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
9123 long_integer_type_internal_node
= long_integer_type_node
;
9124 long_unsigned_type_internal_node
= long_unsigned_type_node
;
9125 intQI_type_internal_node
= intQI_type_node
;
9126 uintQI_type_internal_node
= unsigned_intQI_type_node
;
9127 intHI_type_internal_node
= intHI_type_node
;
9128 uintHI_type_internal_node
= unsigned_intHI_type_node
;
9129 intSI_type_internal_node
= intSI_type_node
;
9130 uintSI_type_internal_node
= unsigned_intSI_type_node
;
9131 float_type_internal_node
= float_type_node
;
9132 void_type_internal_node
= void_type_node
;
9134 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9135 get_identifier ("__bool char"),
9136 bool_char_type_node
));
9137 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9138 get_identifier ("__bool short"),
9139 bool_short_type_node
));
9140 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9141 get_identifier ("__bool int"),
9142 bool_int_type_node
));
9143 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9144 get_identifier ("__pixel"),
9147 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
9148 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
9149 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
9150 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
9152 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9153 get_identifier ("__vector unsigned char"),
9154 unsigned_V16QI_type_node
));
9155 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9156 get_identifier ("__vector signed char"),
9158 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9159 get_identifier ("__vector __bool char"),
9160 bool_V16QI_type_node
));
9162 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9163 get_identifier ("__vector unsigned short"),
9164 unsigned_V8HI_type_node
));
9165 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9166 get_identifier ("__vector signed short"),
9168 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9169 get_identifier ("__vector __bool short"),
9170 bool_V8HI_type_node
));
9172 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9173 get_identifier ("__vector unsigned int"),
9174 unsigned_V4SI_type_node
));
9175 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9176 get_identifier ("__vector signed int"),
9178 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9179 get_identifier ("__vector __bool int"),
9180 bool_V4SI_type_node
));
9182 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9183 get_identifier ("__vector float"),
9185 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
9186 get_identifier ("__vector __pixel"),
9187 pixel_V8HI_type_node
));
9189 if (TARGET_PAIRED_FLOAT
)
9190 paired_init_builtins ();
9192 spe_init_builtins ();
9194 altivec_init_builtins ();
9195 if (TARGET_ALTIVEC
|| TARGET_SPE
|| TARGET_PAIRED_FLOAT
)
9196 rs6000_common_init_builtins ();
9197 if (TARGET_PPC_GFXOPT
)
9199 tree ftype
= build_function_type_list (float_type_node
,
9203 def_builtin (MASK_PPC_GFXOPT
, "__builtin_recipdivf", ftype
,
9204 RS6000_BUILTIN_RECIPF
);
9206 ftype
= build_function_type_list (float_type_node
,
9209 def_builtin (MASK_PPC_GFXOPT
, "__builtin_rsqrtf", ftype
,
9210 RS6000_BUILTIN_RSQRTF
);
9214 tree ftype
= build_function_type_list (double_type_node
,
9218 def_builtin (MASK_POPCNTB
, "__builtin_recipdiv", ftype
,
9219 RS6000_BUILTIN_RECIP
);
9224 /* AIX libm provides clog as __clog. */
9225 if (built_in_decls
[BUILT_IN_CLOG
])
9226 set_user_assembler_name (built_in_decls
[BUILT_IN_CLOG
], "__clog");
9229 #ifdef SUBTARGET_INIT_BUILTINS
9230 SUBTARGET_INIT_BUILTINS
;
9234 /* Search through a set of builtins and enable the mask bits.
9235 DESC is an array of builtins.
9236 SIZE is the total number of builtins.
9237 START is the builtin enum at which to start.
9238 END is the builtin enum at which to end. */
9240 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
9241 enum rs6000_builtins start
,
9242 enum rs6000_builtins end
)
9246 for (i
= 0; i
< size
; ++i
)
9247 if (desc
[i
].code
== start
)
9253 for (; i
< size
; ++i
)
9255 /* Flip all the bits on. */
9256 desc
[i
].mask
= target_flags
;
9257 if (desc
[i
].code
== end
)
9263 spe_init_builtins (void)
9265 tree endlink
= void_list_node
;
9266 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
9267 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
9268 struct builtin_description
*d
;
9271 tree v2si_ftype_4_v2si
9272 = build_function_type
9273 (opaque_V2SI_type_node
,
9274 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9275 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9276 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9277 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9280 tree v2sf_ftype_4_v2sf
9281 = build_function_type
9282 (opaque_V2SF_type_node
,
9283 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9284 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9285 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9286 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9289 tree int_ftype_int_v2si_v2si
9290 = build_function_type
9292 tree_cons (NULL_TREE
, integer_type_node
,
9293 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9294 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9297 tree int_ftype_int_v2sf_v2sf
9298 = build_function_type
9300 tree_cons (NULL_TREE
, integer_type_node
,
9301 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9302 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
9305 tree void_ftype_v2si_puint_int
9306 = build_function_type (void_type_node
,
9307 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9308 tree_cons (NULL_TREE
, puint_type_node
,
9309 tree_cons (NULL_TREE
,
9313 tree void_ftype_v2si_puint_char
9314 = build_function_type (void_type_node
,
9315 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9316 tree_cons (NULL_TREE
, puint_type_node
,
9317 tree_cons (NULL_TREE
,
9321 tree void_ftype_v2si_pv2si_int
9322 = build_function_type (void_type_node
,
9323 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9324 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
9325 tree_cons (NULL_TREE
,
9329 tree void_ftype_v2si_pv2si_char
9330 = build_function_type (void_type_node
,
9331 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
9332 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
9333 tree_cons (NULL_TREE
,
9338 = build_function_type (void_type_node
,
9339 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
9342 = build_function_type (integer_type_node
, endlink
);
9344 tree v2si_ftype_pv2si_int
9345 = build_function_type (opaque_V2SI_type_node
,
9346 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
9347 tree_cons (NULL_TREE
, integer_type_node
,
9350 tree v2si_ftype_puint_int
9351 = build_function_type (opaque_V2SI_type_node
,
9352 tree_cons (NULL_TREE
, puint_type_node
,
9353 tree_cons (NULL_TREE
, integer_type_node
,
9356 tree v2si_ftype_pushort_int
9357 = build_function_type (opaque_V2SI_type_node
,
9358 tree_cons (NULL_TREE
, pushort_type_node
,
9359 tree_cons (NULL_TREE
, integer_type_node
,
9362 tree v2si_ftype_signed_char
9363 = build_function_type (opaque_V2SI_type_node
,
9364 tree_cons (NULL_TREE
, signed_char_type_node
,
9367 /* The initialization of the simple binary and unary builtins is
9368 done in rs6000_common_init_builtins, but we have to enable the
9369 mask bits here manually because we have run out of `target_flags'
9370 bits. We really need to redesign this mask business. */
9372 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
9373 ARRAY_SIZE (bdesc_2arg
),
9376 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
9377 ARRAY_SIZE (bdesc_1arg
),
9379 SPE_BUILTIN_EVSUBFUSIAAW
);
9380 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
9381 ARRAY_SIZE (bdesc_spe_predicates
),
9382 SPE_BUILTIN_EVCMPEQ
,
9383 SPE_BUILTIN_EVFSTSTLT
);
9384 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
9385 ARRAY_SIZE (bdesc_spe_evsel
),
9386 SPE_BUILTIN_EVSEL_CMPGTS
,
9387 SPE_BUILTIN_EVSEL_FSTSTEQ
);
9389 (*lang_hooks
.decls
.pushdecl
)
9390 (build_decl (TYPE_DECL
, get_identifier ("__ev64_opaque__"),
9391 opaque_V2SI_type_node
));
9393 /* Initialize irregular SPE builtins. */
9395 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
9396 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
9397 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
9398 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
9399 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
9400 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
9401 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
9402 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
9403 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
9404 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
9405 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
9406 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
9407 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
9408 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
9409 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
9410 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
9411 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
9412 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
9415 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
9416 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
9417 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
9418 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
9419 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
9420 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
9421 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
9422 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
9423 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
9424 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
9425 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
9426 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
9427 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
9428 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
9429 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
9430 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
9431 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
9432 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
9433 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
9434 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
9435 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
9436 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
9439 d
= (struct builtin_description
*) bdesc_spe_predicates
;
9440 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
9444 switch (insn_data
[d
->icode
].operand
[1].mode
)
9447 type
= int_ftype_int_v2si_v2si
;
9450 type
= int_ftype_int_v2sf_v2sf
;
9456 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9459 /* Evsel predicates. */
9460 d
= (struct builtin_description
*) bdesc_spe_evsel
;
9461 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
9465 switch (insn_data
[d
->icode
].operand
[1].mode
)
9468 type
= v2si_ftype_4_v2si
;
9471 type
= v2sf_ftype_4_v2sf
;
9477 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9482 paired_init_builtins (void)
9484 const struct builtin_description
*d
;
9486 tree endlink
= void_list_node
;
9488 tree int_ftype_int_v2sf_v2sf
9489 = build_function_type
9491 tree_cons (NULL_TREE
, integer_type_node
,
9492 tree_cons (NULL_TREE
, V2SF_type_node
,
9493 tree_cons (NULL_TREE
, V2SF_type_node
,
9495 tree pcfloat_type_node
=
9496 build_pointer_type (build_qualified_type
9497 (float_type_node
, TYPE_QUAL_CONST
));
9499 tree v2sf_ftype_long_pcfloat
= build_function_type_list (V2SF_type_node
,
9500 long_integer_type_node
,
9503 tree void_ftype_v2sf_long_pcfloat
=
9504 build_function_type_list (void_type_node
,
9506 long_integer_type_node
,
9511 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat
,
9515 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat
,
9516 PAIRED_BUILTIN_STX
);
9519 d
= bdesc_paired_preds
;
9520 for (i
= 0; i
< ARRAY_SIZE (bdesc_paired_preds
); ++i
, d
++)
9524 switch (insn_data
[d
->icode
].operand
[1].mode
)
9527 type
= int_ftype_int_v2sf_v2sf
;
9533 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9538 altivec_init_builtins (void)
9540 const struct builtin_description
*d
;
9541 const struct builtin_description_predicates
*dp
;
9545 tree pfloat_type_node
= build_pointer_type (float_type_node
);
9546 tree pint_type_node
= build_pointer_type (integer_type_node
);
9547 tree pshort_type_node
= build_pointer_type (short_integer_type_node
);
9548 tree pchar_type_node
= build_pointer_type (char_type_node
);
9550 tree pvoid_type_node
= build_pointer_type (void_type_node
);
9552 tree pcfloat_type_node
= build_pointer_type (build_qualified_type (float_type_node
, TYPE_QUAL_CONST
));
9553 tree pcint_type_node
= build_pointer_type (build_qualified_type (integer_type_node
, TYPE_QUAL_CONST
));
9554 tree pcshort_type_node
= build_pointer_type (build_qualified_type (short_integer_type_node
, TYPE_QUAL_CONST
));
9555 tree pcchar_type_node
= build_pointer_type (build_qualified_type (char_type_node
, TYPE_QUAL_CONST
));
9557 tree pcvoid_type_node
= build_pointer_type (build_qualified_type (void_type_node
, TYPE_QUAL_CONST
));
9559 tree int_ftype_opaque
9560 = build_function_type_list (integer_type_node
,
9561 opaque_V4SI_type_node
, NULL_TREE
);
9563 tree opaque_ftype_opaque_int
9564 = build_function_type_list (opaque_V4SI_type_node
,
9565 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
9566 tree opaque_ftype_opaque_opaque_int
9567 = build_function_type_list (opaque_V4SI_type_node
,
9568 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
9569 integer_type_node
, NULL_TREE
);
9570 tree int_ftype_int_opaque_opaque
9571 = build_function_type_list (integer_type_node
,
9572 integer_type_node
, opaque_V4SI_type_node
,
9573 opaque_V4SI_type_node
, NULL_TREE
);
9574 tree int_ftype_int_v4si_v4si
9575 = build_function_type_list (integer_type_node
,
9576 integer_type_node
, V4SI_type_node
,
9577 V4SI_type_node
, NULL_TREE
);
9578 tree v4sf_ftype_pcfloat
9579 = build_function_type_list (V4SF_type_node
, pcfloat_type_node
, NULL_TREE
);
9580 tree void_ftype_pfloat_v4sf
9581 = build_function_type_list (void_type_node
,
9582 pfloat_type_node
, V4SF_type_node
, NULL_TREE
);
9583 tree v4si_ftype_pcint
9584 = build_function_type_list (V4SI_type_node
, pcint_type_node
, NULL_TREE
);
9585 tree void_ftype_pint_v4si
9586 = build_function_type_list (void_type_node
,
9587 pint_type_node
, V4SI_type_node
, NULL_TREE
);
9588 tree v8hi_ftype_pcshort
9589 = build_function_type_list (V8HI_type_node
, pcshort_type_node
, NULL_TREE
);
9590 tree void_ftype_pshort_v8hi
9591 = build_function_type_list (void_type_node
,
9592 pshort_type_node
, V8HI_type_node
, NULL_TREE
);
9593 tree v16qi_ftype_pcchar
9594 = build_function_type_list (V16QI_type_node
, pcchar_type_node
, NULL_TREE
);
9595 tree void_ftype_pchar_v16qi
9596 = build_function_type_list (void_type_node
,
9597 pchar_type_node
, V16QI_type_node
, NULL_TREE
);
9598 tree void_ftype_v4si
9599 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
9600 tree v8hi_ftype_void
9601 = build_function_type (V8HI_type_node
, void_list_node
);
9602 tree void_ftype_void
9603 = build_function_type (void_type_node
, void_list_node
);
9605 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
9607 tree opaque_ftype_long_pcvoid
9608 = build_function_type_list (opaque_V4SI_type_node
,
9609 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9610 tree v16qi_ftype_long_pcvoid
9611 = build_function_type_list (V16QI_type_node
,
9612 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9613 tree v8hi_ftype_long_pcvoid
9614 = build_function_type_list (V8HI_type_node
,
9615 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9616 tree v4si_ftype_long_pcvoid
9617 = build_function_type_list (V4SI_type_node
,
9618 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
9620 tree void_ftype_opaque_long_pvoid
9621 = build_function_type_list (void_type_node
,
9622 opaque_V4SI_type_node
, long_integer_type_node
,
9623 pvoid_type_node
, NULL_TREE
);
9624 tree void_ftype_v4si_long_pvoid
9625 = build_function_type_list (void_type_node
,
9626 V4SI_type_node
, long_integer_type_node
,
9627 pvoid_type_node
, NULL_TREE
);
9628 tree void_ftype_v16qi_long_pvoid
9629 = build_function_type_list (void_type_node
,
9630 V16QI_type_node
, long_integer_type_node
,
9631 pvoid_type_node
, NULL_TREE
);
9632 tree void_ftype_v8hi_long_pvoid
9633 = build_function_type_list (void_type_node
,
9634 V8HI_type_node
, long_integer_type_node
,
9635 pvoid_type_node
, NULL_TREE
);
9636 tree int_ftype_int_v8hi_v8hi
9637 = build_function_type_list (integer_type_node
,
9638 integer_type_node
, V8HI_type_node
,
9639 V8HI_type_node
, NULL_TREE
);
9640 tree int_ftype_int_v16qi_v16qi
9641 = build_function_type_list (integer_type_node
,
9642 integer_type_node
, V16QI_type_node
,
9643 V16QI_type_node
, NULL_TREE
);
9644 tree int_ftype_int_v4sf_v4sf
9645 = build_function_type_list (integer_type_node
,
9646 integer_type_node
, V4SF_type_node
,
9647 V4SF_type_node
, NULL_TREE
);
9648 tree v4si_ftype_v4si
9649 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
9650 tree v8hi_ftype_v8hi
9651 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
9652 tree v16qi_ftype_v16qi
9653 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
9654 tree v4sf_ftype_v4sf
9655 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
9656 tree void_ftype_pcvoid_int_int
9657 = build_function_type_list (void_type_node
,
9658 pcvoid_type_node
, integer_type_node
,
9659 integer_type_node
, NULL_TREE
);
9661 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat
,
9662 ALTIVEC_BUILTIN_LD_INTERNAL_4sf
);
9663 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf
,
9664 ALTIVEC_BUILTIN_ST_INTERNAL_4sf
);
9665 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint
,
9666 ALTIVEC_BUILTIN_LD_INTERNAL_4si
);
9667 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si
,
9668 ALTIVEC_BUILTIN_ST_INTERNAL_4si
);
9669 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort
,
9670 ALTIVEC_BUILTIN_LD_INTERNAL_8hi
);
9671 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi
,
9672 ALTIVEC_BUILTIN_ST_INTERNAL_8hi
);
9673 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar
,
9674 ALTIVEC_BUILTIN_LD_INTERNAL_16qi
);
9675 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi
,
9676 ALTIVEC_BUILTIN_ST_INTERNAL_16qi
);
9677 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
9678 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
9679 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
9680 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
9681 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
9682 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
9683 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
9684 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
9685 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
9686 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
9687 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
9688 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
9689 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
9690 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
9691 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
9692 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
9693 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
9694 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
9695 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
9696 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
9697 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
9698 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
9699 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
9700 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
9701 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
9702 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
9703 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
9704 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
9705 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
9706 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
9708 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
9710 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
9711 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
9712 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
9713 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
9714 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
9715 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
9716 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
9717 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
9718 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
9719 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
9721 /* Add the DST variants. */
9723 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
9724 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
9726 /* Initialize the predicates. */
9727 dp
= bdesc_altivec_preds
;
9728 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
9730 enum machine_mode mode1
;
9732 bool is_overloaded
= dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9733 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
9738 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
9743 type
= int_ftype_int_opaque_opaque
;
9746 type
= int_ftype_int_v4si_v4si
;
9749 type
= int_ftype_int_v8hi_v8hi
;
9752 type
= int_ftype_int_v16qi_v16qi
;
9755 type
= int_ftype_int_v4sf_v4sf
;
9761 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
9764 /* Initialize the abs* operators. */
9766 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
9768 enum machine_mode mode0
;
9771 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
9776 type
= v4si_ftype_v4si
;
9779 type
= v8hi_ftype_v8hi
;
9782 type
= v16qi_ftype_v16qi
;
9785 type
= v4sf_ftype_v4sf
;
9791 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9798 /* Initialize target builtin that implements
9799 targetm.vectorize.builtin_mask_for_load. */
9801 decl
= add_builtin_function ("__builtin_altivec_mask_for_load",
9802 v16qi_ftype_long_pcvoid
,
9803 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
9804 BUILT_IN_MD
, NULL
, NULL_TREE
);
9805 TREE_READONLY (decl
) = 1;
9806 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
9807 altivec_builtin_mask_for_load
= decl
;
9810 /* Access to the vec_init patterns. */
9811 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
9812 integer_type_node
, integer_type_node
,
9813 integer_type_node
, NULL_TREE
);
9814 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4si", ftype
,
9815 ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
9817 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
9818 short_integer_type_node
,
9819 short_integer_type_node
,
9820 short_integer_type_node
,
9821 short_integer_type_node
,
9822 short_integer_type_node
,
9823 short_integer_type_node
,
9824 short_integer_type_node
, NULL_TREE
);
9825 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v8hi", ftype
,
9826 ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
9828 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
9829 char_type_node
, char_type_node
,
9830 char_type_node
, char_type_node
,
9831 char_type_node
, char_type_node
,
9832 char_type_node
, char_type_node
,
9833 char_type_node
, char_type_node
,
9834 char_type_node
, char_type_node
,
9835 char_type_node
, char_type_node
,
9836 char_type_node
, NULL_TREE
);
9837 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v16qi", ftype
,
9838 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
9840 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
9841 float_type_node
, float_type_node
,
9842 float_type_node
, NULL_TREE
);
9843 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4sf", ftype
,
9844 ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
9846 /* Access to the vec_set patterns. */
9847 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
9849 integer_type_node
, NULL_TREE
);
9850 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4si", ftype
,
9851 ALTIVEC_BUILTIN_VEC_SET_V4SI
);
9853 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
9855 integer_type_node
, NULL_TREE
);
9856 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v8hi", ftype
,
9857 ALTIVEC_BUILTIN_VEC_SET_V8HI
);
9859 ftype
= build_function_type_list (V8HI_type_node
, V16QI_type_node
,
9861 integer_type_node
, NULL_TREE
);
9862 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v16qi", ftype
,
9863 ALTIVEC_BUILTIN_VEC_SET_V16QI
);
9865 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
9867 integer_type_node
, NULL_TREE
);
9868 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4sf", ftype
,
9869 ALTIVEC_BUILTIN_VEC_SET_V4SF
);
9871 /* Access to the vec_extract patterns. */
9872 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
9873 integer_type_node
, NULL_TREE
);
9874 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4si", ftype
,
9875 ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
9877 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
9878 integer_type_node
, NULL_TREE
);
9879 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v8hi", ftype
,
9880 ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
9882 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
9883 integer_type_node
, NULL_TREE
);
9884 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v16qi", ftype
,
9885 ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
9887 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
9888 integer_type_node
, NULL_TREE
);
9889 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4sf", ftype
,
9890 ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
9894 rs6000_common_init_builtins (void)
9896 const struct builtin_description
*d
;
9899 tree v2sf_ftype_v2sf_v2sf_v2sf
9900 = build_function_type_list (V2SF_type_node
,
9901 V2SF_type_node
, V2SF_type_node
,
9902 V2SF_type_node
, NULL_TREE
);
9904 tree v4sf_ftype_v4sf_v4sf_v16qi
9905 = build_function_type_list (V4SF_type_node
,
9906 V4SF_type_node
, V4SF_type_node
,
9907 V16QI_type_node
, NULL_TREE
);
9908 tree v4si_ftype_v4si_v4si_v16qi
9909 = build_function_type_list (V4SI_type_node
,
9910 V4SI_type_node
, V4SI_type_node
,
9911 V16QI_type_node
, NULL_TREE
);
9912 tree v8hi_ftype_v8hi_v8hi_v16qi
9913 = build_function_type_list (V8HI_type_node
,
9914 V8HI_type_node
, V8HI_type_node
,
9915 V16QI_type_node
, NULL_TREE
);
9916 tree v16qi_ftype_v16qi_v16qi_v16qi
9917 = build_function_type_list (V16QI_type_node
,
9918 V16QI_type_node
, V16QI_type_node
,
9919 V16QI_type_node
, NULL_TREE
);
9921 = build_function_type_list (V4SI_type_node
, integer_type_node
, NULL_TREE
);
9923 = build_function_type_list (V8HI_type_node
, integer_type_node
, NULL_TREE
);
9924 tree v16qi_ftype_int
9925 = build_function_type_list (V16QI_type_node
, integer_type_node
, NULL_TREE
);
9926 tree v8hi_ftype_v16qi
9927 = build_function_type_list (V8HI_type_node
, V16QI_type_node
, NULL_TREE
);
9928 tree v4sf_ftype_v4sf
9929 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
9931 tree v2si_ftype_v2si_v2si
9932 = build_function_type_list (opaque_V2SI_type_node
,
9933 opaque_V2SI_type_node
,
9934 opaque_V2SI_type_node
, NULL_TREE
);
9936 tree v2sf_ftype_v2sf_v2sf_spe
9937 = build_function_type_list (opaque_V2SF_type_node
,
9938 opaque_V2SF_type_node
,
9939 opaque_V2SF_type_node
, NULL_TREE
);
9941 tree v2sf_ftype_v2sf_v2sf
9942 = build_function_type_list (V2SF_type_node
,
9944 V2SF_type_node
, NULL_TREE
);
9947 tree v2si_ftype_int_int
9948 = build_function_type_list (opaque_V2SI_type_node
,
9949 integer_type_node
, integer_type_node
,
9952 tree opaque_ftype_opaque
9953 = build_function_type_list (opaque_V4SI_type_node
,
9954 opaque_V4SI_type_node
, NULL_TREE
);
9956 tree v2si_ftype_v2si
9957 = build_function_type_list (opaque_V2SI_type_node
,
9958 opaque_V2SI_type_node
, NULL_TREE
);
9960 tree v2sf_ftype_v2sf_spe
9961 = build_function_type_list (opaque_V2SF_type_node
,
9962 opaque_V2SF_type_node
, NULL_TREE
);
9964 tree v2sf_ftype_v2sf
9965 = build_function_type_list (V2SF_type_node
,
9966 V2SF_type_node
, NULL_TREE
);
9968 tree v2sf_ftype_v2si
9969 = build_function_type_list (opaque_V2SF_type_node
,
9970 opaque_V2SI_type_node
, NULL_TREE
);
9972 tree v2si_ftype_v2sf
9973 = build_function_type_list (opaque_V2SI_type_node
,
9974 opaque_V2SF_type_node
, NULL_TREE
);
9976 tree v2si_ftype_v2si_char
9977 = build_function_type_list (opaque_V2SI_type_node
,
9978 opaque_V2SI_type_node
,
9979 char_type_node
, NULL_TREE
);
9981 tree v2si_ftype_int_char
9982 = build_function_type_list (opaque_V2SI_type_node
,
9983 integer_type_node
, char_type_node
, NULL_TREE
);
9985 tree v2si_ftype_char
9986 = build_function_type_list (opaque_V2SI_type_node
,
9987 char_type_node
, NULL_TREE
);
9989 tree int_ftype_int_int
9990 = build_function_type_list (integer_type_node
,
9991 integer_type_node
, integer_type_node
,
9994 tree opaque_ftype_opaque_opaque
9995 = build_function_type_list (opaque_V4SI_type_node
,
9996 opaque_V4SI_type_node
, opaque_V4SI_type_node
, NULL_TREE
);
9997 tree v4si_ftype_v4si_v4si
9998 = build_function_type_list (V4SI_type_node
,
9999 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
10000 tree v4sf_ftype_v4si_int
10001 = build_function_type_list (V4SF_type_node
,
10002 V4SI_type_node
, integer_type_node
, NULL_TREE
);
10003 tree v4si_ftype_v4sf_int
10004 = build_function_type_list (V4SI_type_node
,
10005 V4SF_type_node
, integer_type_node
, NULL_TREE
);
10006 tree v4si_ftype_v4si_int
10007 = build_function_type_list (V4SI_type_node
,
10008 V4SI_type_node
, integer_type_node
, NULL_TREE
);
10009 tree v8hi_ftype_v8hi_int
10010 = build_function_type_list (V8HI_type_node
,
10011 V8HI_type_node
, integer_type_node
, NULL_TREE
);
10012 tree v16qi_ftype_v16qi_int
10013 = build_function_type_list (V16QI_type_node
,
10014 V16QI_type_node
, integer_type_node
, NULL_TREE
);
10015 tree v16qi_ftype_v16qi_v16qi_int
10016 = build_function_type_list (V16QI_type_node
,
10017 V16QI_type_node
, V16QI_type_node
,
10018 integer_type_node
, NULL_TREE
);
10019 tree v8hi_ftype_v8hi_v8hi_int
10020 = build_function_type_list (V8HI_type_node
,
10021 V8HI_type_node
, V8HI_type_node
,
10022 integer_type_node
, NULL_TREE
);
10023 tree v4si_ftype_v4si_v4si_int
10024 = build_function_type_list (V4SI_type_node
,
10025 V4SI_type_node
, V4SI_type_node
,
10026 integer_type_node
, NULL_TREE
);
10027 tree v4sf_ftype_v4sf_v4sf_int
10028 = build_function_type_list (V4SF_type_node
,
10029 V4SF_type_node
, V4SF_type_node
,
10030 integer_type_node
, NULL_TREE
);
10031 tree v4sf_ftype_v4sf_v4sf
10032 = build_function_type_list (V4SF_type_node
,
10033 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10034 tree opaque_ftype_opaque_opaque_opaque
10035 = build_function_type_list (opaque_V4SI_type_node
,
10036 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
10037 opaque_V4SI_type_node
, NULL_TREE
);
10038 tree v4sf_ftype_v4sf_v4sf_v4si
10039 = build_function_type_list (V4SF_type_node
,
10040 V4SF_type_node
, V4SF_type_node
,
10041 V4SI_type_node
, NULL_TREE
);
10042 tree v4sf_ftype_v4sf_v4sf_v4sf
10043 = build_function_type_list (V4SF_type_node
,
10044 V4SF_type_node
, V4SF_type_node
,
10045 V4SF_type_node
, NULL_TREE
);
10046 tree v4si_ftype_v4si_v4si_v4si
10047 = build_function_type_list (V4SI_type_node
,
10048 V4SI_type_node
, V4SI_type_node
,
10049 V4SI_type_node
, NULL_TREE
);
10050 tree v8hi_ftype_v8hi_v8hi
10051 = build_function_type_list (V8HI_type_node
,
10052 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10053 tree v8hi_ftype_v8hi_v8hi_v8hi
10054 = build_function_type_list (V8HI_type_node
,
10055 V8HI_type_node
, V8HI_type_node
,
10056 V8HI_type_node
, NULL_TREE
);
10057 tree v4si_ftype_v8hi_v8hi_v4si
10058 = build_function_type_list (V4SI_type_node
,
10059 V8HI_type_node
, V8HI_type_node
,
10060 V4SI_type_node
, NULL_TREE
);
10061 tree v4si_ftype_v16qi_v16qi_v4si
10062 = build_function_type_list (V4SI_type_node
,
10063 V16QI_type_node
, V16QI_type_node
,
10064 V4SI_type_node
, NULL_TREE
);
10065 tree v16qi_ftype_v16qi_v16qi
10066 = build_function_type_list (V16QI_type_node
,
10067 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10068 tree v4si_ftype_v4sf_v4sf
10069 = build_function_type_list (V4SI_type_node
,
10070 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10071 tree v8hi_ftype_v16qi_v16qi
10072 = build_function_type_list (V8HI_type_node
,
10073 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10074 tree v4si_ftype_v8hi_v8hi
10075 = build_function_type_list (V4SI_type_node
,
10076 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10077 tree v8hi_ftype_v4si_v4si
10078 = build_function_type_list (V8HI_type_node
,
10079 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
10080 tree v16qi_ftype_v8hi_v8hi
10081 = build_function_type_list (V16QI_type_node
,
10082 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10083 tree v4si_ftype_v16qi_v4si
10084 = build_function_type_list (V4SI_type_node
,
10085 V16QI_type_node
, V4SI_type_node
, NULL_TREE
);
10086 tree v4si_ftype_v16qi_v16qi
10087 = build_function_type_list (V4SI_type_node
,
10088 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10089 tree v4si_ftype_v8hi_v4si
10090 = build_function_type_list (V4SI_type_node
,
10091 V8HI_type_node
, V4SI_type_node
, NULL_TREE
);
10092 tree v4si_ftype_v8hi
10093 = build_function_type_list (V4SI_type_node
, V8HI_type_node
, NULL_TREE
);
10094 tree int_ftype_v4si_v4si
10095 = build_function_type_list (integer_type_node
,
10096 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
10097 tree int_ftype_v4sf_v4sf
10098 = build_function_type_list (integer_type_node
,
10099 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
10100 tree int_ftype_v16qi_v16qi
10101 = build_function_type_list (integer_type_node
,
10102 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
10103 tree int_ftype_v8hi_v8hi
10104 = build_function_type_list (integer_type_node
,
10105 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
10107 /* Add the simple ternary operators. */
10109 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
10111 enum machine_mode mode0
, mode1
, mode2
, mode3
;
10113 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10114 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10125 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
10128 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10129 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10130 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
10131 mode3
= insn_data
[d
->icode
].operand
[3].mode
;
10134 /* When all four are of the same mode. */
10135 if (mode0
== mode1
&& mode1
== mode2
&& mode2
== mode3
)
10140 type
= opaque_ftype_opaque_opaque_opaque
;
10143 type
= v4si_ftype_v4si_v4si_v4si
;
10146 type
= v4sf_ftype_v4sf_v4sf_v4sf
;
10149 type
= v8hi_ftype_v8hi_v8hi_v8hi
;
10152 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
10155 type
= v2sf_ftype_v2sf_v2sf_v2sf
;
10158 gcc_unreachable ();
10161 else if (mode0
== mode1
&& mode1
== mode2
&& mode3
== V16QImode
)
10166 type
= v4si_ftype_v4si_v4si_v16qi
;
10169 type
= v4sf_ftype_v4sf_v4sf_v16qi
;
10172 type
= v8hi_ftype_v8hi_v8hi_v16qi
;
10175 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
10178 gcc_unreachable ();
10181 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
10182 && mode3
== V4SImode
)
10183 type
= v4si_ftype_v16qi_v16qi_v4si
;
10184 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
10185 && mode3
== V4SImode
)
10186 type
= v4si_ftype_v8hi_v8hi_v4si
;
10187 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
10188 && mode3
== V4SImode
)
10189 type
= v4sf_ftype_v4sf_v4sf_v4si
;
10191 /* vchar, vchar, vchar, 4-bit literal. */
10192 else if (mode0
== V16QImode
&& mode1
== mode0
&& mode2
== mode0
10193 && mode3
== QImode
)
10194 type
= v16qi_ftype_v16qi_v16qi_int
;
10196 /* vshort, vshort, vshort, 4-bit literal. */
10197 else if (mode0
== V8HImode
&& mode1
== mode0
&& mode2
== mode0
10198 && mode3
== QImode
)
10199 type
= v8hi_ftype_v8hi_v8hi_int
;
10201 /* vint, vint, vint, 4-bit literal. */
10202 else if (mode0
== V4SImode
&& mode1
== mode0
&& mode2
== mode0
10203 && mode3
== QImode
)
10204 type
= v4si_ftype_v4si_v4si_int
;
10206 /* vfloat, vfloat, vfloat, 4-bit literal. */
10207 else if (mode0
== V4SFmode
&& mode1
== mode0
&& mode2
== mode0
10208 && mode3
== QImode
)
10209 type
= v4sf_ftype_v4sf_v4sf_int
;
10212 gcc_unreachable ();
10214 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10217 /* Add the simple binary operators. */
10218 d
= (struct builtin_description
*) bdesc_2arg
;
10219 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
10221 enum machine_mode mode0
, mode1
, mode2
;
10223 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10224 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10234 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
10237 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10238 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10239 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
10242 /* When all three operands are of the same mode. */
10243 if (mode0
== mode1
&& mode1
== mode2
)
10248 type
= opaque_ftype_opaque_opaque
;
10251 type
= v4sf_ftype_v4sf_v4sf
;
10254 type
= v4si_ftype_v4si_v4si
;
10257 type
= v16qi_ftype_v16qi_v16qi
;
10260 type
= v8hi_ftype_v8hi_v8hi
;
10263 type
= v2si_ftype_v2si_v2si
;
10266 if (TARGET_PAIRED_FLOAT
)
10267 type
= v2sf_ftype_v2sf_v2sf
;
10269 type
= v2sf_ftype_v2sf_v2sf_spe
;
10272 type
= int_ftype_int_int
;
10275 gcc_unreachable ();
10279 /* A few other combos we really don't want to do manually. */
10281 /* vint, vfloat, vfloat. */
10282 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
)
10283 type
= v4si_ftype_v4sf_v4sf
;
10285 /* vshort, vchar, vchar. */
10286 else if (mode0
== V8HImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
10287 type
= v8hi_ftype_v16qi_v16qi
;
10289 /* vint, vshort, vshort. */
10290 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
10291 type
= v4si_ftype_v8hi_v8hi
;
10293 /* vshort, vint, vint. */
10294 else if (mode0
== V8HImode
&& mode1
== V4SImode
&& mode2
== V4SImode
)
10295 type
= v8hi_ftype_v4si_v4si
;
10297 /* vchar, vshort, vshort. */
10298 else if (mode0
== V16QImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
10299 type
= v16qi_ftype_v8hi_v8hi
;
10301 /* vint, vchar, vint. */
10302 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V4SImode
)
10303 type
= v4si_ftype_v16qi_v4si
;
10305 /* vint, vchar, vchar. */
10306 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
10307 type
= v4si_ftype_v16qi_v16qi
;
10309 /* vint, vshort, vint. */
10310 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V4SImode
)
10311 type
= v4si_ftype_v8hi_v4si
;
10313 /* vint, vint, 5-bit literal. */
10314 else if (mode0
== V4SImode
&& mode1
== V4SImode
&& mode2
== QImode
)
10315 type
= v4si_ftype_v4si_int
;
10317 /* vshort, vshort, 5-bit literal. */
10318 else if (mode0
== V8HImode
&& mode1
== V8HImode
&& mode2
== QImode
)
10319 type
= v8hi_ftype_v8hi_int
;
10321 /* vchar, vchar, 5-bit literal. */
10322 else if (mode0
== V16QImode
&& mode1
== V16QImode
&& mode2
== QImode
)
10323 type
= v16qi_ftype_v16qi_int
;
10325 /* vfloat, vint, 5-bit literal. */
10326 else if (mode0
== V4SFmode
&& mode1
== V4SImode
&& mode2
== QImode
)
10327 type
= v4sf_ftype_v4si_int
;
10329 /* vint, vfloat, 5-bit literal. */
10330 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== QImode
)
10331 type
= v4si_ftype_v4sf_int
;
10333 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== SImode
)
10334 type
= v2si_ftype_int_int
;
10336 else if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
10337 type
= v2si_ftype_v2si_char
;
10339 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== QImode
)
10340 type
= v2si_ftype_int_char
;
10345 gcc_assert (mode0
== SImode
);
10349 type
= int_ftype_v4si_v4si
;
10352 type
= int_ftype_v4sf_v4sf
;
10355 type
= int_ftype_v16qi_v16qi
;
10358 type
= int_ftype_v8hi_v8hi
;
10361 gcc_unreachable ();
10365 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10368 /* Add the simple unary operators. */
10369 d
= (struct builtin_description
*) bdesc_1arg
;
10370 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
10372 enum machine_mode mode0
, mode1
;
10374 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10375 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
10384 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
10387 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
10388 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
10391 if (mode0
== V4SImode
&& mode1
== QImode
)
10392 type
= v4si_ftype_int
;
10393 else if (mode0
== V8HImode
&& mode1
== QImode
)
10394 type
= v8hi_ftype_int
;
10395 else if (mode0
== V16QImode
&& mode1
== QImode
)
10396 type
= v16qi_ftype_int
;
10397 else if (mode0
== VOIDmode
&& mode1
== VOIDmode
)
10398 type
= opaque_ftype_opaque
;
10399 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
)
10400 type
= v4sf_ftype_v4sf
;
10401 else if (mode0
== V8HImode
&& mode1
== V16QImode
)
10402 type
= v8hi_ftype_v16qi
;
10403 else if (mode0
== V4SImode
&& mode1
== V8HImode
)
10404 type
= v4si_ftype_v8hi
;
10405 else if (mode0
== V2SImode
&& mode1
== V2SImode
)
10406 type
= v2si_ftype_v2si
;
10407 else if (mode0
== V2SFmode
&& mode1
== V2SFmode
)
10409 if (TARGET_PAIRED_FLOAT
)
10410 type
= v2sf_ftype_v2sf
;
10412 type
= v2sf_ftype_v2sf_spe
;
10414 else if (mode0
== V2SFmode
&& mode1
== V2SImode
)
10415 type
= v2sf_ftype_v2si
;
10416 else if (mode0
== V2SImode
&& mode1
== V2SFmode
)
10417 type
= v2si_ftype_v2sf
;
10418 else if (mode0
== V2SImode
&& mode1
== QImode
)
10419 type
= v2si_ftype_char
;
10421 gcc_unreachable ();
10423 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
10428 rs6000_init_libfuncs (void)
10430 if (DEFAULT_ABI
!= ABI_V4
&& TARGET_XCOFF
10431 && !TARGET_POWER2
&& !TARGET_POWERPC
)
10433 /* AIX library routines for float->int conversion. */
10434 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
10435 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
10436 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
10437 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
10440 if (!TARGET_IEEEQUAD
)
10441 /* AIX/Darwin/64-bit Linux quad floating point routines. */
10442 if (!TARGET_XL_COMPAT
)
10444 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
10445 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
10446 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
10447 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
10449 if (!(TARGET_HARD_FLOAT
&& (TARGET_FPRS
|| TARGET_E500_DOUBLE
)))
10451 set_optab_libfunc (neg_optab
, TFmode
, "__gcc_qneg");
10452 set_optab_libfunc (eq_optab
, TFmode
, "__gcc_qeq");
10453 set_optab_libfunc (ne_optab
, TFmode
, "__gcc_qne");
10454 set_optab_libfunc (gt_optab
, TFmode
, "__gcc_qgt");
10455 set_optab_libfunc (ge_optab
, TFmode
, "__gcc_qge");
10456 set_optab_libfunc (lt_optab
, TFmode
, "__gcc_qlt");
10457 set_optab_libfunc (le_optab
, TFmode
, "__gcc_qle");
10459 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "__gcc_stoq");
10460 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "__gcc_dtoq");
10461 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "__gcc_qtos");
10462 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "__gcc_qtod");
10463 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "__gcc_qtoi");
10464 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "__gcc_qtou");
10465 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "__gcc_itoq");
10466 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "__gcc_utoq");
10469 if (!(TARGET_HARD_FLOAT
&& TARGET_FPRS
))
10470 set_optab_libfunc (unord_optab
, TFmode
, "__gcc_qunord");
10474 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
10475 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
10476 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
10477 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
10481 /* 32-bit SVR4 quad floating point routines. */
10483 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
10484 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
10485 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
10486 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
10487 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
10488 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
10489 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
10491 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
10492 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
10493 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
10494 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
10495 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
10496 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
10498 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
10499 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
10500 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
10501 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
10502 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
10503 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
10504 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
10505 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "_q_utoq");
10510 /* Expand a block clear operation, and return 1 if successful. Return 0
10511 if we should let the compiler generate normal code.
10513 operands[0] is the destination
10514 operands[1] is the length
10515 operands[3] is the alignment */
10518 expand_block_clear (rtx operands
[])
10520 rtx orig_dest
= operands
[0];
10521 rtx bytes_rtx
= operands
[1];
10522 rtx align_rtx
= operands
[3];
10523 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
10524 HOST_WIDE_INT align
;
10525 HOST_WIDE_INT bytes
;
10530 /* If this is not a fixed size move, just call memcpy */
10534 /* This must be a fixed size alignment */
10535 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
10536 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
10538 /* Anything to clear? */
10539 bytes
= INTVAL (bytes_rtx
);
10543 /* Use the builtin memset after a point, to avoid huge code bloat.
10544 When optimize_size, avoid any significant code bloat; calling
10545 memset is about 4 instructions, so allow for one instruction to
10546 load zero and three to do clearing. */
10547 if (TARGET_ALTIVEC
&& align
>= 128)
10549 else if (TARGET_POWERPC64
&& align
>= 32)
10551 else if (TARGET_SPE
&& align
>= 64)
10556 if (optimize_size
&& bytes
> 3 * clear_step
)
10558 if (! optimize_size
&& bytes
> 8 * clear_step
)
10561 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
10563 enum machine_mode mode
= BLKmode
;
10566 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
10571 else if (bytes
>= 8 && TARGET_SPE
&& align
>= 64)
10576 else if (bytes
>= 8 && TARGET_POWERPC64
10577 /* 64-bit loads and stores require word-aligned
10579 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
10584 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
10585 { /* move 4 bytes */
10589 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
10590 { /* move 2 bytes */
10594 else /* move 1 byte at a time */
10600 dest
= adjust_address (orig_dest
, mode
, offset
);
10602 emit_move_insn (dest
, CONST0_RTX (mode
));
10609 /* Expand a block move operation, and return 1 if successful. Return 0
10610 if we should let the compiler generate normal code.
10612 operands[0] is the destination
10613 operands[1] is the source
10614 operands[2] is the length
10615 operands[3] is the alignment */
10617 #define MAX_MOVE_REG 4
10620 expand_block_move (rtx operands
[])
10622 rtx orig_dest
= operands
[0];
10623 rtx orig_src
= operands
[1];
10624 rtx bytes_rtx
= operands
[2];
10625 rtx align_rtx
= operands
[3];
10626 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
10631 rtx stores
[MAX_MOVE_REG
];
10634 /* If this is not a fixed size move, just call memcpy */
10638 /* This must be a fixed size alignment */
10639 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
10640 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
10642 /* Anything to move? */
10643 bytes
= INTVAL (bytes_rtx
);
10647 /* store_one_arg depends on expand_block_move to handle at least the size of
10648 reg_parm_stack_space. */
10649 if (bytes
> (TARGET_POWERPC64
? 64 : 32))
10652 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
10655 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
10656 rtx (*mov
) (rtx
, rtx
);
10658 enum machine_mode mode
= BLKmode
;
10661 /* Altivec first, since it will be faster than a string move
10662 when it applies, and usually not significantly larger. */
10663 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
10667 gen_func
.mov
= gen_movv4si
;
10669 else if (TARGET_SPE
&& bytes
>= 8 && align
>= 64)
10673 gen_func
.mov
= gen_movv2si
;
10675 else if (TARGET_STRING
10676 && bytes
> 24 /* move up to 32 bytes at a time */
10682 && ! fixed_regs
[10]
10683 && ! fixed_regs
[11]
10684 && ! fixed_regs
[12])
10686 move_bytes
= (bytes
> 32) ? 32 : bytes
;
10687 gen_func
.movmemsi
= gen_movmemsi_8reg
;
10689 else if (TARGET_STRING
10690 && bytes
> 16 /* move up to 24 bytes at a time */
10696 && ! fixed_regs
[10])
10698 move_bytes
= (bytes
> 24) ? 24 : bytes
;
10699 gen_func
.movmemsi
= gen_movmemsi_6reg
;
10701 else if (TARGET_STRING
10702 && bytes
> 8 /* move up to 16 bytes at a time */
10706 && ! fixed_regs
[8])
10708 move_bytes
= (bytes
> 16) ? 16 : bytes
;
10709 gen_func
.movmemsi
= gen_movmemsi_4reg
;
10711 else if (bytes
>= 8 && TARGET_POWERPC64
10712 /* 64-bit loads and stores require word-aligned
10714 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
10718 gen_func
.mov
= gen_movdi
;
10720 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
10721 { /* move up to 8 bytes at a time */
10722 move_bytes
= (bytes
> 8) ? 8 : bytes
;
10723 gen_func
.movmemsi
= gen_movmemsi_2reg
;
10725 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
10726 { /* move 4 bytes */
10729 gen_func
.mov
= gen_movsi
;
10731 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
10732 { /* move 2 bytes */
10735 gen_func
.mov
= gen_movhi
;
10737 else if (TARGET_STRING
&& bytes
> 1)
10738 { /* move up to 4 bytes at a time */
10739 move_bytes
= (bytes
> 4) ? 4 : bytes
;
10740 gen_func
.movmemsi
= gen_movmemsi_1reg
;
10742 else /* move 1 byte at a time */
10746 gen_func
.mov
= gen_movqi
;
10749 src
= adjust_address (orig_src
, mode
, offset
);
10750 dest
= adjust_address (orig_dest
, mode
, offset
);
10752 if (mode
!= BLKmode
)
10754 rtx tmp_reg
= gen_reg_rtx (mode
);
10756 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
10757 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
10760 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
10763 for (i
= 0; i
< num_reg
; i
++)
10764 emit_insn (stores
[i
]);
10768 if (mode
== BLKmode
)
10770 /* Move the address into scratch registers. The movmemsi
10771 patterns require zero offset. */
10772 if (!REG_P (XEXP (src
, 0)))
10774 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
10775 src
= replace_equiv_address (src
, src_reg
);
10777 set_mem_size (src
, GEN_INT (move_bytes
));
10779 if (!REG_P (XEXP (dest
, 0)))
10781 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
10782 dest
= replace_equiv_address (dest
, dest_reg
);
10784 set_mem_size (dest
, GEN_INT (move_bytes
));
10786 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
10787 GEN_INT (move_bytes
& 31),
10796 /* Return a string to perform a load_multiple operation.
10797 operands[0] is the vector.
10798 operands[1] is the source address.
10799 operands[2] is the first destination register. */
10802 rs6000_output_load_multiple (rtx operands
[3])
10804 /* We have to handle the case where the pseudo used to contain the address
10805 is assigned to one of the output registers. */
10807 int words
= XVECLEN (operands
[0], 0);
10810 if (XVECLEN (operands
[0], 0) == 1)
10811 return "{l|lwz} %2,0(%1)";
10813 for (i
= 0; i
< words
; i
++)
10814 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
10815 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
10819 xop
[0] = GEN_INT (4 * (words
-1));
10820 xop
[1] = operands
[1];
10821 xop
[2] = operands
[2];
10822 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
10827 xop
[0] = GEN_INT (4 * (words
-1));
10828 xop
[1] = operands
[1];
10829 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
10830 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
);
10835 for (j
= 0; j
< words
; j
++)
10838 xop
[0] = GEN_INT (j
* 4);
10839 xop
[1] = operands
[1];
10840 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
10841 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
10843 xop
[0] = GEN_INT (i
* 4);
10844 xop
[1] = operands
[1];
10845 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
10850 return "{lsi|lswi} %2,%1,%N0";
10854 /* A validation routine: say whether CODE, a condition code, and MODE
10855 match. The other alternatives either don't make sense or should
10856 never be generated. */
10859 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
10861 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
10862 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
10863 && GET_MODE_CLASS (mode
) == MODE_CC
);
10865 /* These don't make sense. */
10866 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
10867 || mode
!= CCUNSmode
);
10869 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
10870 || mode
== CCUNSmode
);
10872 gcc_assert (mode
== CCFPmode
10873 || (code
!= ORDERED
&& code
!= UNORDERED
10874 && code
!= UNEQ
&& code
!= LTGT
10875 && code
!= UNGT
&& code
!= UNLT
10876 && code
!= UNGE
&& code
!= UNLE
));
10878 /* These should never be generated except for
10879 flag_finite_math_only. */
10880 gcc_assert (mode
!= CCFPmode
10881 || flag_finite_math_only
10882 || (code
!= LE
&& code
!= GE
10883 && code
!= UNEQ
&& code
!= LTGT
10884 && code
!= UNGT
&& code
!= UNLT
));
10886 /* These are invalid; the information is not there. */
10887 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
10891 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
10892 mask required to convert the result of a rotate insn into a shift
10893 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
10896 includes_lshift_p (rtx shiftop
, rtx andop
)
10898 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
10900 shift_mask
<<= INTVAL (shiftop
);
10902 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
10905 /* Similar, but for right shift. */
10908 includes_rshift_p (rtx shiftop
, rtx andop
)
10910 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
10912 shift_mask
>>= INTVAL (shiftop
);
10914 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
10917 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
10918 to perform a left shift. It must have exactly SHIFTOP least
10919 significant 0's, then one or more 1's, then zero or more 0's. */
10922 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
10924 if (GET_CODE (andop
) == CONST_INT
)
10926 HOST_WIDE_INT c
, lsb
, shift_mask
;
10928 c
= INTVAL (andop
);
10929 if (c
== 0 || c
== ~0)
10933 shift_mask
<<= INTVAL (shiftop
);
10935 /* Find the least significant one bit. */
10938 /* It must coincide with the LSB of the shift mask. */
10939 if (-lsb
!= shift_mask
)
10942 /* Invert to look for the next transition (if any). */
10945 /* Remove the low group of ones (originally low group of zeros). */
10948 /* Again find the lsb, and check we have all 1's above. */
10952 else if (GET_CODE (andop
) == CONST_DOUBLE
10953 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
10955 HOST_WIDE_INT low
, high
, lsb
;
10956 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
10958 low
= CONST_DOUBLE_LOW (andop
);
10959 if (HOST_BITS_PER_WIDE_INT
< 64)
10960 high
= CONST_DOUBLE_HIGH (andop
);
10962 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
10963 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
10966 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
10968 shift_mask_high
= ~0;
10969 if (INTVAL (shiftop
) > 32)
10970 shift_mask_high
<<= INTVAL (shiftop
) - 32;
10972 lsb
= high
& -high
;
10974 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
10980 lsb
= high
& -high
;
10981 return high
== -lsb
;
10984 shift_mask_low
= ~0;
10985 shift_mask_low
<<= INTVAL (shiftop
);
10989 if (-lsb
!= shift_mask_low
)
10992 if (HOST_BITS_PER_WIDE_INT
< 64)
10997 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
10999 lsb
= high
& -high
;
11000 return high
== -lsb
;
11004 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
11010 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
11011 to perform a left shift. It must have SHIFTOP or more least
11012 significant 0's, with the remainder of the word 1's. */
11015 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
11017 if (GET_CODE (andop
) == CONST_INT
)
11019 HOST_WIDE_INT c
, lsb
, shift_mask
;
11022 shift_mask
<<= INTVAL (shiftop
);
11023 c
= INTVAL (andop
);
11025 /* Find the least significant one bit. */
11028 /* It must be covered by the shift mask.
11029 This test also rejects c == 0. */
11030 if ((lsb
& shift_mask
) == 0)
11033 /* Check we have all 1's above the transition, and reject all 1's. */
11034 return c
== -lsb
&& lsb
!= 1;
11036 else if (GET_CODE (andop
) == CONST_DOUBLE
11037 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
11039 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
11041 low
= CONST_DOUBLE_LOW (andop
);
11043 if (HOST_BITS_PER_WIDE_INT
< 64)
11045 HOST_WIDE_INT high
, shift_mask_high
;
11047 high
= CONST_DOUBLE_HIGH (andop
);
11051 shift_mask_high
= ~0;
11052 if (INTVAL (shiftop
) > 32)
11053 shift_mask_high
<<= INTVAL (shiftop
) - 32;
11055 lsb
= high
& -high
;
11057 if ((lsb
& shift_mask_high
) == 0)
11060 return high
== -lsb
;
11066 shift_mask_low
= ~0;
11067 shift_mask_low
<<= INTVAL (shiftop
);
11071 if ((lsb
& shift_mask_low
) == 0)
11074 return low
== -lsb
&& lsb
!= 1;
11080 /* Return 1 if operands will generate a valid arguments to rlwimi
11081 instruction for insert with right shift in 64-bit mode. The mask may
11082 not start on the first bit or stop on the last bit because wrap-around
11083 effects of instruction do not correspond to semantics of RTL insn. */
11086 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
11088 if (INTVAL (startop
) > 32
11089 && INTVAL (startop
) < 64
11090 && INTVAL (sizeop
) > 1
11091 && INTVAL (sizeop
) + INTVAL (startop
) < 64
11092 && INTVAL (shiftop
) > 0
11093 && INTVAL (sizeop
) + INTVAL (shiftop
) < 32
11094 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
11100 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
11101 for lfq and stfq insns iff the registers are hard registers. */
11104 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
11106 /* We might have been passed a SUBREG. */
11107 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
11110 /* We might have been passed non floating point registers. */
11111 if (!FP_REGNO_P (REGNO (reg1
))
11112 || !FP_REGNO_P (REGNO (reg2
)))
11115 return (REGNO (reg1
) == REGNO (reg2
) - 1);
11118 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
11119 addr1 and addr2 must be in consecutive memory locations
11120 (addr2 == addr1 + 8). */
11123 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
11126 unsigned int reg1
, reg2
;
11127 int offset1
, offset2
;
11129 /* The mems cannot be volatile. */
11130 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
11133 addr1
= XEXP (mem1
, 0);
11134 addr2
= XEXP (mem2
, 0);
11136 /* Extract an offset (if used) from the first addr. */
11137 if (GET_CODE (addr1
) == PLUS
)
11139 /* If not a REG, return zero. */
11140 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
11144 reg1
= REGNO (XEXP (addr1
, 0));
11145 /* The offset must be constant! */
11146 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
11148 offset1
= INTVAL (XEXP (addr1
, 1));
11151 else if (GET_CODE (addr1
) != REG
)
11155 reg1
= REGNO (addr1
);
11156 /* This was a simple (mem (reg)) expression. Offset is 0. */
11160 /* And now for the second addr. */
11161 if (GET_CODE (addr2
) == PLUS
)
11163 /* If not a REG, return zero. */
11164 if (GET_CODE (XEXP (addr2
, 0)) != REG
)
11168 reg2
= REGNO (XEXP (addr2
, 0));
11169 /* The offset must be constant. */
11170 if (GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
11172 offset2
= INTVAL (XEXP (addr2
, 1));
11175 else if (GET_CODE (addr2
) != REG
)
11179 reg2
= REGNO (addr2
);
11180 /* This was a simple (mem (reg)) expression. Offset is 0. */
11184 /* Both of these must have the same base register. */
11188 /* The offset for the second addr must be 8 more than the first addr. */
11189 if (offset2
!= offset1
+ 8)
11192 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
11199 rs6000_secondary_memory_needed_rtx (enum machine_mode mode
)
11201 static bool eliminated
= false;
11202 if (mode
!= SDmode
)
11203 return assign_stack_local (mode
, GET_MODE_SIZE (mode
), 0);
11206 rtx mem
= cfun
->machine
->sdmode_stack_slot
;
11207 gcc_assert (mem
!= NULL_RTX
);
11211 mem
= eliminate_regs (mem
, VOIDmode
, NULL_RTX
);
11212 cfun
->machine
->sdmode_stack_slot
= mem
;
11220 rs6000_check_sdmode (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
11222 /* Don't walk into types. */
11223 if (*tp
== NULL_TREE
|| *tp
== error_mark_node
|| TYPE_P (*tp
))
11225 *walk_subtrees
= 0;
11229 switch (TREE_CODE (*tp
))
11237 case ALIGN_INDIRECT_REF
:
11238 case MISALIGNED_INDIRECT_REF
:
11239 case VIEW_CONVERT_EXPR
:
11240 if (TYPE_MODE (TREE_TYPE (*tp
)) == SDmode
)
11251 /* Allocate a 64-bit stack slot to be used for copying SDmode
11252 values through if this function has any SDmode references. */
11255 rs6000_alloc_sdmode_stack_slot (void)
11259 block_stmt_iterator bsi
;
11261 gcc_assert (cfun
->machine
->sdmode_stack_slot
== NULL_RTX
);
11264 for (bsi
= bsi_start (bb
); !bsi_end_p (bsi
); bsi_next (&bsi
))
11266 tree ret
= walk_tree_without_duplicates (bsi_stmt_ptr (bsi
),
11267 rs6000_check_sdmode
, NULL
);
11270 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
11271 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
11277 /* Check for any SDmode parameters of the function. */
11278 for (t
= DECL_ARGUMENTS (cfun
->decl
); t
; t
= TREE_CHAIN (t
))
11280 if (TREE_TYPE (t
) == error_mark_node
)
11283 if (TYPE_MODE (TREE_TYPE (t
)) == SDmode
11284 || TYPE_MODE (DECL_ARG_TYPE (t
)) == SDmode
)
11286 rtx stack
= assign_stack_local (DDmode
, GET_MODE_SIZE (DDmode
), 0);
11287 cfun
->machine
->sdmode_stack_slot
= adjust_address_nv (stack
,
11295 rs6000_instantiate_decls (void)
11297 if (cfun
->machine
->sdmode_stack_slot
!= NULL_RTX
)
11298 instantiate_decl_rtl (cfun
->machine
->sdmode_stack_slot
);
11301 /* Return the register class of a scratch register needed to copy IN into
11302 or out of a register in CLASS in MODE. If it can be done directly,
11303 NO_REGS is returned. */
11306 rs6000_secondary_reload_class (enum reg_class
class,
11307 enum machine_mode mode ATTRIBUTE_UNUSED
,
11312 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
11314 && MACHOPIC_INDIRECT
11318 /* We cannot copy a symbolic operand directly into anything
11319 other than BASE_REGS for TARGET_ELF. So indicate that a
11320 register from BASE_REGS is needed as an intermediate
11323 On Darwin, pic addresses require a load from memory, which
11324 needs a base register. */
11325 if (class != BASE_REGS
11326 && (GET_CODE (in
) == SYMBOL_REF
11327 || GET_CODE (in
) == HIGH
11328 || GET_CODE (in
) == LABEL_REF
11329 || GET_CODE (in
) == CONST
))
11333 if (GET_CODE (in
) == REG
)
11335 regno
= REGNO (in
);
11336 if (regno
>= FIRST_PSEUDO_REGISTER
)
11338 regno
= true_regnum (in
);
11339 if (regno
>= FIRST_PSEUDO_REGISTER
)
11343 else if (GET_CODE (in
) == SUBREG
)
11345 regno
= true_regnum (in
);
11346 if (regno
>= FIRST_PSEUDO_REGISTER
)
11352 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
11354 if (class == GENERAL_REGS
|| class == BASE_REGS
11355 || (regno
>= 0 && INT_REGNO_P (regno
)))
11358 /* Constants, memory, and FP registers can go into FP registers. */
11359 if ((regno
== -1 || FP_REGNO_P (regno
))
11360 && (class == FLOAT_REGS
|| class == NON_SPECIAL_REGS
))
11361 return (mode
!= SDmode
) ? NO_REGS
: GENERAL_REGS
;
11363 /* Memory, and AltiVec registers can go into AltiVec registers. */
11364 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
11365 && class == ALTIVEC_REGS
)
11368 /* We can copy among the CR registers. */
11369 if ((class == CR_REGS
|| class == CR0_REGS
)
11370 && regno
>= 0 && CR_REGNO_P (regno
))
11373 /* Otherwise, we need GENERAL_REGS. */
11374 return GENERAL_REGS
;
11377 /* Given a comparison operation, return the bit number in CCR to test. We
11378 know this is a valid comparison.
11380 SCC_P is 1 if this is for an scc. That means that %D will have been
11381 used instead of %C, so the bits will be in different places.
11383 Return -1 if OP isn't a valid comparison for some reason. */
11386 ccr_bit (rtx op
, int scc_p
)
11388 enum rtx_code code
= GET_CODE (op
);
11389 enum machine_mode cc_mode
;
11394 if (!COMPARISON_P (op
))
11397 reg
= XEXP (op
, 0);
11399 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
11401 cc_mode
= GET_MODE (reg
);
11402 cc_regnum
= REGNO (reg
);
11403 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
11405 validate_condition_mode (code
, cc_mode
);
11407 /* When generating a sCOND operation, only positive conditions are
11410 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
11411 || code
== GTU
|| code
== LTU
);
11416 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
11418 return base_bit
+ 2;
11419 case GT
: case GTU
: case UNLE
:
11420 return base_bit
+ 1;
11421 case LT
: case LTU
: case UNGE
:
11423 case ORDERED
: case UNORDERED
:
11424 return base_bit
+ 3;
11427 /* If scc, we will have done a cror to put the bit in the
11428 unordered position. So test that bit. For integer, this is ! LT
11429 unless this is an scc insn. */
11430 return scc_p
? base_bit
+ 3 : base_bit
;
11433 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
11436 gcc_unreachable ();
11440 /* Return the GOT register. */
11443 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
11445 /* The second flow pass currently (June 1999) can't update
11446 regs_ever_live without disturbing other parts of the compiler, so
11447 update it here to make the prolog/epilogue code happy. */
11448 if (!can_create_pseudo_p ()
11449 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
))
11450 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM
, true);
11452 current_function_uses_pic_offset_table
= 1;
11454 return pic_offset_table_rtx
;
11457 /* Function to init struct machine_function.
11458 This will be called, via a pointer variable,
11459 from push_function_context. */
11461 static struct machine_function
*
11462 rs6000_init_machine_status (void)
11464 return ggc_alloc_cleared (sizeof (machine_function
));
11467 /* These macros test for integers and extract the low-order bits. */
11469 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
11470 && GET_MODE (X) == VOIDmode)
11472 #define INT_LOWPART(X) \
11473 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
11476 extract_MB (rtx op
)
11479 unsigned long val
= INT_LOWPART (op
);
11481 /* If the high bit is zero, the value is the first 1 bit we find
11483 if ((val
& 0x80000000) == 0)
11485 gcc_assert (val
& 0xffffffff);
11488 while (((val
<<= 1) & 0x80000000) == 0)
11493 /* If the high bit is set and the low bit is not, or the mask is all
11494 1's, the value is zero. */
11495 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
11498 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11501 while (((val
>>= 1) & 1) != 0)
11508 extract_ME (rtx op
)
11511 unsigned long val
= INT_LOWPART (op
);
11513 /* If the low bit is zero, the value is the first 1 bit we find from
11515 if ((val
& 1) == 0)
11517 gcc_assert (val
& 0xffffffff);
11520 while (((val
>>= 1) & 1) == 0)
11526 /* If the low bit is set and the high bit is not, or the mask is all
11527 1's, the value is 31. */
11528 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
11531 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11534 while (((val
<<= 1) & 0x80000000) != 0)
11540 /* Locate some local-dynamic symbol still in use by this function
11541 so that we can print its name in some tls_ld pattern. */
11543 static const char *
11544 rs6000_get_some_local_dynamic_name (void)
11548 if (cfun
->machine
->some_ld_name
)
11549 return cfun
->machine
->some_ld_name
;
11551 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
11553 && for_each_rtx (&PATTERN (insn
),
11554 rs6000_get_some_local_dynamic_name_1
, 0))
11555 return cfun
->machine
->some_ld_name
;
11557 gcc_unreachable ();
11560 /* Helper function for rs6000_get_some_local_dynamic_name. */
11563 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
11567 if (GET_CODE (x
) == SYMBOL_REF
)
11569 const char *str
= XSTR (x
, 0);
11570 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
11572 cfun
->machine
->some_ld_name
= str
;
11580 /* Write out a function code label. */
11583 rs6000_output_function_entry (FILE *file
, const char *fname
)
11585 if (fname
[0] != '.')
11587 switch (DEFAULT_ABI
)
11590 gcc_unreachable ();
11596 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
11605 RS6000_OUTPUT_BASENAME (file
, fname
);
11607 assemble_name (file
, fname
);
11610 /* Print an operand. Recognize special options, documented below. */
11613 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
11614 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
11616 #define SMALL_DATA_RELOC "sda21"
11617 #define SMALL_DATA_REG 0
11621 print_operand (FILE *file
, rtx x
, int code
)
11625 unsigned HOST_WIDE_INT uval
;
11630 /* Write out an instruction after the call which may be replaced
11631 with glue code by the loader. This depends on the AIX version. */
11632 asm_fprintf (file
, RS6000_CALL_GLUE
);
11635 /* %a is output_address. */
11638 /* If X is a constant integer whose low-order 5 bits are zero,
11639 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
11640 in the AIX assembler where "sri" with a zero shift count
11641 writes a trash instruction. */
11642 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
11649 /* If constant, low-order 16 bits of constant, unsigned.
11650 Otherwise, write normally. */
11652 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
11654 print_operand (file
, x
, 0);
11658 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
11659 for 64-bit mask direction. */
11660 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
11663 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
11667 /* X is a CR register. Print the number of the GT bit of the CR. */
11668 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
11669 output_operand_lossage ("invalid %%E value");
11671 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
11675 /* Like 'J' but get to the GT bit only. */
11676 gcc_assert (GET_CODE (x
) == REG
);
11678 /* Bit 1 is GT bit. */
11679 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 1;
11681 /* Add one for shift count in rlinm for scc. */
11682 fprintf (file
, "%d", i
+ 1);
11686 /* X is a CR register. Print the number of the EQ bit of the CR */
11687 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
11688 output_operand_lossage ("invalid %%E value");
11690 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
11694 /* X is a CR register. Print the shift count needed to move it
11695 to the high-order four bits. */
11696 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
11697 output_operand_lossage ("invalid %%f value");
11699 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
11703 /* Similar, but print the count for the rotate in the opposite
11705 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
11706 output_operand_lossage ("invalid %%F value");
11708 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
11712 /* X is a constant integer. If it is negative, print "m",
11713 otherwise print "z". This is to make an aze or ame insn. */
11714 if (GET_CODE (x
) != CONST_INT
)
11715 output_operand_lossage ("invalid %%G value");
11716 else if (INTVAL (x
) >= 0)
11723 /* If constant, output low-order five bits. Otherwise, write
11726 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
11728 print_operand (file
, x
, 0);
11732 /* If constant, output low-order six bits. Otherwise, write
11735 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
11737 print_operand (file
, x
, 0);
11741 /* Print `i' if this is a constant, else nothing. */
11747 /* Write the bit number in CCR for jump. */
11748 i
= ccr_bit (x
, 0);
11750 output_operand_lossage ("invalid %%j code");
11752 fprintf (file
, "%d", i
);
11756 /* Similar, but add one for shift count in rlinm for scc and pass
11757 scc flag to `ccr_bit'. */
11758 i
= ccr_bit (x
, 1);
11760 output_operand_lossage ("invalid %%J code");
11762 /* If we want bit 31, write a shift count of zero, not 32. */
11763 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
11767 /* X must be a constant. Write the 1's complement of the
11770 output_operand_lossage ("invalid %%k value");
11772 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
11776 /* X must be a symbolic constant on ELF. Write an
11777 expression suitable for an 'addi' that adds in the low 16
11778 bits of the MEM. */
11779 if (GET_CODE (x
) != CONST
)
11781 print_operand_address (file
, x
);
11782 fputs ("@l", file
);
11786 if (GET_CODE (XEXP (x
, 0)) != PLUS
11787 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
11788 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
11789 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
11790 output_operand_lossage ("invalid %%K value");
11791 print_operand_address (file
, XEXP (XEXP (x
, 0), 0));
11792 fputs ("@l", file
);
11793 /* For GNU as, there must be a non-alphanumeric character
11794 between 'l' and the number. The '-' is added by
11795 print_operand() already. */
11796 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
11798 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
11802 /* %l is output_asm_label. */
11805 /* Write second word of DImode or DFmode reference. Works on register
11806 or non-indexed memory only. */
11807 if (GET_CODE (x
) == REG
)
11808 fputs (reg_names
[REGNO (x
) + 1], file
);
11809 else if (GET_CODE (x
) == MEM
)
11811 /* Handle possible auto-increment. Since it is pre-increment and
11812 we have already done it, we can just use an offset of word. */
11813 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
11814 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
11815 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
11817 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
11818 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
11821 output_address (XEXP (adjust_address_nv (x
, SImode
,
11825 if (small_data_operand (x
, GET_MODE (x
)))
11826 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
11827 reg_names
[SMALL_DATA_REG
]);
11832 /* MB value for a mask operand. */
11833 if (! mask_operand (x
, SImode
))
11834 output_operand_lossage ("invalid %%m value");
11836 fprintf (file
, "%d", extract_MB (x
));
11840 /* ME value for a mask operand. */
11841 if (! mask_operand (x
, SImode
))
11842 output_operand_lossage ("invalid %%M value");
11844 fprintf (file
, "%d", extract_ME (x
));
11847 /* %n outputs the negative of its operand. */
11850 /* Write the number of elements in the vector times 4. */
11851 if (GET_CODE (x
) != PARALLEL
)
11852 output_operand_lossage ("invalid %%N value");
11854 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
11858 /* Similar, but subtract 1 first. */
11859 if (GET_CODE (x
) != PARALLEL
)
11860 output_operand_lossage ("invalid %%O value");
11862 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
11866 /* X is a CONST_INT that is a power of two. Output the logarithm. */
11868 || INT_LOWPART (x
) < 0
11869 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
11870 output_operand_lossage ("invalid %%p value");
11872 fprintf (file
, "%d", i
);
11876 /* The operand must be an indirect memory reference. The result
11877 is the register name. */
11878 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
11879 || REGNO (XEXP (x
, 0)) >= 32)
11880 output_operand_lossage ("invalid %%P value");
11882 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
11886 /* This outputs the logical code corresponding to a boolean
11887 expression. The expression may have one or both operands
11888 negated (if one, only the first one). For condition register
11889 logical operations, it will also treat the negated
11890 CR codes as NOTs, but not handle NOTs of them. */
11892 const char *const *t
= 0;
11894 enum rtx_code code
= GET_CODE (x
);
11895 static const char * const tbl
[3][3] = {
11896 { "and", "andc", "nor" },
11897 { "or", "orc", "nand" },
11898 { "xor", "eqv", "xor" } };
11902 else if (code
== IOR
)
11904 else if (code
== XOR
)
11907 output_operand_lossage ("invalid %%q value");
11909 if (GET_CODE (XEXP (x
, 0)) != NOT
)
11913 if (GET_CODE (XEXP (x
, 1)) == NOT
)
11931 /* X is a CR register. Print the mask for `mtcrf'. */
11932 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
11933 output_operand_lossage ("invalid %%R value");
11935 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
11939 /* Low 5 bits of 32 - value */
11941 output_operand_lossage ("invalid %%s value");
11943 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
11947 /* PowerPC64 mask position. All 0's is excluded.
11948 CONST_INT 32-bit mask is considered sign-extended so any
11949 transition must occur within the CONST_INT, not on the boundary. */
11950 if (! mask64_operand (x
, DImode
))
11951 output_operand_lossage ("invalid %%S value");
11953 uval
= INT_LOWPART (x
);
11955 if (uval
& 1) /* Clear Left */
11957 #if HOST_BITS_PER_WIDE_INT > 64
11958 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
11962 else /* Clear Right */
11965 #if HOST_BITS_PER_WIDE_INT > 64
11966 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
11972 gcc_assert (i
>= 0);
11973 fprintf (file
, "%d", i
);
11977 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
11978 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
11980 /* Bit 3 is OV bit. */
11981 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
11983 /* If we want bit 31, write a shift count of zero, not 32. */
11984 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
11988 /* Print the symbolic name of a branch target register. */
11989 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LR_REGNO
11990 && REGNO (x
) != CTR_REGNO
))
11991 output_operand_lossage ("invalid %%T value");
11992 else if (REGNO (x
) == LR_REGNO
)
11993 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
11995 fputs ("ctr", file
);
11999 /* High-order 16 bits of constant for use in unsigned operand. */
12001 output_operand_lossage ("invalid %%u value");
12003 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
12004 (INT_LOWPART (x
) >> 16) & 0xffff);
12008 /* High-order 16 bits of constant for use in signed operand. */
12010 output_operand_lossage ("invalid %%v value");
12012 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
12013 (INT_LOWPART (x
) >> 16) & 0xffff);
12017 /* Print `u' if this has an auto-increment or auto-decrement. */
12018 if (GET_CODE (x
) == MEM
12019 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
12020 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
12021 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
))
12026 /* Print the trap code for this operand. */
12027 switch (GET_CODE (x
))
12030 fputs ("eq", file
); /* 4 */
12033 fputs ("ne", file
); /* 24 */
12036 fputs ("lt", file
); /* 16 */
12039 fputs ("le", file
); /* 20 */
12042 fputs ("gt", file
); /* 8 */
12045 fputs ("ge", file
); /* 12 */
12048 fputs ("llt", file
); /* 2 */
12051 fputs ("lle", file
); /* 6 */
12054 fputs ("lgt", file
); /* 1 */
12057 fputs ("lge", file
); /* 5 */
12060 gcc_unreachable ();
12065 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
12068 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
12069 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
12071 print_operand (file
, x
, 0);
12075 /* MB value for a PowerPC64 rldic operand. */
12076 val
= (GET_CODE (x
) == CONST_INT
12077 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
12082 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
12083 if ((val
<<= 1) < 0)
12086 #if HOST_BITS_PER_WIDE_INT == 32
12087 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
12088 i
+= 32; /* zero-extend high-part was all 0's */
12089 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
12091 val
= CONST_DOUBLE_LOW (x
);
12097 for ( ; i
< 64; i
++)
12098 if ((val
<<= 1) < 0)
12103 fprintf (file
, "%d", i
+ 1);
12107 if (GET_CODE (x
) == MEM
12108 && (legitimate_indexed_address_p (XEXP (x
, 0), 0)
12109 || (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
12110 && legitimate_indexed_address_p (XEXP (XEXP (x
, 0), 1), 0))))
12115 /* Like 'L', for third word of TImode */
12116 if (GET_CODE (x
) == REG
)
12117 fputs (reg_names
[REGNO (x
) + 2], file
);
12118 else if (GET_CODE (x
) == MEM
)
12120 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
12121 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12122 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
12123 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12124 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
12126 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
12127 if (small_data_operand (x
, GET_MODE (x
)))
12128 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12129 reg_names
[SMALL_DATA_REG
]);
12134 /* X is a SYMBOL_REF. Write out the name preceded by a
12135 period and without any trailing data in brackets. Used for function
12136 names. If we are configured for System V (or the embedded ABI) on
12137 the PowerPC, do not emit the period, since those systems do not use
12138 TOCs and the like. */
12139 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
12141 /* Mark the decl as referenced so that cgraph will output the
12143 if (SYMBOL_REF_DECL (x
))
12144 mark_decl_referenced (SYMBOL_REF_DECL (x
));
12146 /* For macho, check to see if we need a stub. */
12149 const char *name
= XSTR (x
, 0);
12151 if (MACHOPIC_INDIRECT
12152 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
12153 name
= machopic_indirection_name (x
, /*stub_p=*/true);
12155 assemble_name (file
, name
);
12157 else if (!DOT_SYMBOLS
)
12158 assemble_name (file
, XSTR (x
, 0));
12160 rs6000_output_function_entry (file
, XSTR (x
, 0));
12164 /* Like 'L', for last word of TImode. */
12165 if (GET_CODE (x
) == REG
)
12166 fputs (reg_names
[REGNO (x
) + 3], file
);
12167 else if (GET_CODE (x
) == MEM
)
12169 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
12170 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12171 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
12172 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12173 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
12175 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
12176 if (small_data_operand (x
, GET_MODE (x
)))
12177 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12178 reg_names
[SMALL_DATA_REG
]);
12182 /* Print AltiVec or SPE memory operand. */
12187 gcc_assert (GET_CODE (x
) == MEM
);
12191 /* Ugly hack because %y is overloaded. */
12192 if ((TARGET_SPE
|| TARGET_E500_DOUBLE
)
12193 && (GET_MODE_SIZE (GET_MODE (x
)) == 8
12194 || GET_MODE (x
) == TFmode
12195 || GET_MODE (x
) == TImode
))
12197 /* Handle [reg]. */
12198 if (GET_CODE (tmp
) == REG
)
12200 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
12203 /* Handle [reg+UIMM]. */
12204 else if (GET_CODE (tmp
) == PLUS
&&
12205 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
12209 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
12211 x
= INTVAL (XEXP (tmp
, 1));
12212 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
12216 /* Fall through. Must be [reg+reg]. */
12219 && GET_CODE (tmp
) == AND
12220 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
12221 && INTVAL (XEXP (tmp
, 1)) == -16)
12222 tmp
= XEXP (tmp
, 0);
12223 if (GET_CODE (tmp
) == REG
)
12224 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
12227 gcc_assert (GET_CODE (tmp
) == PLUS
12228 && REG_P (XEXP (tmp
, 0))
12229 && REG_P (XEXP (tmp
, 1)));
12231 if (REGNO (XEXP (tmp
, 0)) == 0)
12232 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
12233 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
12235 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
12236 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
12242 if (GET_CODE (x
) == REG
)
12243 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
12244 else if (GET_CODE (x
) == MEM
)
12246 /* We need to handle PRE_INC and PRE_DEC here, since we need to
12247 know the width from the mode. */
12248 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
12249 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
12250 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
12251 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
12252 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
12253 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
12254 else if (GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
)
12255 output_address (XEXP (XEXP (x
, 0), 1));
12257 output_address (XEXP (x
, 0));
12260 output_addr_const (file
, x
);
12264 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
12268 output_operand_lossage ("invalid %%xn code");
12272 /* Print the address of an operand. */
12275 print_operand_address (FILE *file
, rtx x
)
12277 if (GET_CODE (x
) == REG
)
12278 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
12279 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
12280 || GET_CODE (x
) == LABEL_REF
)
12282 output_addr_const (file
, x
);
12283 if (small_data_operand (x
, GET_MODE (x
)))
12284 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
12285 reg_names
[SMALL_DATA_REG
]);
12287 gcc_assert (!TARGET_TOC
);
12289 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
12291 gcc_assert (REG_P (XEXP (x
, 0)));
12292 if (REGNO (XEXP (x
, 0)) == 0)
12293 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
12294 reg_names
[ REGNO (XEXP (x
, 0)) ]);
12296 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
12297 reg_names
[ REGNO (XEXP (x
, 1)) ]);
12299 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
12300 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
12301 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
12303 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
12304 && CONSTANT_P (XEXP (x
, 1)))
12306 output_addr_const (file
, XEXP (x
, 1));
12307 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
12311 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
12312 && CONSTANT_P (XEXP (x
, 1)))
12314 fprintf (file
, "lo16(");
12315 output_addr_const (file
, XEXP (x
, 1));
12316 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
12319 else if (legitimate_constant_pool_address_p (x
))
12321 if (TARGET_AIX
&& (!TARGET_ELF
|| !TARGET_MINIMAL_TOC
))
12323 rtx contains_minus
= XEXP (x
, 1);
12327 /* Find the (minus (sym) (toc)) buried in X, and temporarily
12328 turn it into (sym) for output_addr_const. */
12329 while (GET_CODE (XEXP (contains_minus
, 0)) != MINUS
)
12330 contains_minus
= XEXP (contains_minus
, 0);
12332 minus
= XEXP (contains_minus
, 0);
12333 symref
= XEXP (minus
, 0);
12334 XEXP (contains_minus
, 0) = symref
;
12339 name
= XSTR (symref
, 0);
12340 newname
= alloca (strlen (name
) + sizeof ("@toc"));
12341 strcpy (newname
, name
);
12342 strcat (newname
, "@toc");
12343 XSTR (symref
, 0) = newname
;
12345 output_addr_const (file
, XEXP (x
, 1));
12347 XSTR (symref
, 0) = name
;
12348 XEXP (contains_minus
, 0) = minus
;
12351 output_addr_const (file
, XEXP (x
, 1));
12353 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
12356 gcc_unreachable ();
12359 /* Target hook for assembling integer objects. The PowerPC version has
12360 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
12361 is defined. It also needs to handle DI-mode objects on 64-bit
12365 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
12367 #ifdef RELOCATABLE_NEEDS_FIXUP
12368 /* Special handling for SI values. */
12369 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
12371 static int recurse
= 0;
12373 /* For -mrelocatable, we mark all addresses that need to be fixed up
12374 in the .fixup section. */
12375 if (TARGET_RELOCATABLE
12376 && in_section
!= toc_section
12377 && in_section
!= text_section
12378 && !unlikely_text_section_p (in_section
)
12380 && GET_CODE (x
) != CONST_INT
12381 && GET_CODE (x
) != CONST_DOUBLE
12387 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
12389 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
12390 fprintf (asm_out_file
, "\t.long\t(");
12391 output_addr_const (asm_out_file
, x
);
12392 fprintf (asm_out_file
, ")@fixup\n");
12393 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
12394 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
12395 fprintf (asm_out_file
, "\t.long\t");
12396 assemble_name (asm_out_file
, buf
);
12397 fprintf (asm_out_file
, "\n\t.previous\n");
12401 /* Remove initial .'s to turn a -mcall-aixdesc function
12402 address into the address of the descriptor, not the function
12404 else if (GET_CODE (x
) == SYMBOL_REF
12405 && XSTR (x
, 0)[0] == '.'
12406 && DEFAULT_ABI
== ABI_AIX
)
12408 const char *name
= XSTR (x
, 0);
12409 while (*name
== '.')
12412 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
12416 #endif /* RELOCATABLE_NEEDS_FIXUP */
12417 return default_assemble_integer (x
, size
, aligned_p
);
12420 #ifdef HAVE_GAS_HIDDEN
12421 /* Emit an assembler directive to set symbol visibility for DECL to
12422 VISIBILITY_TYPE. */
12425 rs6000_assemble_visibility (tree decl
, int vis
)
12427 /* Functions need to have their entry point symbol visibility set as
12428 well as their descriptor symbol visibility. */
12429 if (DEFAULT_ABI
== ABI_AIX
12431 && TREE_CODE (decl
) == FUNCTION_DECL
)
12433 static const char * const visibility_types
[] = {
12434 NULL
, "internal", "hidden", "protected"
12437 const char *name
, *type
;
12439 name
= ((* targetm
.strip_name_encoding
)
12440 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
12441 type
= visibility_types
[vis
];
12443 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
12444 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
12447 default_assemble_visibility (decl
, vis
);
12452 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
12454 /* Reversal of FP compares takes care -- an ordered compare
12455 becomes an unordered compare and vice versa. */
12456 if (mode
== CCFPmode
12457 && (!flag_finite_math_only
12458 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
12459 || code
== UNEQ
|| code
== LTGT
))
12460 return reverse_condition_maybe_unordered (code
);
12462 return reverse_condition (code
);
12465 /* Generate a compare for CODE. Return a brand-new rtx that
12466 represents the result of the compare. */
12469 rs6000_generate_compare (enum rtx_code code
)
12471 enum machine_mode comp_mode
;
12472 rtx compare_result
;
12474 if (rs6000_compare_fp_p
)
12475 comp_mode
= CCFPmode
;
12476 else if (code
== GTU
|| code
== LTU
12477 || code
== GEU
|| code
== LEU
)
12478 comp_mode
= CCUNSmode
;
12479 else if ((code
== EQ
|| code
== NE
)
12480 && GET_CODE (rs6000_compare_op0
) == SUBREG
12481 && GET_CODE (rs6000_compare_op1
) == SUBREG
12482 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0
)
12483 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1
))
12484 /* These are unsigned values, perhaps there will be a later
12485 ordering compare that can be shared with this one.
12486 Unfortunately we cannot detect the signedness of the operands
12487 for non-subregs. */
12488 comp_mode
= CCUNSmode
;
12490 comp_mode
= CCmode
;
12492 /* First, the compare. */
12493 compare_result
= gen_reg_rtx (comp_mode
);
12495 /* E500 FP compare instructions on the GPRs. Yuck! */
12496 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
)
12497 && rs6000_compare_fp_p
)
12499 rtx cmp
, or_result
, compare_result2
;
12500 enum machine_mode op_mode
= GET_MODE (rs6000_compare_op0
);
12502 if (op_mode
== VOIDmode
)
12503 op_mode
= GET_MODE (rs6000_compare_op1
);
12505 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
12506 This explains the following mess. */
12510 case EQ
: case UNEQ
: case NE
: case LTGT
:
12514 cmp
= flag_unsafe_math_optimizations
12515 ? gen_tstsfeq_gpr (compare_result
, rs6000_compare_op0
,
12516 rs6000_compare_op1
)
12517 : gen_cmpsfeq_gpr (compare_result
, rs6000_compare_op0
,
12518 rs6000_compare_op1
);
12522 cmp
= flag_unsafe_math_optimizations
12523 ? gen_tstdfeq_gpr (compare_result
, rs6000_compare_op0
,
12524 rs6000_compare_op1
)
12525 : gen_cmpdfeq_gpr (compare_result
, rs6000_compare_op0
,
12526 rs6000_compare_op1
);
12530 cmp
= flag_unsafe_math_optimizations
12531 ? gen_tsttfeq_gpr (compare_result
, rs6000_compare_op0
,
12532 rs6000_compare_op1
)
12533 : gen_cmptfeq_gpr (compare_result
, rs6000_compare_op0
,
12534 rs6000_compare_op1
);
12538 gcc_unreachable ();
12542 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
12546 cmp
= flag_unsafe_math_optimizations
12547 ? gen_tstsfgt_gpr (compare_result
, rs6000_compare_op0
,
12548 rs6000_compare_op1
)
12549 : gen_cmpsfgt_gpr (compare_result
, rs6000_compare_op0
,
12550 rs6000_compare_op1
);
12554 cmp
= flag_unsafe_math_optimizations
12555 ? gen_tstdfgt_gpr (compare_result
, rs6000_compare_op0
,
12556 rs6000_compare_op1
)
12557 : gen_cmpdfgt_gpr (compare_result
, rs6000_compare_op0
,
12558 rs6000_compare_op1
);
12562 cmp
= flag_unsafe_math_optimizations
12563 ? gen_tsttfgt_gpr (compare_result
, rs6000_compare_op0
,
12564 rs6000_compare_op1
)
12565 : gen_cmptfgt_gpr (compare_result
, rs6000_compare_op0
,
12566 rs6000_compare_op1
);
12570 gcc_unreachable ();
12574 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
12578 cmp
= flag_unsafe_math_optimizations
12579 ? gen_tstsflt_gpr (compare_result
, rs6000_compare_op0
,
12580 rs6000_compare_op1
)
12581 : gen_cmpsflt_gpr (compare_result
, rs6000_compare_op0
,
12582 rs6000_compare_op1
);
12586 cmp
= flag_unsafe_math_optimizations
12587 ? gen_tstdflt_gpr (compare_result
, rs6000_compare_op0
,
12588 rs6000_compare_op1
)
12589 : gen_cmpdflt_gpr (compare_result
, rs6000_compare_op0
,
12590 rs6000_compare_op1
);
12594 cmp
= flag_unsafe_math_optimizations
12595 ? gen_tsttflt_gpr (compare_result
, rs6000_compare_op0
,
12596 rs6000_compare_op1
)
12597 : gen_cmptflt_gpr (compare_result
, rs6000_compare_op0
,
12598 rs6000_compare_op1
);
12602 gcc_unreachable ();
12606 gcc_unreachable ();
12609 /* Synthesize LE and GE from LT/GT || EQ. */
12610 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
12616 case LE
: code
= LT
; break;
12617 case GE
: code
= GT
; break;
12618 case LEU
: code
= LT
; break;
12619 case GEU
: code
= GT
; break;
12620 default: gcc_unreachable ();
12623 compare_result2
= gen_reg_rtx (CCFPmode
);
12629 cmp
= flag_unsafe_math_optimizations
12630 ? gen_tstsfeq_gpr (compare_result2
, rs6000_compare_op0
,
12631 rs6000_compare_op1
)
12632 : gen_cmpsfeq_gpr (compare_result2
, rs6000_compare_op0
,
12633 rs6000_compare_op1
);
12637 cmp
= flag_unsafe_math_optimizations
12638 ? gen_tstdfeq_gpr (compare_result2
, rs6000_compare_op0
,
12639 rs6000_compare_op1
)
12640 : gen_cmpdfeq_gpr (compare_result2
, rs6000_compare_op0
,
12641 rs6000_compare_op1
);
12645 cmp
= flag_unsafe_math_optimizations
12646 ? gen_tsttfeq_gpr (compare_result2
, rs6000_compare_op0
,
12647 rs6000_compare_op1
)
12648 : gen_cmptfeq_gpr (compare_result2
, rs6000_compare_op0
,
12649 rs6000_compare_op1
);
12653 gcc_unreachable ();
12657 /* OR them together. */
12658 or_result
= gen_reg_rtx (CCFPmode
);
12659 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
12661 compare_result
= or_result
;
12666 if (code
== NE
|| code
== LTGT
)
12676 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
12677 CLOBBERs to match cmptf_internal2 pattern. */
12678 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
12679 && GET_MODE (rs6000_compare_op0
) == TFmode
12680 && !TARGET_IEEEQUAD
12681 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
12682 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
12684 gen_rtx_SET (VOIDmode
,
12686 gen_rtx_COMPARE (comp_mode
,
12687 rs6000_compare_op0
,
12688 rs6000_compare_op1
)),
12689 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12690 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12691 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12692 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12693 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12694 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12695 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
12696 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)))));
12697 else if (GET_CODE (rs6000_compare_op1
) == UNSPEC
12698 && XINT (rs6000_compare_op1
, 1) == UNSPEC_SP_TEST
)
12700 rtx op1
= XVECEXP (rs6000_compare_op1
, 0, 0);
12701 comp_mode
= CCEQmode
;
12702 compare_result
= gen_reg_rtx (CCEQmode
);
12704 emit_insn (gen_stack_protect_testdi (compare_result
,
12705 rs6000_compare_op0
, op1
));
12707 emit_insn (gen_stack_protect_testsi (compare_result
,
12708 rs6000_compare_op0
, op1
));
12711 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
12712 gen_rtx_COMPARE (comp_mode
,
12713 rs6000_compare_op0
,
12714 rs6000_compare_op1
)));
12717 /* Some kinds of FP comparisons need an OR operation;
12718 under flag_finite_math_only we don't bother. */
12719 if (rs6000_compare_fp_p
12720 && !flag_finite_math_only
12721 && !(TARGET_HARD_FLOAT
&& !TARGET_FPRS
)
12722 && (code
== LE
|| code
== GE
12723 || code
== UNEQ
|| code
== LTGT
12724 || code
== UNGT
|| code
== UNLT
))
12726 enum rtx_code or1
, or2
;
12727 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
12728 rtx or_result
= gen_reg_rtx (CCEQmode
);
12732 case LE
: or1
= LT
; or2
= EQ
; break;
12733 case GE
: or1
= GT
; or2
= EQ
; break;
12734 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
12735 case LTGT
: or1
= LT
; or2
= GT
; break;
12736 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
12737 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
12738 default: gcc_unreachable ();
12740 validate_condition_mode (or1
, comp_mode
);
12741 validate_condition_mode (or2
, comp_mode
);
12742 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
12743 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
12744 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
12745 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
12747 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
12749 compare_result
= or_result
;
12753 validate_condition_mode (code
, GET_MODE (compare_result
));
12755 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
12759 /* Emit the RTL for an sCOND pattern. */
12762 rs6000_emit_sCOND (enum rtx_code code
, rtx result
)
12765 enum machine_mode op_mode
;
12766 enum rtx_code cond_code
;
12768 condition_rtx
= rs6000_generate_compare (code
);
12769 cond_code
= GET_CODE (condition_rtx
);
12771 if (rs6000_compare_fp_p
12772 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
12776 PUT_MODE (condition_rtx
, SImode
);
12777 t
= XEXP (condition_rtx
, 0);
12779 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
12781 if (cond_code
== NE
)
12782 emit_insn (gen_e500_flip_gt_bit (t
, t
));
12784 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
12788 if (cond_code
== NE
12789 || cond_code
== GE
|| cond_code
== LE
12790 || cond_code
== GEU
|| cond_code
== LEU
12791 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
12793 rtx not_result
= gen_reg_rtx (CCEQmode
);
12794 rtx not_op
, rev_cond_rtx
;
12795 enum machine_mode cc_mode
;
12797 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
12799 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
12800 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
12801 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
12802 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
12803 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
12806 op_mode
= GET_MODE (rs6000_compare_op0
);
12807 if (op_mode
== VOIDmode
)
12808 op_mode
= GET_MODE (rs6000_compare_op1
);
12810 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| rs6000_compare_fp_p
))
12812 PUT_MODE (condition_rtx
, DImode
);
12813 convert_move (result
, condition_rtx
, 0);
12817 PUT_MODE (condition_rtx
, SImode
);
12818 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
12822 /* Emit a branch of kind CODE to location LOC. */
12825 rs6000_emit_cbranch (enum rtx_code code
, rtx loc
)
12827 rtx condition_rtx
, loc_ref
;
12829 condition_rtx
= rs6000_generate_compare (code
);
12830 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, loc
);
12831 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
12832 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
12833 loc_ref
, pc_rtx
)));
12836 /* Return the string to output a conditional branch to LABEL, which is
12837 the operand number of the label, or -1 if the branch is really a
12838 conditional return.
12840 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
12841 condition code register and its mode specifies what kind of
12842 comparison we made.
12844 REVERSED is nonzero if we should reverse the sense of the comparison.
12846 INSN is the insn. */
12849 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
12851 static char string
[64];
12852 enum rtx_code code
= GET_CODE (op
);
12853 rtx cc_reg
= XEXP (op
, 0);
12854 enum machine_mode mode
= GET_MODE (cc_reg
);
12855 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
12856 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
12857 int really_reversed
= reversed
^ need_longbranch
;
12863 validate_condition_mode (code
, mode
);
12865 /* Work out which way this really branches. We could use
12866 reverse_condition_maybe_unordered here always but this
12867 makes the resulting assembler clearer. */
12868 if (really_reversed
)
12870 /* Reversal of FP compares takes care -- an ordered compare
12871 becomes an unordered compare and vice versa. */
12872 if (mode
== CCFPmode
)
12873 code
= reverse_condition_maybe_unordered (code
);
12875 code
= reverse_condition (code
);
12878 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
12880 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
12885 /* Opposite of GT. */
12894 gcc_unreachable ();
12900 /* Not all of these are actually distinct opcodes, but
12901 we distinguish them for clarity of the resulting assembler. */
12902 case NE
: case LTGT
:
12903 ccode
= "ne"; break;
12904 case EQ
: case UNEQ
:
12905 ccode
= "eq"; break;
12907 ccode
= "ge"; break;
12908 case GT
: case GTU
: case UNGT
:
12909 ccode
= "gt"; break;
12911 ccode
= "le"; break;
12912 case LT
: case LTU
: case UNLT
:
12913 ccode
= "lt"; break;
12914 case UNORDERED
: ccode
= "un"; break;
12915 case ORDERED
: ccode
= "nu"; break;
12916 case UNGE
: ccode
= "nl"; break;
12917 case UNLE
: ccode
= "ng"; break;
12919 gcc_unreachable ();
12922 /* Maybe we have a guess as to how likely the branch is.
12923 The old mnemonics don't have a way to specify this information. */
12925 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
12926 if (note
!= NULL_RTX
)
12928 /* PROB is the difference from 50%. */
12929 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
12931 /* Only hint for highly probable/improbable branches on newer
12932 cpus as static prediction overrides processor dynamic
12933 prediction. For older cpus we may as well always hint, but
12934 assume not taken for branches that are very close to 50% as a
12935 mispredicted taken branch is more expensive than a
12936 mispredicted not-taken branch. */
12937 if (rs6000_always_hint
12938 || (abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48
12939 && br_prob_note_reliable_p (note
)))
12941 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
12942 && ((prob
> 0) ^ need_longbranch
))
12950 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
12952 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
12954 /* We need to escape any '%' characters in the reg_names string.
12955 Assume they'd only be the first character.... */
12956 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
12958 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
12962 /* If the branch distance was too far, we may have to use an
12963 unconditional branch to go the distance. */
12964 if (need_longbranch
)
12965 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
12967 s
+= sprintf (s
, ",%s", label
);
12973 /* Return the string to flip the GT bit on a CR. */
12975 output_e500_flip_gt_bit (rtx dst
, rtx src
)
12977 static char string
[64];
12980 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
12981 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
12984 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
12985 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
12987 sprintf (string
, "crnot %d,%d", a
, b
);
12991 /* Return insn index for the vector compare instruction for given CODE,
12992 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
12996 get_vec_cmp_insn (enum rtx_code code
,
12997 enum machine_mode dest_mode
,
12998 enum machine_mode op_mode
)
13000 if (!TARGET_ALTIVEC
)
13001 return INSN_NOT_AVAILABLE
;
13006 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
13007 return UNSPEC_VCMPEQUB
;
13008 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
13009 return UNSPEC_VCMPEQUH
;
13010 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
13011 return UNSPEC_VCMPEQUW
;
13012 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
13013 return UNSPEC_VCMPEQFP
;
13016 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
13017 return UNSPEC_VCMPGEFP
;
13019 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
13020 return UNSPEC_VCMPGTSB
;
13021 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
13022 return UNSPEC_VCMPGTSH
;
13023 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
13024 return UNSPEC_VCMPGTSW
;
13025 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
13026 return UNSPEC_VCMPGTFP
;
13029 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
13030 return UNSPEC_VCMPGTUB
;
13031 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
13032 return UNSPEC_VCMPGTUH
;
13033 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
13034 return UNSPEC_VCMPGTUW
;
13039 return INSN_NOT_AVAILABLE
;
13042 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
13043 DMODE is expected destination mode. This is a recursive function. */
13046 rs6000_emit_vector_compare (enum rtx_code rcode
,
13048 enum machine_mode dmode
)
13052 enum machine_mode dest_mode
;
13053 enum machine_mode op_mode
= GET_MODE (op1
);
13055 gcc_assert (TARGET_ALTIVEC
);
13056 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
13058 /* Floating point vector compare instructions uses destination V4SImode.
13059 Move destination to appropriate mode later. */
13060 if (dmode
== V4SFmode
)
13061 dest_mode
= V4SImode
;
13065 mask
= gen_reg_rtx (dest_mode
);
13066 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
13068 if (vec_cmp_insn
== INSN_NOT_AVAILABLE
)
13070 bool swap_operands
= false;
13071 bool try_again
= false;
13076 swap_operands
= true;
13081 swap_operands
= true;
13089 /* Invert condition and try again.
13090 e.g., A != B becomes ~(A==B). */
13092 enum rtx_code rev_code
;
13093 enum insn_code nor_code
;
13096 rev_code
= reverse_condition_maybe_unordered (rcode
);
13097 eq_rtx
= rs6000_emit_vector_compare (rev_code
, op0
, op1
,
13100 nor_code
= optab_handler (one_cmpl_optab
, (int)dest_mode
)->insn_code
;
13101 gcc_assert (nor_code
!= CODE_FOR_nothing
);
13102 emit_insn (GEN_FCN (nor_code
) (mask
, eq_rtx
));
13104 if (dmode
!= dest_mode
)
13106 rtx temp
= gen_reg_rtx (dest_mode
);
13107 convert_move (temp
, mask
, 0);
13117 /* Try GT/GTU/LT/LTU OR EQ */
13120 enum insn_code ior_code
;
13121 enum rtx_code new_code
;
13142 gcc_unreachable ();
13145 c_rtx
= rs6000_emit_vector_compare (new_code
,
13146 op0
, op1
, dest_mode
);
13147 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
,
13150 ior_code
= optab_handler (ior_optab
, (int)dest_mode
)->insn_code
;
13151 gcc_assert (ior_code
!= CODE_FOR_nothing
);
13152 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
13153 if (dmode
!= dest_mode
)
13155 rtx temp
= gen_reg_rtx (dest_mode
);
13156 convert_move (temp
, mask
, 0);
13163 gcc_unreachable ();
13168 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
13169 /* You only get two chances. */
13170 gcc_assert (vec_cmp_insn
!= INSN_NOT_AVAILABLE
);
13182 emit_insn (gen_rtx_SET (VOIDmode
, mask
,
13183 gen_rtx_UNSPEC (dest_mode
,
13184 gen_rtvec (2, op0
, op1
),
13186 if (dmode
!= dest_mode
)
13188 rtx temp
= gen_reg_rtx (dest_mode
);
13189 convert_move (temp
, mask
, 0);
13195 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
13196 valid insn doesn exist for given mode. */
13199 get_vsel_insn (enum machine_mode mode
)
13204 return UNSPEC_VSEL4SI
;
13207 return UNSPEC_VSEL4SF
;
13210 return UNSPEC_VSEL8HI
;
13213 return UNSPEC_VSEL16QI
;
13216 return INSN_NOT_AVAILABLE
;
13219 return INSN_NOT_AVAILABLE
;
13222 /* Emit vector select insn where DEST is destination using
13223 operands OP1, OP2 and MASK. */
13226 rs6000_emit_vector_select (rtx dest
, rtx op1
, rtx op2
, rtx mask
)
13229 enum machine_mode dest_mode
= GET_MODE (dest
);
13230 int vsel_insn_index
= get_vsel_insn (GET_MODE (dest
));
13232 temp
= gen_reg_rtx (dest_mode
);
13234 /* For each vector element, select op1 when mask is 1 otherwise
13236 t
= gen_rtx_SET (VOIDmode
, temp
,
13237 gen_rtx_UNSPEC (dest_mode
,
13238 gen_rtvec (3, op2
, op1
, mask
),
13241 emit_move_insn (dest
, temp
);
13245 /* Emit vector conditional expression.
13246 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
13247 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
13250 rs6000_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
13251 rtx cond
, rtx cc_op0
, rtx cc_op1
)
13253 enum machine_mode dest_mode
= GET_MODE (dest
);
13254 enum rtx_code rcode
= GET_CODE (cond
);
13257 if (!TARGET_ALTIVEC
)
13260 /* Get the vector mask for the given relational operations. */
13261 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
13263 rs6000_emit_vector_select (dest
, op1
, op2
, mask
);
13268 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
13269 operands of the last comparison is nonzero/true, FALSE_COND if it
13270 is zero/false. Return 0 if the hardware has no such operation. */
13273 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
13275 enum rtx_code code
= GET_CODE (op
);
13276 rtx op0
= rs6000_compare_op0
;
13277 rtx op1
= rs6000_compare_op1
;
13278 REAL_VALUE_TYPE c1
;
13279 enum machine_mode compare_mode
= GET_MODE (op0
);
13280 enum machine_mode result_mode
= GET_MODE (dest
);
13282 bool is_against_zero
;
13284 /* These modes should always match. */
13285 if (GET_MODE (op1
) != compare_mode
13286 /* In the isel case however, we can use a compare immediate, so
13287 op1 may be a small constant. */
13288 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
13290 if (GET_MODE (true_cond
) != result_mode
)
13292 if (GET_MODE (false_cond
) != result_mode
)
13295 /* First, work out if the hardware can do this at all, or
13296 if it's too slow.... */
13297 if (! rs6000_compare_fp_p
)
13300 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
13303 else if (TARGET_HARD_FLOAT
&& !TARGET_FPRS
13304 && SCALAR_FLOAT_MODE_P (compare_mode
))
13307 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
13309 /* A floating-point subtract might overflow, underflow, or produce
13310 an inexact result, thus changing the floating-point flags, so it
13311 can't be generated if we care about that. It's safe if one side
13312 of the construct is zero, since then no subtract will be
13314 if (SCALAR_FLOAT_MODE_P (compare_mode
)
13315 && flag_trapping_math
&& ! is_against_zero
)
13318 /* Eliminate half of the comparisons by switching operands, this
13319 makes the remaining code simpler. */
13320 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
13321 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
13323 code
= reverse_condition_maybe_unordered (code
);
13325 true_cond
= false_cond
;
13329 /* UNEQ and LTGT take four instructions for a comparison with zero,
13330 it'll probably be faster to use a branch here too. */
13331 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
13334 if (GET_CODE (op1
) == CONST_DOUBLE
)
13335 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
13337 /* We're going to try to implement comparisons by performing
13338 a subtract, then comparing against zero. Unfortunately,
13339 Inf - Inf is NaN which is not zero, and so if we don't
13340 know that the operand is finite and the comparison
13341 would treat EQ different to UNORDERED, we can't do it. */
13342 if (HONOR_INFINITIES (compare_mode
)
13343 && code
!= GT
&& code
!= UNGE
13344 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
13345 /* Constructs of the form (a OP b ? a : b) are safe. */
13346 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
13347 || (! rtx_equal_p (op0
, true_cond
)
13348 && ! rtx_equal_p (op1
, true_cond
))))
13351 /* At this point we know we can use fsel. */
13353 /* Reduce the comparison to a comparison against zero. */
13354 if (! is_against_zero
)
13356 temp
= gen_reg_rtx (compare_mode
);
13357 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13358 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
13360 op1
= CONST0_RTX (compare_mode
);
13363 /* If we don't care about NaNs we can reduce some of the comparisons
13364 down to faster ones. */
13365 if (! HONOR_NANS (compare_mode
))
13371 true_cond
= false_cond
;
13384 /* Now, reduce everything down to a GE. */
13391 temp
= gen_reg_rtx (compare_mode
);
13392 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
13397 temp
= gen_reg_rtx (compare_mode
);
13398 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
13403 temp
= gen_reg_rtx (compare_mode
);
13404 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13405 gen_rtx_NEG (compare_mode
,
13406 gen_rtx_ABS (compare_mode
, op0
))));
13411 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
13412 temp
= gen_reg_rtx (result_mode
);
13413 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
13414 gen_rtx_IF_THEN_ELSE (result_mode
,
13415 gen_rtx_GE (VOIDmode
,
13417 true_cond
, false_cond
)));
13418 false_cond
= true_cond
;
13421 temp
= gen_reg_rtx (compare_mode
);
13422 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
13427 /* a GT 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 true_cond
= false_cond
;
13437 temp
= gen_reg_rtx (compare_mode
);
13438 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
13443 gcc_unreachable ();
13446 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
13447 gen_rtx_IF_THEN_ELSE (result_mode
,
13448 gen_rtx_GE (VOIDmode
,
13450 true_cond
, false_cond
)));
13454 /* Same as above, but for ints (isel). */
13457 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
13459 rtx condition_rtx
, cr
;
13461 /* All isel implementations thus far are 32-bits. */
13462 if (GET_MODE (rs6000_compare_op0
) != SImode
)
13465 /* We still have to do the compare, because isel doesn't do a
13466 compare, it just looks at the CRx bits set by a previous compare
13468 condition_rtx
= rs6000_generate_compare (GET_CODE (op
));
13469 cr
= XEXP (condition_rtx
, 0);
13471 if (GET_MODE (cr
) == CCmode
)
13472 emit_insn (gen_isel_signed (dest
, condition_rtx
,
13473 true_cond
, false_cond
, cr
));
13475 emit_insn (gen_isel_unsigned (dest
, condition_rtx
,
13476 true_cond
, false_cond
, cr
));
13482 output_isel (rtx
*operands
)
13484 enum rtx_code code
;
13486 code
= GET_CODE (operands
[1]);
13487 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
13489 PUT_CODE (operands
[1], reverse_condition (code
));
13490 return "isel %0,%3,%2,%j1";
13493 return "isel %0,%2,%3,%j1";
13497 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
13499 enum machine_mode mode
= GET_MODE (op0
);
13503 if (code
== SMAX
|| code
== SMIN
)
13508 if (code
== SMAX
|| code
== UMAX
)
13509 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
13510 op0
, op1
, mode
, 0);
13512 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
13513 op1
, op0
, mode
, 0);
13514 gcc_assert (target
);
13515 if (target
!= dest
)
13516 emit_move_insn (dest
, target
);
13519 /* Emit instructions to perform a load-reserved/store-conditional operation.
13520 The operation performed is an atomic
13521 (set M (CODE:MODE M OP))
13522 If not NULL, BEFORE is atomically set to M before the operation, and
13523 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
13524 If SYNC_P then a memory barrier is emitted before the operation.
13525 Either OP or M may be wrapped in a NOT operation. */
13528 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
13529 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
13532 enum machine_mode used_mode
;
13533 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
13536 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
13537 rtx shift
= NULL_RTX
;
13540 emit_insn (gen_memory_barrier ());
13542 if (GET_CODE (m
) == NOT
)
13543 used_m
= XEXP (m
, 0);
13547 /* If this is smaller than SImode, we'll have to use SImode with
13549 if (mode
== QImode
|| mode
== HImode
)
13553 if (MEM_ALIGN (used_m
) >= 32)
13556 if (BYTES_BIG_ENDIAN
)
13557 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
13559 shift
= GEN_INT (ishift
);
13560 used_m
= change_address (used_m
, SImode
, 0);
13564 rtx addrSI
, aligned_addr
;
13565 int shift_mask
= mode
== QImode
? 0x18 : 0x10;
13567 addrSI
= gen_lowpart_common (SImode
,
13568 force_reg (Pmode
, XEXP (used_m
, 0)));
13569 addrSI
= force_reg (SImode
, addrSI
);
13570 shift
= gen_reg_rtx (SImode
);
13572 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
13573 GEN_INT (shift_mask
)));
13574 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
13576 aligned_addr
= expand_binop (Pmode
, and_optab
,
13578 GEN_INT (-4), NULL_RTX
,
13579 1, OPTAB_LIB_WIDEN
);
13580 used_m
= change_address (used_m
, SImode
, aligned_addr
);
13581 set_mem_align (used_m
, 32);
13583 /* It's safe to keep the old alias set of USED_M, because
13584 the operation is atomic and only affects the original
13586 if (GET_CODE (m
) == NOT
)
13587 m
= gen_rtx_NOT (SImode
, used_m
);
13591 if (GET_CODE (op
) == NOT
)
13593 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
13594 oldop
= gen_rtx_NOT (SImode
, oldop
);
13597 oldop
= lowpart_subreg (SImode
, op
, mode
);
13603 newop
= expand_binop (SImode
, and_optab
,
13604 oldop
, GEN_INT (imask
), NULL_RTX
,
13605 1, OPTAB_LIB_WIDEN
);
13606 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
13610 newop
= expand_binop (SImode
, ior_optab
,
13611 oldop
, GEN_INT (~imask
), NULL_RTX
,
13612 1, OPTAB_LIB_WIDEN
);
13613 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
13621 newop
= expand_binop (SImode
, and_optab
,
13622 oldop
, GEN_INT (imask
), NULL_RTX
,
13623 1, OPTAB_LIB_WIDEN
);
13624 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
13626 mask
= gen_reg_rtx (SImode
);
13627 emit_move_insn (mask
, GEN_INT (imask
));
13628 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
13631 newop
= gen_rtx_PLUS (SImode
, m
, newop
);
13633 newop
= gen_rtx_MINUS (SImode
, m
, newop
);
13634 newop
= gen_rtx_AND (SImode
, newop
, mask
);
13635 newop
= gen_rtx_IOR (SImode
, newop
,
13636 gen_rtx_AND (SImode
,
13637 gen_rtx_NOT (SImode
, mask
),
13643 gcc_unreachable ();
13646 if (GET_CODE (m
) == NOT
)
13650 mask
= gen_reg_rtx (SImode
);
13651 emit_move_insn (mask
, GEN_INT (imask
));
13652 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
13654 xorm
= gen_rtx_XOR (SImode
, used_m
, mask
);
13655 /* Depending on the value of 'op', the XOR or the operation might
13656 be able to be simplified away. */
13657 newop
= simplify_gen_binary (code
, SImode
, xorm
, newop
);
13660 used_mode
= SImode
;
13661 before
= gen_reg_rtx (used_mode
);
13662 after
= gen_reg_rtx (used_mode
);
13667 before
= before_param
;
13668 after
= after_param
;
13670 if (before
== NULL_RTX
)
13671 before
= gen_reg_rtx (used_mode
);
13672 if (after
== NULL_RTX
)
13673 after
= gen_reg_rtx (used_mode
);
13676 if ((code
== PLUS
|| code
== MINUS
|| GET_CODE (m
) == NOT
)
13677 && used_mode
!= mode
)
13678 the_op
= op
; /* Computed above. */
13679 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
13680 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
13682 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
13684 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
13685 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
13686 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
13687 gen_rtx_UNSPEC (used_mode
,
13688 gen_rtvec (1, the_op
),
13690 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
13692 if ((code
== PLUS
|| code
== MINUS
) && used_mode
!= mode
)
13693 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
13694 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
13696 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
13697 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
13699 /* Shift and mask the return values properly. */
13700 if (used_mode
!= mode
&& before_param
)
13702 emit_insn (gen_lshrsi3 (before
, before
, shift
));
13703 convert_move (before_param
, before
, 1);
13706 if (used_mode
!= mode
&& after_param
)
13708 emit_insn (gen_lshrsi3 (after
, after
, shift
));
13709 convert_move (after_param
, after
, 1);
13712 /* The previous sequence will end with a branch that's dependent on
13713 the conditional store, so placing an isync will ensure that no
13714 other instructions (especially, no load or store instructions)
13715 can start before the atomic operation completes. */
13717 emit_insn (gen_isync ());
13720 /* A subroutine of the atomic operation splitters. Jump to LABEL if
13721 COND is true. Mark the jump as unlikely to be taken. */
13724 emit_unlikely_jump (rtx cond
, rtx label
)
13726 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
13729 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
13730 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
13731 REG_NOTES (x
) = gen_rtx_EXPR_LIST (REG_BR_PROB
, very_unlikely
, NULL_RTX
);
13734 /* A subroutine of the atomic operation splitters. Emit a load-locked
13735 instruction in MODE. */
13738 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
13740 rtx (*fn
) (rtx
, rtx
) = NULL
;
13741 if (mode
== SImode
)
13742 fn
= gen_load_locked_si
;
13743 else if (mode
== DImode
)
13744 fn
= gen_load_locked_di
;
13745 emit_insn (fn (reg
, mem
));
13748 /* A subroutine of the atomic operation splitters. Emit a store-conditional
13749 instruction in MODE. */
13752 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
13754 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
13755 if (mode
== SImode
)
13756 fn
= gen_store_conditional_si
;
13757 else if (mode
== DImode
)
13758 fn
= gen_store_conditional_di
;
13760 /* Emit sync before stwcx. to address PPC405 Erratum. */
13761 if (PPC405_ERRATUM77
)
13762 emit_insn (gen_memory_barrier ());
13764 emit_insn (fn (res
, mem
, val
));
13767 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
13768 to perform. MEM is the memory on which to operate. VAL is the second
13769 operand of the binary operator. BEFORE and AFTER are optional locations to
13770 return the value of MEM either before of after the operation. SCRATCH is
13771 a scratch register. */
13774 rs6000_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
13775 rtx before
, rtx after
, rtx scratch
)
13777 enum machine_mode mode
= GET_MODE (mem
);
13778 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
13780 emit_insn (gen_memory_barrier ());
13782 label
= gen_label_rtx ();
13783 emit_label (label
);
13784 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
13786 if (before
== NULL_RTX
)
13788 emit_load_locked (mode
, before
, mem
);
13791 x
= gen_rtx_AND (mode
, gen_rtx_NOT (mode
, before
), val
);
13792 else if (code
== AND
)
13793 x
= gen_rtx_UNSPEC (mode
, gen_rtvec (2, before
, val
), UNSPEC_AND
);
13795 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
13797 if (after
!= NULL_RTX
)
13798 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
13799 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
13801 emit_store_conditional (mode
, cond
, mem
, scratch
);
13803 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
13804 emit_unlikely_jump (x
, label
);
13806 emit_insn (gen_isync ());
13809 /* Expand an atomic compare and swap operation. MEM is the memory on which
13810 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
13811 value to be stored. SCRATCH is a scratch GPR. */
13814 rs6000_split_compare_and_swap (rtx retval
, rtx mem
, rtx oldval
, rtx newval
,
13817 enum machine_mode mode
= GET_MODE (mem
);
13818 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
13820 emit_insn (gen_memory_barrier ());
13822 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
13823 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
13824 emit_label (XEXP (label1
, 0));
13826 emit_load_locked (mode
, retval
, mem
);
13828 x
= gen_rtx_COMPARE (CCmode
, retval
, oldval
);
13829 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
13831 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
13832 emit_unlikely_jump (x
, label2
);
13834 emit_move_insn (scratch
, newval
);
13835 emit_store_conditional (mode
, cond
, mem
, scratch
);
13837 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
13838 emit_unlikely_jump (x
, label1
);
13840 emit_insn (gen_isync ());
13841 emit_label (XEXP (label2
, 0));
13844 /* Expand an atomic test and set operation. MEM is the memory on which
13845 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
13848 rs6000_split_lock_test_and_set (rtx retval
, rtx mem
, rtx val
, rtx scratch
)
13850 enum machine_mode mode
= GET_MODE (mem
);
13851 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
13853 emit_insn (gen_memory_barrier ());
13855 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
13856 emit_label (XEXP (label
, 0));
13858 emit_load_locked (mode
, retval
, mem
);
13859 emit_move_insn (scratch
, val
);
13860 emit_store_conditional (mode
, cond
, mem
, scratch
);
13862 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
13863 emit_unlikely_jump (x
, label
);
13865 emit_insn (gen_isync ());
13869 rs6000_expand_compare_and_swapqhi (rtx dst
, rtx mem
, rtx oldval
, rtx newval
)
13871 enum machine_mode mode
= GET_MODE (mem
);
13872 rtx addrSI
, align
, wdst
, shift
, mask
;
13873 HOST_WIDE_INT shift_mask
= mode
== QImode
? 0x18 : 0x10;
13874 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
13876 /* Shift amount for subword relative to aligned word. */
13877 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
, XEXP (mem
, 0)));
13878 shift
= gen_reg_rtx (SImode
);
13879 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
13880 GEN_INT (shift_mask
)));
13881 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
13883 /* Shift and mask old value into position within word. */
13884 oldval
= convert_modes (SImode
, mode
, oldval
, 1);
13885 oldval
= expand_binop (SImode
, and_optab
,
13886 oldval
, GEN_INT (imask
), NULL_RTX
,
13887 1, OPTAB_LIB_WIDEN
);
13888 emit_insn (gen_ashlsi3 (oldval
, oldval
, shift
));
13890 /* Shift and mask new value into position within word. */
13891 newval
= convert_modes (SImode
, mode
, newval
, 1);
13892 newval
= expand_binop (SImode
, and_optab
,
13893 newval
, GEN_INT (imask
), NULL_RTX
,
13894 1, OPTAB_LIB_WIDEN
);
13895 emit_insn (gen_ashlsi3 (newval
, newval
, shift
));
13897 /* Mask for insertion. */
13898 mask
= gen_reg_rtx (SImode
);
13899 emit_move_insn (mask
, GEN_INT (imask
));
13900 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
13902 /* Address of aligned word containing subword. */
13903 align
= expand_binop (Pmode
, and_optab
, XEXP (mem
, 0), GEN_INT (-4),
13904 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
13905 mem
= change_address (mem
, SImode
, align
);
13906 set_mem_align (mem
, 32);
13907 MEM_VOLATILE_P (mem
) = 1;
13909 wdst
= gen_reg_rtx (SImode
);
13910 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst
, mask
,
13911 oldval
, newval
, mem
));
13913 /* Shift the result back. */
13914 emit_insn (gen_lshrsi3 (wdst
, wdst
, shift
));
13916 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
13920 rs6000_split_compare_and_swapqhi (rtx dest
, rtx mask
,
13921 rtx oldval
, rtx newval
, rtx mem
,
13924 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
13926 emit_insn (gen_memory_barrier ());
13927 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
13928 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
13929 emit_label (XEXP (label1
, 0));
13931 emit_load_locked (SImode
, scratch
, mem
);
13933 /* Mask subword within loaded value for comparison with oldval.
13934 Use UNSPEC_AND to avoid clobber.*/
13935 emit_insn (gen_rtx_SET (SImode
, dest
,
13936 gen_rtx_UNSPEC (SImode
,
13937 gen_rtvec (2, scratch
, mask
),
13940 x
= gen_rtx_COMPARE (CCmode
, dest
, oldval
);
13941 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
13943 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
13944 emit_unlikely_jump (x
, label2
);
13946 /* Clear subword within loaded value for insertion of new value. */
13947 emit_insn (gen_rtx_SET (SImode
, scratch
,
13948 gen_rtx_AND (SImode
,
13949 gen_rtx_NOT (SImode
, mask
), scratch
)));
13950 emit_insn (gen_iorsi3 (scratch
, scratch
, newval
));
13951 emit_store_conditional (SImode
, cond
, mem
, scratch
);
13953 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
13954 emit_unlikely_jump (x
, label1
);
13956 emit_insn (gen_isync ());
13957 emit_label (XEXP (label2
, 0));
13961 /* Emit instructions to move SRC to DST. Called by splitters for
13962 multi-register moves. It will emit at most one instruction for
13963 each register that is accessed; that is, it won't emit li/lis pairs
13964 (or equivalent for 64-bit code). One of SRC or DST must be a hard
13968 rs6000_split_multireg_move (rtx dst
, rtx src
)
13970 /* The register number of the first register being moved. */
13972 /* The mode that is to be moved. */
13973 enum machine_mode mode
;
13974 /* The mode that the move is being done in, and its size. */
13975 enum machine_mode reg_mode
;
13977 /* The number of registers that will be moved. */
13980 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
13981 mode
= GET_MODE (dst
);
13982 nregs
= hard_regno_nregs
[reg
][mode
];
13983 if (FP_REGNO_P (reg
))
13984 reg_mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
: DFmode
;
13985 else if (ALTIVEC_REGNO_P (reg
))
13986 reg_mode
= V16QImode
;
13987 else if (TARGET_E500_DOUBLE
&& (mode
== TFmode
|| mode
== TDmode
))
13988 reg_mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
: DFmode
;
13990 reg_mode
= word_mode
;
13991 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
13993 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
13995 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
13997 /* Move register range backwards, if we might have destructive
14000 for (i
= nregs
- 1; i
>= 0; i
--)
14001 emit_insn (gen_rtx_SET (VOIDmode
,
14002 simplify_gen_subreg (reg_mode
, dst
, mode
,
14003 i
* reg_mode_size
),
14004 simplify_gen_subreg (reg_mode
, src
, mode
,
14005 i
* reg_mode_size
)));
14011 bool used_update
= false;
14013 if (MEM_P (src
) && INT_REGNO_P (reg
))
14017 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
14018 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
14021 breg
= XEXP (XEXP (src
, 0), 0);
14022 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
14023 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
14024 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
14025 emit_insn (TARGET_32BIT
14026 ? gen_addsi3 (breg
, breg
, delta_rtx
)
14027 : gen_adddi3 (breg
, breg
, delta_rtx
));
14028 src
= replace_equiv_address (src
, breg
);
14030 else if (! rs6000_offsettable_memref_p (src
))
14033 basereg
= gen_rtx_REG (Pmode
, reg
);
14034 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
14035 src
= replace_equiv_address (src
, basereg
);
14038 breg
= XEXP (src
, 0);
14039 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
14040 breg
= XEXP (breg
, 0);
14042 /* If the base register we are using to address memory is
14043 also a destination reg, then change that register last. */
14045 && REGNO (breg
) >= REGNO (dst
)
14046 && REGNO (breg
) < REGNO (dst
) + nregs
)
14047 j
= REGNO (breg
) - REGNO (dst
);
14050 if (GET_CODE (dst
) == MEM
&& INT_REGNO_P (reg
))
14054 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
14055 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
14058 breg
= XEXP (XEXP (dst
, 0), 0);
14059 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
14060 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
14061 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
14063 /* We have to update the breg before doing the store.
14064 Use store with update, if available. */
14068 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
14069 emit_insn (TARGET_32BIT
14070 ? (TARGET_POWERPC64
14071 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
14072 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
14073 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
14074 used_update
= true;
14077 emit_insn (TARGET_32BIT
14078 ? gen_addsi3 (breg
, breg
, delta_rtx
)
14079 : gen_adddi3 (breg
, breg
, delta_rtx
));
14080 dst
= replace_equiv_address (dst
, breg
);
14083 gcc_assert (rs6000_offsettable_memref_p (dst
));
14086 for (i
= 0; i
< nregs
; i
++)
14088 /* Calculate index to next subword. */
14093 /* If compiler already emitted move of first word by
14094 store with update, no need to do anything. */
14095 if (j
== 0 && used_update
)
14098 emit_insn (gen_rtx_SET (VOIDmode
,
14099 simplify_gen_subreg (reg_mode
, dst
, mode
,
14100 j
* reg_mode_size
),
14101 simplify_gen_subreg (reg_mode
, src
, mode
,
14102 j
* reg_mode_size
)));
14108 /* This page contains routines that are used to determine what the
14109 function prologue and epilogue code will do and write them out. */
14111 /* Return the first fixed-point register that is required to be
14112 saved. 32 if none. */
14115 first_reg_to_save (void)
14119 /* Find lowest numbered live register. */
14120 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
14121 if (df_regs_ever_live_p (first_reg
)
14122 && (! call_used_regs
[first_reg
]
14123 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
14124 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
14125 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
14126 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
14131 && current_function_uses_pic_offset_table
14132 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
14133 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
14139 /* Similar, for FP regs. */
14142 first_fp_reg_to_save (void)
14146 /* Find lowest numbered live register. */
14147 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
14148 if (df_regs_ever_live_p (first_reg
))
14154 /* Similar, for AltiVec regs. */
14157 first_altivec_reg_to_save (void)
14161 /* Stack frame remains as is unless we are in AltiVec ABI. */
14162 if (! TARGET_ALTIVEC_ABI
)
14163 return LAST_ALTIVEC_REGNO
+ 1;
14165 /* On Darwin, the unwind routines are compiled without
14166 TARGET_ALTIVEC, and use save_world to save/restore the
14167 altivec registers when necessary. */
14168 if (DEFAULT_ABI
== ABI_DARWIN
&& current_function_calls_eh_return
14169 && ! TARGET_ALTIVEC
)
14170 return FIRST_ALTIVEC_REGNO
+ 20;
14172 /* Find lowest numbered live register. */
14173 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14174 if (df_regs_ever_live_p (i
))
14180 /* Return a 32-bit mask of the AltiVec registers we need to set in
14181 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
14182 the 32-bit word is 0. */
14184 static unsigned int
14185 compute_vrsave_mask (void)
14187 unsigned int i
, mask
= 0;
14189 /* On Darwin, the unwind routines are compiled without
14190 TARGET_ALTIVEC, and use save_world to save/restore the
14191 call-saved altivec registers when necessary. */
14192 if (DEFAULT_ABI
== ABI_DARWIN
&& current_function_calls_eh_return
14193 && ! TARGET_ALTIVEC
)
14196 /* First, find out if we use _any_ altivec registers. */
14197 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14198 if (df_regs_ever_live_p (i
))
14199 mask
|= ALTIVEC_REG_BIT (i
);
14204 /* Next, remove the argument registers from the set. These must
14205 be in the VRSAVE mask set by the caller, so we don't need to add
14206 them in again. More importantly, the mask we compute here is
14207 used to generate CLOBBERs in the set_vrsave insn, and we do not
14208 wish the argument registers to die. */
14209 for (i
= crtl
->args
.info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
14210 mask
&= ~ALTIVEC_REG_BIT (i
);
14212 /* Similarly, remove the return value from the set. */
14215 diddle_return_value (is_altivec_return_reg
, &yes
);
14217 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
14223 /* For a very restricted set of circumstances, we can cut down the
14224 size of prologues/epilogues by calling our own save/restore-the-world
14228 compute_save_world_info (rs6000_stack_t
*info_ptr
)
14230 info_ptr
->world_save_p
= 1;
14231 info_ptr
->world_save_p
14232 = (WORLD_SAVE_P (info_ptr
)
14233 && DEFAULT_ABI
== ABI_DARWIN
14234 && ! (current_function_calls_setjmp
&& flag_exceptions
)
14235 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
14236 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
14237 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
14238 && info_ptr
->cr_save_p
);
14240 /* This will not work in conjunction with sibcalls. Make sure there
14241 are none. (This check is expensive, but seldom executed.) */
14242 if (WORLD_SAVE_P (info_ptr
))
14245 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
14246 if ( GET_CODE (insn
) == CALL_INSN
14247 && SIBLING_CALL_P (insn
))
14249 info_ptr
->world_save_p
= 0;
14254 if (WORLD_SAVE_P (info_ptr
))
14256 /* Even if we're not touching VRsave, make sure there's room on the
14257 stack for it, if it looks like we're calling SAVE_WORLD, which
14258 will attempt to save it. */
14259 info_ptr
->vrsave_size
= 4;
14261 /* If we are going to save the world, we need to save the link register too. */
14262 info_ptr
->lr_save_p
= 1;
14264 /* "Save" the VRsave register too if we're saving the world. */
14265 if (info_ptr
->vrsave_mask
== 0)
14266 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
14268 /* Because the Darwin register save/restore routines only handle
14269 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
14271 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
14272 && (info_ptr
->first_altivec_reg_save
14273 >= FIRST_SAVED_ALTIVEC_REGNO
));
14280 is_altivec_return_reg (rtx reg
, void *xyes
)
14282 bool *yes
= (bool *) xyes
;
14283 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
14288 /* Calculate the stack information for the current function. This is
14289 complicated by having two separate calling sequences, the AIX calling
14290 sequence and the V.4 calling sequence.
14292 AIX (and Darwin/Mac OS X) stack frames look like:
14294 SP----> +---------------------------------------+
14295 | back chain to caller | 0 0
14296 +---------------------------------------+
14297 | saved CR | 4 8 (8-11)
14298 +---------------------------------------+
14300 +---------------------------------------+
14301 | reserved for compilers | 12 24
14302 +---------------------------------------+
14303 | reserved for binders | 16 32
14304 +---------------------------------------+
14305 | saved TOC pointer | 20 40
14306 +---------------------------------------+
14307 | Parameter save area (P) | 24 48
14308 +---------------------------------------+
14309 | Alloca space (A) | 24+P etc.
14310 +---------------------------------------+
14311 | Local variable space (L) | 24+P+A
14312 +---------------------------------------+
14313 | Float/int conversion temporary (X) | 24+P+A+L
14314 +---------------------------------------+
14315 | Save area for AltiVec registers (W) | 24+P+A+L+X
14316 +---------------------------------------+
14317 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
14318 +---------------------------------------+
14319 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
14320 +---------------------------------------+
14321 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
14322 +---------------------------------------+
14323 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
14324 +---------------------------------------+
14325 old SP->| back chain to caller's caller |
14326 +---------------------------------------+
14328 The required alignment for AIX configurations is two words (i.e., 8
14332 V.4 stack frames look like:
14334 SP----> +---------------------------------------+
14335 | back chain to caller | 0
14336 +---------------------------------------+
14337 | caller's saved LR | 4
14338 +---------------------------------------+
14339 | Parameter save area (P) | 8
14340 +---------------------------------------+
14341 | Alloca space (A) | 8+P
14342 +---------------------------------------+
14343 | Varargs save area (V) | 8+P+A
14344 +---------------------------------------+
14345 | Local variable space (L) | 8+P+A+V
14346 +---------------------------------------+
14347 | Float/int conversion temporary (X) | 8+P+A+V+L
14348 +---------------------------------------+
14349 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
14350 +---------------------------------------+
14351 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
14352 +---------------------------------------+
14353 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
14354 +---------------------------------------+
14355 | SPE: area for 64-bit GP registers |
14356 +---------------------------------------+
14357 | SPE alignment padding |
14358 +---------------------------------------+
14359 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
14360 +---------------------------------------+
14361 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
14362 +---------------------------------------+
14363 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
14364 +---------------------------------------+
14365 old SP->| back chain to caller's caller |
14366 +---------------------------------------+
14368 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
14369 given. (But note below and in sysv4.h that we require only 8 and
14370 may round up the size of our stack frame anyways. The historical
14371 reason is early versions of powerpc-linux which didn't properly
14372 align the stack at program startup. A happy side-effect is that
14373 -mno-eabi libraries can be used with -meabi programs.)
14375 The EABI configuration defaults to the V.4 layout. However,
14376 the stack alignment requirements may differ. If -mno-eabi is not
14377 given, the required stack alignment is 8 bytes; if -mno-eabi is
14378 given, the required alignment is 16 bytes. (But see V.4 comment
14381 #ifndef ABI_STACK_BOUNDARY
14382 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
14385 static rs6000_stack_t
*
14386 rs6000_stack_info (void)
14388 static rs6000_stack_t info
;
14389 rs6000_stack_t
*info_ptr
= &info
;
14390 int reg_size
= TARGET_32BIT
? 4 : 8;
14394 HOST_WIDE_INT non_fixed_size
;
14396 memset (&info
, 0, sizeof (info
));
14400 /* Cache value so we don't rescan instruction chain over and over. */
14401 if (cfun
->machine
->insn_chain_scanned_p
== 0)
14402 cfun
->machine
->insn_chain_scanned_p
14403 = spe_func_has_64bit_regs_p () + 1;
14404 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
14407 /* Select which calling sequence. */
14408 info_ptr
->abi
= DEFAULT_ABI
;
14410 /* Calculate which registers need to be saved & save area size. */
14411 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
14412 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
14413 even if it currently looks like we won't. Reload may need it to
14414 get at a constant; if so, it will have already created a constant
14415 pool entry for it. */
14416 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
14417 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
14418 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
14419 && current_function_uses_const_pool
14420 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
14421 first_gp
= RS6000_PIC_OFFSET_TABLE_REGNUM
;
14423 first_gp
= info_ptr
->first_gp_reg_save
;
14425 info_ptr
->gp_size
= reg_size
* (32 - first_gp
);
14427 /* For the SPE, we have an additional upper 32-bits on each GPR.
14428 Ideally we should save the entire 64-bits only when the upper
14429 half is used in SIMD instructions. Since we only record
14430 registers live (not the size they are used in), this proves
14431 difficult because we'd have to traverse the instruction chain at
14432 the right time, taking reload into account. This is a real pain,
14433 so we opt to save the GPRs in 64-bits always if but one register
14434 gets used in 64-bits. Otherwise, all the registers in the frame
14435 get saved in 32-bits.
14437 So... since when we save all GPRs (except the SP) in 64-bits, the
14438 traditional GP save area will be empty. */
14439 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
14440 info_ptr
->gp_size
= 0;
14442 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
14443 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
14445 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
14446 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
14447 - info_ptr
->first_altivec_reg_save
);
14449 /* Does this function call anything? */
14450 info_ptr
->calls_p
= (! current_function_is_leaf
14451 || cfun
->machine
->ra_needs_full_frame
);
14453 /* Determine if we need to save the link register. */
14454 if ((DEFAULT_ABI
== ABI_AIX
14455 && current_function_profile
14456 && !TARGET_PROFILE_KERNEL
)
14457 #ifdef TARGET_RELOCATABLE
14458 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
14460 || (info_ptr
->first_fp_reg_save
!= 64
14461 && !FP_SAVE_INLINE (info_ptr
->first_fp_reg_save
))
14462 || (DEFAULT_ABI
== ABI_V4
&& current_function_calls_alloca
)
14463 || info_ptr
->calls_p
14464 || rs6000_ra_ever_killed ())
14466 info_ptr
->lr_save_p
= 1;
14467 df_set_regs_ever_live (LR_REGNO
, true);
14470 /* Determine if we need to save the condition code registers. */
14471 if (df_regs_ever_live_p (CR2_REGNO
)
14472 || df_regs_ever_live_p (CR3_REGNO
)
14473 || df_regs_ever_live_p (CR4_REGNO
))
14475 info_ptr
->cr_save_p
= 1;
14476 if (DEFAULT_ABI
== ABI_V4
)
14477 info_ptr
->cr_size
= reg_size
;
14480 /* If the current function calls __builtin_eh_return, then we need
14481 to allocate stack space for registers that will hold data for
14482 the exception handler. */
14483 if (current_function_calls_eh_return
)
14486 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
14489 /* SPE saves EH registers in 64-bits. */
14490 ehrd_size
= i
* (TARGET_SPE_ABI
14491 && info_ptr
->spe_64bit_regs_used
!= 0
14492 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
14497 /* Determine various sizes. */
14498 info_ptr
->reg_size
= reg_size
;
14499 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
14500 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
14501 info_ptr
->parm_size
= RS6000_ALIGN (crtl
->outgoing_args_size
,
14502 TARGET_ALTIVEC
? 16 : 8);
14503 if (FRAME_GROWS_DOWNWARD
)
14504 info_ptr
->vars_size
14505 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
14506 + info_ptr
->parm_size
,
14507 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
14508 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
14509 + info_ptr
->parm_size
);
14511 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
14512 info_ptr
->spe_gp_size
= 8 * (32 - first_gp
);
14514 info_ptr
->spe_gp_size
= 0;
14516 if (TARGET_ALTIVEC_ABI
)
14517 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
14519 info_ptr
->vrsave_mask
= 0;
14521 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
14522 info_ptr
->vrsave_size
= 4;
14524 info_ptr
->vrsave_size
= 0;
14526 compute_save_world_info (info_ptr
);
14528 /* Calculate the offsets. */
14529 switch (DEFAULT_ABI
)
14533 gcc_unreachable ();
14537 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
14538 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
14540 if (TARGET_ALTIVEC_ABI
)
14542 info_ptr
->vrsave_save_offset
14543 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
14545 /* Align stack so vector save area is on a quadword boundary.
14546 The padding goes above the vectors. */
14547 if (info_ptr
->altivec_size
!= 0)
14548 info_ptr
->altivec_padding_size
14549 = info_ptr
->vrsave_save_offset
& 0xF;
14551 info_ptr
->altivec_padding_size
= 0;
14553 info_ptr
->altivec_save_offset
14554 = info_ptr
->vrsave_save_offset
14555 - info_ptr
->altivec_padding_size
14556 - info_ptr
->altivec_size
;
14557 gcc_assert (info_ptr
->altivec_size
== 0
14558 || info_ptr
->altivec_save_offset
% 16 == 0);
14560 /* Adjust for AltiVec case. */
14561 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
14564 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
14565 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
14566 info_ptr
->lr_save_offset
= 2*reg_size
;
14570 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
14571 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
14572 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
14574 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
14576 /* Align stack so SPE GPR save area is aligned on a
14577 double-word boundary. */
14578 if (info_ptr
->spe_gp_size
!= 0)
14579 info_ptr
->spe_padding_size
14580 = 8 - (-info_ptr
->cr_save_offset
% 8);
14582 info_ptr
->spe_padding_size
= 0;
14584 info_ptr
->spe_gp_save_offset
14585 = info_ptr
->cr_save_offset
14586 - info_ptr
->spe_padding_size
14587 - info_ptr
->spe_gp_size
;
14589 /* Adjust for SPE case. */
14590 info_ptr
->ehrd_offset
= info_ptr
->spe_gp_save_offset
;
14592 else if (TARGET_ALTIVEC_ABI
)
14594 info_ptr
->vrsave_save_offset
14595 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
14597 /* Align stack so vector save area is on a quadword boundary. */
14598 if (info_ptr
->altivec_size
!= 0)
14599 info_ptr
->altivec_padding_size
14600 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
14602 info_ptr
->altivec_padding_size
= 0;
14604 info_ptr
->altivec_save_offset
14605 = info_ptr
->vrsave_save_offset
14606 - info_ptr
->altivec_padding_size
14607 - info_ptr
->altivec_size
;
14609 /* Adjust for AltiVec case. */
14610 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
;
14613 info_ptr
->ehrd_offset
= info_ptr
->cr_save_offset
;
14614 info_ptr
->ehrd_offset
-= ehrd_size
;
14615 info_ptr
->lr_save_offset
= reg_size
;
14619 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
14620 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
14621 + info_ptr
->gp_size
14622 + info_ptr
->altivec_size
14623 + info_ptr
->altivec_padding_size
14624 + info_ptr
->spe_gp_size
14625 + info_ptr
->spe_padding_size
14627 + info_ptr
->cr_size
14628 + info_ptr
->vrsave_size
,
14631 non_fixed_size
= (info_ptr
->vars_size
14632 + info_ptr
->parm_size
14633 + info_ptr
->save_size
);
14635 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
14636 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
14638 /* Determine if we need to allocate any stack frame:
14640 For AIX we need to push the stack if a frame pointer is needed
14641 (because the stack might be dynamically adjusted), if we are
14642 debugging, if we make calls, or if the sum of fp_save, gp_save,
14643 and local variables are more than the space needed to save all
14644 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
14645 + 18*8 = 288 (GPR13 reserved).
14647 For V.4 we don't have the stack cushion that AIX uses, but assume
14648 that the debugger can handle stackless frames. */
14650 if (info_ptr
->calls_p
)
14651 info_ptr
->push_p
= 1;
14653 else if (DEFAULT_ABI
== ABI_V4
)
14654 info_ptr
->push_p
= non_fixed_size
!= 0;
14656 else if (frame_pointer_needed
)
14657 info_ptr
->push_p
= 1;
14659 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
14660 info_ptr
->push_p
= 1;
14663 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
14665 /* Zero offsets if we're not saving those registers. */
14666 if (info_ptr
->fp_size
== 0)
14667 info_ptr
->fp_save_offset
= 0;
14669 if (info_ptr
->gp_size
== 0)
14670 info_ptr
->gp_save_offset
= 0;
14672 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
14673 info_ptr
->altivec_save_offset
= 0;
14675 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
14676 info_ptr
->vrsave_save_offset
= 0;
14678 if (! TARGET_SPE_ABI
14679 || info_ptr
->spe_64bit_regs_used
== 0
14680 || info_ptr
->spe_gp_size
== 0)
14681 info_ptr
->spe_gp_save_offset
= 0;
14683 if (! info_ptr
->lr_save_p
)
14684 info_ptr
->lr_save_offset
= 0;
14686 if (! info_ptr
->cr_save_p
)
14687 info_ptr
->cr_save_offset
= 0;
14692 /* Return true if the current function uses any GPRs in 64-bit SIMD
14696 spe_func_has_64bit_regs_p (void)
14700 /* Functions that save and restore all the call-saved registers will
14701 need to save/restore the registers in 64-bits. */
14702 if (current_function_calls_eh_return
14703 || current_function_calls_setjmp
14704 || current_function_has_nonlocal_goto
)
14707 insns
= get_insns ();
14709 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
14715 /* FIXME: This should be implemented with attributes...
14717 (set_attr "spe64" "true")....then,
14718 if (get_spe64(insn)) return true;
14720 It's the only reliable way to do the stuff below. */
14722 i
= PATTERN (insn
);
14723 if (GET_CODE (i
) == SET
)
14725 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
14727 if (SPE_VECTOR_MODE (mode
))
14729 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
14730 || mode
== DDmode
|| mode
== TDmode
))
14740 debug_stack_info (rs6000_stack_t
*info
)
14742 const char *abi_string
;
14745 info
= rs6000_stack_info ();
14747 fprintf (stderr
, "\nStack information for function %s:\n",
14748 ((current_function_decl
&& DECL_NAME (current_function_decl
))
14749 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
14754 default: abi_string
= "Unknown"; break;
14755 case ABI_NONE
: abi_string
= "NONE"; break;
14756 case ABI_AIX
: abi_string
= "AIX"; break;
14757 case ABI_DARWIN
: abi_string
= "Darwin"; break;
14758 case ABI_V4
: abi_string
= "V.4"; break;
14761 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
14763 if (TARGET_ALTIVEC_ABI
)
14764 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
14766 if (TARGET_SPE_ABI
)
14767 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
14769 if (info
->first_gp_reg_save
!= 32)
14770 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
14772 if (info
->first_fp_reg_save
!= 64)
14773 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
14775 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
14776 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
14777 info
->first_altivec_reg_save
);
14779 if (info
->lr_save_p
)
14780 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
14782 if (info
->cr_save_p
)
14783 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
14785 if (info
->vrsave_mask
)
14786 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
14789 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
14792 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
14794 if (info
->gp_save_offset
)
14795 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
14797 if (info
->fp_save_offset
)
14798 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
14800 if (info
->altivec_save_offset
)
14801 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
14802 info
->altivec_save_offset
);
14804 if (info
->spe_gp_save_offset
)
14805 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
14806 info
->spe_gp_save_offset
);
14808 if (info
->vrsave_save_offset
)
14809 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
14810 info
->vrsave_save_offset
);
14812 if (info
->lr_save_offset
)
14813 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
14815 if (info
->cr_save_offset
)
14816 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
14818 if (info
->varargs_save_offset
)
14819 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
14821 if (info
->total_size
)
14822 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
14825 if (info
->vars_size
)
14826 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
14829 if (info
->parm_size
)
14830 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
14832 if (info
->fixed_size
)
14833 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
14836 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
14838 if (info
->spe_gp_size
)
14839 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
14842 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
14844 if (info
->altivec_size
)
14845 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
14847 if (info
->vrsave_size
)
14848 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
14850 if (info
->altivec_padding_size
)
14851 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
14852 info
->altivec_padding_size
);
14854 if (info
->spe_padding_size
)
14855 fprintf (stderr
, "\tspe_padding_size = %5d\n",
14856 info
->spe_padding_size
);
14859 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
14861 if (info
->save_size
)
14862 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
14864 if (info
->reg_size
!= 4)
14865 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
14867 fprintf (stderr
, "\n");
14871 rs6000_return_addr (int count
, rtx frame
)
14873 /* Currently we don't optimize very well between prolog and body
14874 code and for PIC code the code can be actually quite bad, so
14875 don't try to be too clever here. */
14876 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
14878 cfun
->machine
->ra_needs_full_frame
= 1;
14885 plus_constant (copy_to_reg
14886 (gen_rtx_MEM (Pmode
,
14887 memory_address (Pmode
, frame
))),
14888 RETURN_ADDRESS_OFFSET
)));
14891 cfun
->machine
->ra_need_lr
= 1;
14892 return get_hard_reg_initial_val (Pmode
, LR_REGNO
);
14895 /* Say whether a function is a candidate for sibcall handling or not.
14896 We do not allow indirect calls to be optimized into sibling calls.
14897 Also, we can't do it if there are any vector parameters; there's
14898 nowhere to put the VRsave code so it works; note that functions with
14899 vector parameters are required to have a prototype, so the argument
14900 type info must be available here. (The tail recursion case can work
14901 with vector parameters, but there's no way to distinguish here.) */
14903 rs6000_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
14908 if (TARGET_ALTIVEC_VRSAVE
)
14910 for (type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
14911 type
; type
= TREE_CHAIN (type
))
14913 if (TREE_CODE (TREE_VALUE (type
)) == VECTOR_TYPE
)
14917 if (DEFAULT_ABI
== ABI_DARWIN
14918 || ((*targetm
.binds_local_p
) (decl
)
14919 && (DEFAULT_ABI
!= ABI_AIX
|| !DECL_EXTERNAL (decl
))))
14921 tree attr_list
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
14923 if (!lookup_attribute ("longcall", attr_list
)
14924 || lookup_attribute ("shortcall", attr_list
))
14931 /* NULL if INSN insn is valid within a low-overhead loop.
14932 Otherwise return why doloop cannot be applied.
14933 PowerPC uses the COUNT register for branch on table instructions. */
14935 static const char *
14936 rs6000_invalid_within_doloop (const_rtx insn
)
14939 return "Function call in the loop.";
14942 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
14943 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
14944 return "Computed branch in the loop.";
14950 rs6000_ra_ever_killed (void)
14956 if (current_function_is_thunk
)
14959 /* regs_ever_live has LR marked as used if any sibcalls are present,
14960 but this should not force saving and restoring in the
14961 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
14962 clobbers LR, so that is inappropriate. */
14964 /* Also, the prologue can generate a store into LR that
14965 doesn't really count, like this:
14968 bcl to set PIC register
14972 When we're called from the epilogue, we need to avoid counting
14973 this as a store. */
14975 push_topmost_sequence ();
14976 top
= get_insns ();
14977 pop_topmost_sequence ();
14978 reg
= gen_rtx_REG (Pmode
, LR_REGNO
);
14980 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
14986 if (!SIBLING_CALL_P (insn
))
14989 else if (find_regno_note (insn
, REG_INC
, LR_REGNO
))
14991 else if (set_of (reg
, insn
) != NULL_RTX
14992 && !prologue_epilogue_contains (insn
))
14999 /* Emit instructions needed to load the TOC register.
15000 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
15001 a constant pool; or for SVR4 -fpic. */
15004 rs6000_emit_load_toc_table (int fromprolog
)
15007 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
15009 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
15012 rtx lab
, tmp1
, tmp2
, got
;
15014 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
15015 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15017 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
15019 got
= rs6000_got_sym ();
15020 tmp1
= tmp2
= dest
;
15023 tmp1
= gen_reg_rtx (Pmode
);
15024 tmp2
= gen_reg_rtx (Pmode
);
15026 emit_insn (gen_load_toc_v4_PIC_1 (lab
));
15027 emit_move_insn (tmp1
,
15028 gen_rtx_REG (Pmode
, LR_REGNO
));
15029 emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
15030 emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
15032 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
15034 emit_insn (gen_load_toc_v4_pic_si ());
15035 emit_move_insn (dest
, gen_rtx_REG (Pmode
, LR_REGNO
));
15037 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
15040 rtx temp0
= (fromprolog
15041 ? gen_rtx_REG (Pmode
, 0)
15042 : gen_reg_rtx (Pmode
));
15048 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
15049 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15051 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
15052 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15054 emit_insn (gen_load_toc_v4_PIC_1 (symF
));
15055 emit_move_insn (dest
,
15056 gen_rtx_REG (Pmode
, LR_REGNO
));
15057 emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
, symL
, symF
));
15063 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
15064 emit_insn (gen_load_toc_v4_PIC_1b (tocsym
));
15065 emit_move_insn (dest
,
15066 gen_rtx_REG (Pmode
, LR_REGNO
));
15067 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
15069 emit_insn (gen_addsi3 (dest
, temp0
, dest
));
15071 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
15073 /* This is for AIX code running in non-PIC ELF32. */
15076 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
15077 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
15079 emit_insn (gen_elf_high (dest
, realsym
));
15080 emit_insn (gen_elf_low (dest
, dest
, realsym
));
15084 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
15087 emit_insn (gen_load_toc_aix_si (dest
));
15089 emit_insn (gen_load_toc_aix_di (dest
));
15093 /* Emit instructions to restore the link register after determining where
15094 its value has been stored. */
15097 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
15099 rs6000_stack_t
*info
= rs6000_stack_info ();
15102 operands
[0] = source
;
15103 operands
[1] = scratch
;
15105 if (info
->lr_save_p
)
15107 rtx frame_rtx
= stack_pointer_rtx
;
15108 HOST_WIDE_INT sp_offset
= 0;
15111 if (frame_pointer_needed
15112 || current_function_calls_alloca
15113 || info
->total_size
> 32767)
15115 tmp
= gen_frame_mem (Pmode
, frame_rtx
);
15116 emit_move_insn (operands
[1], tmp
);
15117 frame_rtx
= operands
[1];
15119 else if (info
->push_p
)
15120 sp_offset
= info
->total_size
;
15122 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
15123 tmp
= gen_frame_mem (Pmode
, tmp
);
15124 emit_move_insn (tmp
, operands
[0]);
15127 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
), operands
[0]);
15130 static GTY(()) alias_set_type set
= -1;
15133 get_TOC_alias_set (void)
15136 set
= new_alias_set ();
15140 /* This returns nonzero if the current function uses the TOC. This is
15141 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
15142 is generated by the ABI_V4 load_toc_* patterns. */
15149 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
15152 rtx pat
= PATTERN (insn
);
15155 if (GET_CODE (pat
) == PARALLEL
)
15156 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
15158 rtx sub
= XVECEXP (pat
, 0, i
);
15159 if (GET_CODE (sub
) == USE
)
15161 sub
= XEXP (sub
, 0);
15162 if (GET_CODE (sub
) == UNSPEC
15163 && XINT (sub
, 1) == UNSPEC_TOC
)
15173 create_TOC_reference (rtx symbol
)
15175 if (!can_create_pseudo_p ())
15176 df_set_regs_ever_live (TOC_REGISTER
, true);
15177 return gen_rtx_PLUS (Pmode
,
15178 gen_rtx_REG (Pmode
, TOC_REGISTER
),
15179 gen_rtx_CONST (Pmode
,
15180 gen_rtx_MINUS (Pmode
, symbol
,
15181 gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
))));
15184 /* If _Unwind_* has been called from within the same module,
15185 toc register is not guaranteed to be saved to 40(1) on function
15186 entry. Save it there in that case. */
15189 rs6000_aix_emit_builtin_unwind_init (void)
15192 rtx stack_top
= gen_reg_rtx (Pmode
);
15193 rtx opcode_addr
= gen_reg_rtx (Pmode
);
15194 rtx opcode
= gen_reg_rtx (SImode
);
15195 rtx tocompare
= gen_reg_rtx (SImode
);
15196 rtx no_toc_save_needed
= gen_label_rtx ();
15198 mem
= gen_frame_mem (Pmode
, hard_frame_pointer_rtx
);
15199 emit_move_insn (stack_top
, mem
);
15201 mem
= gen_frame_mem (Pmode
,
15202 gen_rtx_PLUS (Pmode
, stack_top
,
15203 GEN_INT (2 * GET_MODE_SIZE (Pmode
))));
15204 emit_move_insn (opcode_addr
, mem
);
15205 emit_move_insn (opcode
, gen_rtx_MEM (SImode
, opcode_addr
));
15206 emit_move_insn (tocompare
, gen_int_mode (TARGET_32BIT
? 0x80410014
15207 : 0xE8410028, SImode
));
15209 do_compare_rtx_and_jump (opcode
, tocompare
, EQ
, 1,
15210 SImode
, NULL_RTX
, NULL_RTX
,
15211 no_toc_save_needed
);
15213 mem
= gen_frame_mem (Pmode
,
15214 gen_rtx_PLUS (Pmode
, stack_top
,
15215 GEN_INT (5 * GET_MODE_SIZE (Pmode
))));
15216 emit_move_insn (mem
, gen_rtx_REG (Pmode
, 2));
15217 emit_label (no_toc_save_needed
);
15220 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
15221 and the change to the stack pointer. */
15224 rs6000_emit_stack_tie (void)
15226 rtx mem
= gen_frame_mem (BLKmode
,
15227 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
15229 emit_insn (gen_stack_tie (mem
));
15232 /* Emit the correct code for allocating stack space, as insns.
15233 If COPY_R12, make sure a copy of the old frame is left in r12.
15234 The generated code may use hard register 0 as a temporary. */
15237 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, int copy_r12
)
15240 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
15241 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
15242 rtx todec
= gen_int_mode (-size
, Pmode
);
15244 if (INTVAL (todec
) != -size
)
15246 warning (0, "stack frame too large");
15247 emit_insn (gen_trap ());
15251 if (current_function_limit_stack
)
15253 if (REG_P (stack_limit_rtx
)
15254 && REGNO (stack_limit_rtx
) > 1
15255 && REGNO (stack_limit_rtx
) <= 31)
15257 emit_insn (TARGET_32BIT
15258 ? gen_addsi3 (tmp_reg
,
15261 : gen_adddi3 (tmp_reg
,
15265 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
15268 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
15270 && DEFAULT_ABI
== ABI_V4
)
15272 rtx toload
= gen_rtx_CONST (VOIDmode
,
15273 gen_rtx_PLUS (Pmode
,
15277 emit_insn (gen_elf_high (tmp_reg
, toload
));
15278 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
15279 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
15283 warning (0, "stack limit expression is not supported");
15286 if (copy_r12
|| ! TARGET_UPDATE
)
15287 emit_move_insn (gen_rtx_REG (Pmode
, 12), stack_reg
);
15293 /* Need a note here so that try_split doesn't get confused. */
15294 if (get_last_insn () == NULL_RTX
)
15295 emit_note (NOTE_INSN_DELETED
);
15296 insn
= emit_move_insn (tmp_reg
, todec
);
15297 try_split (PATTERN (insn
), insn
, 0);
15301 insn
= emit_insn (TARGET_32BIT
15302 ? gen_movsi_update (stack_reg
, stack_reg
,
15304 : gen_movdi_di_update (stack_reg
, stack_reg
,
15305 todec
, stack_reg
));
15309 insn
= emit_insn (TARGET_32BIT
15310 ? gen_addsi3 (stack_reg
, stack_reg
, todec
)
15311 : gen_adddi3 (stack_reg
, stack_reg
, todec
));
15312 emit_move_insn (gen_rtx_MEM (Pmode
, stack_reg
),
15313 gen_rtx_REG (Pmode
, 12));
15316 RTX_FRAME_RELATED_P (insn
) = 1;
15318 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
15319 gen_rtx_SET (VOIDmode
, stack_reg
,
15320 gen_rtx_PLUS (Pmode
, stack_reg
,
15325 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
15326 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
15327 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
15328 deduce these equivalences by itself so it wasn't necessary to hold
15329 its hand so much. */
15332 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
15333 rtx reg2
, rtx rreg
)
15337 /* copy_rtx will not make unique copies of registers, so we need to
15338 ensure we don't have unwanted sharing here. */
15340 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
15343 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
15345 real
= copy_rtx (PATTERN (insn
));
15347 if (reg2
!= NULL_RTX
)
15348 real
= replace_rtx (real
, reg2
, rreg
);
15350 real
= replace_rtx (real
, reg
,
15351 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
15352 STACK_POINTER_REGNUM
),
15355 /* We expect that 'real' is either a SET or a PARALLEL containing
15356 SETs (and possibly other stuff). In a PARALLEL, all the SETs
15357 are important so they all have to be marked RTX_FRAME_RELATED_P. */
15359 if (GET_CODE (real
) == SET
)
15363 temp
= simplify_rtx (SET_SRC (set
));
15365 SET_SRC (set
) = temp
;
15366 temp
= simplify_rtx (SET_DEST (set
));
15368 SET_DEST (set
) = temp
;
15369 if (GET_CODE (SET_DEST (set
)) == MEM
)
15371 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
15373 XEXP (SET_DEST (set
), 0) = temp
;
15380 gcc_assert (GET_CODE (real
) == PARALLEL
);
15381 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
15382 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
15384 rtx set
= XVECEXP (real
, 0, i
);
15386 temp
= simplify_rtx (SET_SRC (set
));
15388 SET_SRC (set
) = temp
;
15389 temp
= simplify_rtx (SET_DEST (set
));
15391 SET_DEST (set
) = temp
;
15392 if (GET_CODE (SET_DEST (set
)) == MEM
)
15394 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
15396 XEXP (SET_DEST (set
), 0) = temp
;
15398 RTX_FRAME_RELATED_P (set
) = 1;
15402 RTX_FRAME_RELATED_P (insn
) = 1;
15403 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
15408 /* Returns an insn that has a vrsave set operation with the
15409 appropriate CLOBBERs. */
15412 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
15415 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
15416 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
15419 = gen_rtx_SET (VOIDmode
,
15421 gen_rtx_UNSPEC_VOLATILE (SImode
,
15422 gen_rtvec (2, reg
, vrsave
),
15423 UNSPECV_SET_VRSAVE
));
15427 /* We need to clobber the registers in the mask so the scheduler
15428 does not move sets to VRSAVE before sets of AltiVec registers.
15430 However, if the function receives nonlocal gotos, reload will set
15431 all call saved registers live. We will end up with:
15433 (set (reg 999) (mem))
15434 (parallel [ (set (reg vrsave) (unspec blah))
15435 (clobber (reg 999))])
15437 The clobber will cause the store into reg 999 to be dead, and
15438 flow will attempt to delete an epilogue insn. In this case, we
15439 need an unspec use/set of the register. */
15441 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
15442 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
15444 if (!epiloguep
|| call_used_regs
[i
])
15445 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
15446 gen_rtx_REG (V4SImode
, i
));
15449 rtx reg
= gen_rtx_REG (V4SImode
, i
);
15452 = gen_rtx_SET (VOIDmode
,
15454 gen_rtx_UNSPEC (V4SImode
,
15455 gen_rtvec (1, reg
), 27));
15459 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
15461 for (i
= 0; i
< nclobs
; ++i
)
15462 XVECEXP (insn
, 0, i
) = clobs
[i
];
15467 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
15468 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
15471 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
15472 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
15474 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
15475 rtx replacea
, replaceb
;
15477 int_rtx
= GEN_INT (offset
);
15479 /* Some cases that need register indexed addressing. */
15480 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
15481 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== DDmode
))
15483 && SPE_VECTOR_MODE (mode
)
15484 && !SPE_CONST_OFFSET_OK (offset
)))
15486 /* Whomever calls us must make sure r11 is available in the
15487 flow path of instructions in the prologue. */
15488 offset_rtx
= gen_rtx_REG (Pmode
, 11);
15489 emit_move_insn (offset_rtx
, int_rtx
);
15491 replacea
= offset_rtx
;
15492 replaceb
= int_rtx
;
15496 offset_rtx
= int_rtx
;
15497 replacea
= NULL_RTX
;
15498 replaceb
= NULL_RTX
;
15501 reg
= gen_rtx_REG (mode
, regno
);
15502 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
15503 mem
= gen_frame_mem (mode
, addr
);
15505 insn
= emit_move_insn (mem
, reg
);
15507 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
15510 /* Emit an offset memory reference suitable for a frame store, while
15511 converting to a valid addressing mode. */
15514 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
15516 rtx int_rtx
, offset_rtx
;
15518 int_rtx
= GEN_INT (offset
);
15520 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
15521 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== DDmode
)))
15523 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
15524 emit_move_insn (offset_rtx
, int_rtx
);
15527 offset_rtx
= int_rtx
;
15529 return gen_frame_mem (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
15532 /* Look for user-defined global regs. We should not save and restore these,
15533 and cannot use stmw/lmw if there are any in its range. */
15536 no_global_regs_above (int first_greg
)
15539 for (i
= 0; i
< 32 - first_greg
; i
++)
15540 if (global_regs
[first_greg
+ i
])
15545 #ifndef TARGET_FIX_AND_CONTINUE
15546 #define TARGET_FIX_AND_CONTINUE 0
15549 /* Determine whether the gp REG is really used. */
15552 rs6000_reg_live_or_pic_offset_p (int reg
)
15554 return ((df_regs_ever_live_p (reg
)
15555 && (!call_used_regs
[reg
]
15556 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
15557 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
15558 || (reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
15559 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
15560 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))));
15563 /* Emit function prologue as insns. */
15566 rs6000_emit_prologue (void)
15568 rs6000_stack_t
*info
= rs6000_stack_info ();
15569 enum machine_mode reg_mode
= Pmode
;
15570 int reg_size
= TARGET_32BIT
? 4 : 8;
15571 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
15572 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
15573 rtx frame_reg_rtx
= sp_reg_rtx
;
15574 rtx cr_save_rtx
= NULL_RTX
;
15576 int saving_FPRs_inline
;
15577 int using_store_multiple
;
15578 HOST_WIDE_INT sp_offset
= 0;
15580 if (TARGET_FIX_AND_CONTINUE
)
15582 /* gdb on darwin arranges to forward a function from the old
15583 address by modifying the first 5 instructions of the function
15584 to branch to the overriding function. This is necessary to
15585 permit function pointers that point to the old function to
15586 actually forward to the new function. */
15587 emit_insn (gen_nop ());
15588 emit_insn (gen_nop ());
15589 emit_insn (gen_nop ());
15590 emit_insn (gen_nop ());
15591 emit_insn (gen_nop ());
15594 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
15596 reg_mode
= V2SImode
;
15600 using_store_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
15601 && (!TARGET_SPE_ABI
15602 || info
->spe_64bit_regs_used
== 0)
15603 && info
->first_gp_reg_save
< 31
15604 && no_global_regs_above (info
->first_gp_reg_save
));
15605 saving_FPRs_inline
= (info
->first_fp_reg_save
== 64
15606 || FP_SAVE_INLINE (info
->first_fp_reg_save
)
15607 || current_function_calls_eh_return
15608 || cfun
->machine
->ra_need_lr
);
15610 /* For V.4, update stack before we do any saving and set back pointer. */
15611 if (! WORLD_SAVE_P (info
)
15613 && (DEFAULT_ABI
== ABI_V4
15614 || current_function_calls_eh_return
))
15616 if (info
->total_size
< 32767)
15617 sp_offset
= info
->total_size
;
15619 frame_reg_rtx
= frame_ptr_rtx
;
15620 rs6000_emit_allocate_stack (info
->total_size
,
15621 (frame_reg_rtx
!= sp_reg_rtx
15622 && (info
->cr_save_p
15624 || info
->first_fp_reg_save
< 64
15625 || info
->first_gp_reg_save
< 32
15627 if (frame_reg_rtx
!= sp_reg_rtx
)
15628 rs6000_emit_stack_tie ();
15631 /* Handle world saves specially here. */
15632 if (WORLD_SAVE_P (info
))
15639 /* save_world expects lr in r0. */
15640 reg0
= gen_rtx_REG (Pmode
, 0);
15641 if (info
->lr_save_p
)
15643 insn
= emit_move_insn (reg0
,
15644 gen_rtx_REG (Pmode
, LR_REGNO
));
15645 RTX_FRAME_RELATED_P (insn
) = 1;
15648 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
15649 assumptions about the offsets of various bits of the stack
15651 gcc_assert (info
->gp_save_offset
== -220
15652 && info
->fp_save_offset
== -144
15653 && info
->lr_save_offset
== 8
15654 && info
->cr_save_offset
== 4
15657 && (!current_function_calls_eh_return
15658 || info
->ehrd_offset
== -432)
15659 && info
->vrsave_save_offset
== -224
15660 && info
->altivec_save_offset
== -416);
15662 treg
= gen_rtx_REG (SImode
, 11);
15663 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
15665 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
15666 in R11. It also clobbers R12, so beware! */
15668 /* Preserve CR2 for save_world prologues */
15670 sz
+= 32 - info
->first_gp_reg_save
;
15671 sz
+= 64 - info
->first_fp_reg_save
;
15672 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
15673 p
= rtvec_alloc (sz
);
15675 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
15676 gen_rtx_REG (SImode
,
15678 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
15679 gen_rtx_SYMBOL_REF (Pmode
,
15681 /* We do floats first so that the instruction pattern matches
15683 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
15685 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
15686 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15687 GEN_INT (info
->fp_save_offset
15688 + sp_offset
+ 8 * i
));
15689 rtx mem
= gen_frame_mem (DFmode
, addr
);
15691 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
15693 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
15695 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
15696 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15697 GEN_INT (info
->altivec_save_offset
15698 + sp_offset
+ 16 * i
));
15699 rtx mem
= gen_frame_mem (V4SImode
, addr
);
15701 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
15703 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
15705 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
15706 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15707 GEN_INT (info
->gp_save_offset
15708 + sp_offset
+ reg_size
* i
));
15709 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15711 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
15715 /* CR register traditionally saved as CR2. */
15716 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
15717 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15718 GEN_INT (info
->cr_save_offset
15720 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15722 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
15724 /* Explain about use of R0. */
15725 if (info
->lr_save_p
)
15727 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15728 GEN_INT (info
->lr_save_offset
15730 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15732 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg0
);
15734 /* Explain what happens to the stack pointer. */
15736 rtx newval
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
, treg
);
15737 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, sp_reg_rtx
, newval
);
15740 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15741 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15742 treg
, GEN_INT (-info
->total_size
));
15743 sp_offset
= info
->total_size
;
15746 /* If we use the link register, get it into r0. */
15747 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
15749 rtx addr
, reg
, mem
;
15751 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
15752 gen_rtx_REG (Pmode
, LR_REGNO
));
15753 RTX_FRAME_RELATED_P (insn
) = 1;
15755 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15756 GEN_INT (info
->lr_save_offset
+ sp_offset
));
15757 reg
= gen_rtx_REG (Pmode
, 0);
15758 mem
= gen_rtx_MEM (Pmode
, addr
);
15759 /* This should not be of rs6000_sr_alias_set, because of
15760 __builtin_return_address. */
15762 insn
= emit_move_insn (mem
, reg
);
15763 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15764 NULL_RTX
, NULL_RTX
);
15767 /* If we need to save CR, put it into r12. */
15768 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
15772 cr_save_rtx
= gen_rtx_REG (SImode
, 12);
15773 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
15774 RTX_FRAME_RELATED_P (insn
) = 1;
15775 /* Now, there's no way that dwarf2out_frame_debug_expr is going
15776 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
15777 But that's OK. All we have to do is specify that _one_ condition
15778 code register is saved in this stack slot. The thrower's epilogue
15779 will then restore all the call-saved registers.
15780 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
15781 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
15782 gen_rtx_REG (SImode
, CR2_REGNO
));
15783 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
15788 /* Do any required saving of fpr's. If only one or two to save, do
15789 it ourselves. Otherwise, call function. */
15790 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
15793 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
15794 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
15795 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
15796 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, DFmode
,
15797 info
->first_fp_reg_save
+ i
,
15798 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
15801 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
15805 const char *alloc_rname
;
15807 p
= rtvec_alloc (2 + 64 - info
->first_fp_reg_save
);
15809 RTVEC_ELT (p
, 0) = gen_rtx_CLOBBER (VOIDmode
,
15810 gen_rtx_REG (Pmode
,
15812 sprintf (rname
, "%s%d%s", SAVE_FP_PREFIX
,
15813 info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
);
15814 alloc_rname
= ggc_strdup (rname
);
15815 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
15816 gen_rtx_SYMBOL_REF (Pmode
,
15818 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
15820 rtx addr
, reg
, mem
;
15821 reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
15822 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15823 GEN_INT (info
->fp_save_offset
15824 + sp_offset
+ 8*i
));
15825 mem
= gen_frame_mem (DFmode
, addr
);
15827 RTVEC_ELT (p
, i
+ 2) = gen_rtx_SET (VOIDmode
, mem
, reg
);
15829 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15830 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15831 NULL_RTX
, NULL_RTX
);
15834 /* Save GPRs. This is done as a PARALLEL if we are using
15835 the store-multiple instructions. */
15836 if (!WORLD_SAVE_P (info
) && using_store_multiple
)
15840 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
15841 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
15843 rtx addr
, reg
, mem
;
15844 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
15845 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15846 GEN_INT (info
->gp_save_offset
15849 mem
= gen_frame_mem (reg_mode
, addr
);
15851 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
15853 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15854 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15855 NULL_RTX
, NULL_RTX
);
15857 else if (!WORLD_SAVE_P (info
)
15859 && info
->spe_64bit_regs_used
!= 0
15860 && info
->first_gp_reg_save
!= 32)
15863 rtx spe_save_area_ptr
;
15864 int using_static_chain_p
= (cfun
->static_chain_decl
!= NULL_TREE
15865 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM
)
15866 && !call_used_regs
[STATIC_CHAIN_REGNUM
]);
15868 /* Determine whether we can address all of the registers that need
15869 to be saved with an offset from the stack pointer that fits in
15870 the small const field for SPE memory instructions. */
15871 int spe_regs_addressable_via_sp
15872 = SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
15873 + (32 - info
->first_gp_reg_save
- 1) * reg_size
);
15876 if (spe_regs_addressable_via_sp
)
15878 spe_save_area_ptr
= frame_reg_rtx
;
15879 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
15883 /* Make r11 point to the start of the SPE save area. We need
15884 to be careful here if r11 is holding the static chain. If
15885 it is, then temporarily save it in r0. We would use r0 as
15886 our base register here, but using r0 as a base register in
15887 loads and stores means something different from what we
15889 if (using_static_chain_p
)
15891 rtx r0
= gen_rtx_REG (Pmode
, 0);
15893 gcc_assert (info
->first_gp_reg_save
> 11);
15895 emit_move_insn (r0
, gen_rtx_REG (Pmode
, 11));
15898 spe_save_area_ptr
= gen_rtx_REG (Pmode
, 11);
15899 emit_insn (gen_addsi3 (spe_save_area_ptr
, frame_reg_rtx
,
15900 GEN_INT (info
->spe_gp_save_offset
+ sp_offset
)));
15905 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
15906 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
15908 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
15909 rtx offset
, addr
, mem
;
15911 /* We're doing all this to ensure that the offset fits into
15912 the immediate offset of 'evstdd'. */
15913 gcc_assert (SPE_CONST_OFFSET_OK (reg_size
* i
+ spe_offset
));
15915 offset
= GEN_INT (reg_size
* i
+ spe_offset
);
15916 addr
= gen_rtx_PLUS (Pmode
, spe_save_area_ptr
, offset
);
15917 mem
= gen_rtx_MEM (V2SImode
, addr
);
15919 insn
= emit_move_insn (mem
, reg
);
15921 rs6000_frame_related (insn
, spe_save_area_ptr
,
15922 info
->spe_gp_save_offset
15923 + sp_offset
+ reg_size
* i
,
15924 offset
, const0_rtx
);
15927 /* Move the static chain pointer back. */
15928 if (using_static_chain_p
&& !spe_regs_addressable_via_sp
)
15929 emit_move_insn (gen_rtx_REG (Pmode
, 11), gen_rtx_REG (Pmode
, 0));
15931 else if (!WORLD_SAVE_P (info
))
15934 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
15935 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
15937 rtx addr
, reg
, mem
;
15938 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
15940 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15941 GEN_INT (info
->gp_save_offset
15944 mem
= gen_frame_mem (reg_mode
, addr
);
15946 insn
= emit_move_insn (mem
, reg
);
15947 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15948 NULL_RTX
, NULL_RTX
);
15952 /* ??? There's no need to emit actual instructions here, but it's the
15953 easiest way to get the frame unwind information emitted. */
15954 if (current_function_calls_eh_return
)
15956 unsigned int i
, regno
;
15958 /* In AIX ABI we need to pretend we save r2 here. */
15961 rtx addr
, reg
, mem
;
15963 reg
= gen_rtx_REG (reg_mode
, 2);
15964 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15965 GEN_INT (sp_offset
+ 5 * reg_size
));
15966 mem
= gen_frame_mem (reg_mode
, addr
);
15968 insn
= emit_move_insn (mem
, reg
);
15969 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15970 NULL_RTX
, NULL_RTX
);
15971 PATTERN (insn
) = gen_blockage ();
15976 regno
= EH_RETURN_DATA_REGNO (i
);
15977 if (regno
== INVALID_REGNUM
)
15980 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
15981 info
->ehrd_offset
+ sp_offset
15982 + reg_size
* (int) i
,
15987 /* Save CR if we use any that must be preserved. */
15988 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
15990 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15991 GEN_INT (info
->cr_save_offset
+ sp_offset
));
15992 rtx mem
= gen_frame_mem (SImode
, addr
);
15993 /* See the large comment above about why CR2_REGNO is used. */
15994 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
15996 /* If r12 was used to hold the original sp, copy cr into r0 now
15998 if (REGNO (frame_reg_rtx
) == 12)
16002 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
16003 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
16004 RTX_FRAME_RELATED_P (insn
) = 1;
16005 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
16006 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
16011 insn
= emit_move_insn (mem
, cr_save_rtx
);
16013 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16014 NULL_RTX
, NULL_RTX
);
16017 /* Update stack and set back pointer unless this is V.4,
16018 for which it was done previously. */
16019 if (!WORLD_SAVE_P (info
) && info
->push_p
16020 && !(DEFAULT_ABI
== ABI_V4
|| current_function_calls_eh_return
))
16022 if (info
->total_size
< 32767)
16023 sp_offset
= info
->total_size
;
16025 frame_reg_rtx
= frame_ptr_rtx
;
16026 rs6000_emit_allocate_stack (info
->total_size
,
16027 (frame_reg_rtx
!= sp_reg_rtx
16028 && ((info
->altivec_size
!= 0)
16029 || (info
->vrsave_mask
!= 0)
16031 if (frame_reg_rtx
!= sp_reg_rtx
)
16032 rs6000_emit_stack_tie ();
16035 /* Set frame pointer, if needed. */
16036 if (frame_pointer_needed
)
16038 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
16040 RTX_FRAME_RELATED_P (insn
) = 1;
16043 /* Save AltiVec registers if needed. Save here because the red zone does
16044 not include AltiVec registers. */
16045 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
16049 /* There should be a non inline version of this, for when we
16050 are saving lots of vector registers. */
16051 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
16052 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
16054 rtx areg
, savereg
, mem
;
16057 offset
= info
->altivec_save_offset
+ sp_offset
16058 + 16 * (i
- info
->first_altivec_reg_save
);
16060 savereg
= gen_rtx_REG (V4SImode
, i
);
16062 areg
= gen_rtx_REG (Pmode
, 0);
16063 emit_move_insn (areg
, GEN_INT (offset
));
16065 /* AltiVec addressing mode is [reg+reg]. */
16066 mem
= gen_frame_mem (V4SImode
,
16067 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
16069 insn
= emit_move_insn (mem
, savereg
);
16071 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
16072 areg
, GEN_INT (offset
));
16076 /* VRSAVE is a bit vector representing which AltiVec registers
16077 are used. The OS uses this to determine which vector
16078 registers to save on a context switch. We need to save
16079 VRSAVE on the stack frame, add whatever AltiVec registers we
16080 used in this function, and do the corresponding magic in the
16083 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
16084 && info
->vrsave_mask
!= 0)
16086 rtx reg
, mem
, vrsave
;
16089 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
16090 as frame_reg_rtx and r11 as the static chain pointer for
16091 nested functions. */
16092 reg
= gen_rtx_REG (SImode
, 0);
16093 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
16095 emit_insn (gen_get_vrsave_internal (reg
));
16097 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
16099 if (!WORLD_SAVE_P (info
))
16102 offset
= info
->vrsave_save_offset
+ sp_offset
;
16103 mem
= gen_frame_mem (SImode
,
16104 gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16105 GEN_INT (offset
)));
16106 insn
= emit_move_insn (mem
, reg
);
16109 /* Include the registers in the mask. */
16110 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
16112 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
16115 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
16116 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
16117 || (DEFAULT_ABI
== ABI_V4
16118 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
16119 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM
)))
16121 /* If emit_load_toc_table will use the link register, we need to save
16122 it. We use R12 for this purpose because emit_load_toc_table
16123 can use register 0. This allows us to use a plain 'blr' to return
16124 from the procedure more often. */
16125 int save_LR_around_toc_setup
= (TARGET_ELF
16126 && DEFAULT_ABI
!= ABI_AIX
16128 && ! info
->lr_save_p
16129 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
16130 if (save_LR_around_toc_setup
)
16132 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
16134 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
16135 RTX_FRAME_RELATED_P (insn
) = 1;
16137 rs6000_emit_load_toc_table (TRUE
);
16139 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
16140 RTX_FRAME_RELATED_P (insn
) = 1;
16143 rs6000_emit_load_toc_table (TRUE
);
16147 if (DEFAULT_ABI
== ABI_DARWIN
16148 && flag_pic
&& current_function_uses_pic_offset_table
)
16150 rtx lr
= gen_rtx_REG (Pmode
, LR_REGNO
);
16151 rtx src
= machopic_function_base_sym ();
16153 /* Save and restore LR locally around this call (in R0). */
16154 if (!info
->lr_save_p
)
16155 emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
);
16157 emit_insn (gen_load_macho_picbase (src
));
16159 emit_move_insn (gen_rtx_REG (Pmode
,
16160 RS6000_PIC_OFFSET_TABLE_REGNUM
),
16163 if (!info
->lr_save_p
)
16164 emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0));
16169 /* Write function prologue. */
16172 rs6000_output_function_prologue (FILE *file
,
16173 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
16175 rs6000_stack_t
*info
= rs6000_stack_info ();
16177 if (TARGET_DEBUG_STACK
)
16178 debug_stack_info (info
);
16180 /* Write .extern for any function we will call to save and restore
16182 if (info
->first_fp_reg_save
< 64
16183 && !FP_SAVE_INLINE (info
->first_fp_reg_save
))
16184 fprintf (file
, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
16185 SAVE_FP_PREFIX
, info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
,
16186 RESTORE_FP_PREFIX
, info
->first_fp_reg_save
- 32,
16187 RESTORE_FP_SUFFIX
);
16189 /* Write .extern for AIX common mode routines, if needed. */
16190 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
16192 fputs ("\t.extern __mulh\n", file
);
16193 fputs ("\t.extern __mull\n", file
);
16194 fputs ("\t.extern __divss\n", file
);
16195 fputs ("\t.extern __divus\n", file
);
16196 fputs ("\t.extern __quoss\n", file
);
16197 fputs ("\t.extern __quous\n", file
);
16198 common_mode_defined
= 1;
16201 if (! HAVE_prologue
)
16205 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
16206 the "toplevel" insn chain. */
16207 emit_note (NOTE_INSN_DELETED
);
16208 rs6000_emit_prologue ();
16209 emit_note (NOTE_INSN_DELETED
);
16211 /* Expand INSN_ADDRESSES so final() doesn't crash. */
16215 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
16217 INSN_ADDRESSES_NEW (insn
, addr
);
16222 if (TARGET_DEBUG_STACK
)
16223 debug_rtx_list (get_insns (), 100);
16224 final (get_insns (), file
, FALSE
);
16228 rs6000_pic_labelno
++;
16231 /* Emit function epilogue as insns.
16233 At present, dwarf2out_frame_debug_expr doesn't understand
16234 register restores, so we don't bother setting RTX_FRAME_RELATED_P
16235 anywhere in the epilogue. Most of the insns below would in any case
16236 need special notes to explain where r11 is in relation to the stack. */
16239 rs6000_emit_epilogue (int sibcall
)
16241 rs6000_stack_t
*info
;
16242 int restoring_FPRs_inline
;
16243 int using_load_multiple
;
16244 int using_mtcr_multiple
;
16245 int use_backchain_to_restore_sp
;
16247 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
16248 rtx frame_reg_rtx
= sp_reg_rtx
;
16249 enum machine_mode reg_mode
= Pmode
;
16250 int reg_size
= TARGET_32BIT
? 4 : 8;
16253 info
= rs6000_stack_info ();
16255 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
16257 reg_mode
= V2SImode
;
16261 using_load_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
16262 && (!TARGET_SPE_ABI
16263 || info
->spe_64bit_regs_used
== 0)
16264 && info
->first_gp_reg_save
< 31
16265 && no_global_regs_above (info
->first_gp_reg_save
));
16266 restoring_FPRs_inline
= (sibcall
16267 || current_function_calls_eh_return
16268 || info
->first_fp_reg_save
== 64
16269 || FP_SAVE_INLINE (info
->first_fp_reg_save
));
16270 use_backchain_to_restore_sp
= (frame_pointer_needed
16271 || current_function_calls_alloca
16272 || info
->total_size
> 32767);
16273 using_mtcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
16274 || rs6000_cpu
== PROCESSOR_PPC603
16275 || rs6000_cpu
== PROCESSOR_PPC750
16278 if (WORLD_SAVE_P (info
))
16282 const char *alloc_rname
;
16285 /* eh_rest_world_r10 will return to the location saved in the LR
16286 stack slot (which is not likely to be our caller.)
16287 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
16288 rest_world is similar, except any R10 parameter is ignored.
16289 The exception-handling stuff that was here in 2.95 is no
16290 longer necessary. */
16294 + 32 - info
->first_gp_reg_save
16295 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
16296 + 63 + 1 - info
->first_fp_reg_save
);
16298 strcpy (rname
, ((current_function_calls_eh_return
) ?
16299 "*eh_rest_world_r10" : "*rest_world"));
16300 alloc_rname
= ggc_strdup (rname
);
16303 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
16304 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
16305 gen_rtx_REG (Pmode
,
16308 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
16309 /* The instruction pattern requires a clobber here;
16310 it is shared with the restVEC helper. */
16312 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
16315 /* CR register traditionally saved as CR2. */
16316 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
16317 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16318 GEN_INT (info
->cr_save_offset
));
16319 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16321 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16324 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16326 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
16327 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16328 GEN_INT (info
->gp_save_offset
16330 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16332 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16334 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
16336 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
16337 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16338 GEN_INT (info
->altivec_save_offset
16340 rtx mem
= gen_frame_mem (V4SImode
, addr
);
16342 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16344 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
16346 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
16347 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16348 GEN_INT (info
->fp_save_offset
16350 rtx mem
= gen_frame_mem (DFmode
, addr
);
16352 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
16355 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
16357 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
16359 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
16361 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
16363 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
16364 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16369 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
16371 sp_offset
= info
->total_size
;
16373 /* Restore AltiVec registers if we must do so before adjusting the
16375 if (TARGET_ALTIVEC_ABI
16376 && info
->altivec_size
!= 0
16377 && DEFAULT_ABI
!= ABI_V4
16378 && info
->altivec_save_offset
< (TARGET_32BIT
? -220 : -288))
16382 if (use_backchain_to_restore_sp
)
16384 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
16385 emit_move_insn (frame_reg_rtx
,
16386 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
16390 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
16391 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
16393 rtx addr
, areg
, mem
;
16395 areg
= gen_rtx_REG (Pmode
, 0);
16397 (areg
, GEN_INT (info
->altivec_save_offset
16399 + 16 * (i
- info
->first_altivec_reg_save
)));
16401 /* AltiVec addressing mode is [reg+reg]. */
16402 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
16403 mem
= gen_frame_mem (V4SImode
, addr
);
16405 emit_move_insn (gen_rtx_REG (V4SImode
, i
), mem
);
16409 /* Restore VRSAVE if we must do so before adjusting the stack. */
16411 && TARGET_ALTIVEC_VRSAVE
16412 && info
->vrsave_mask
!= 0
16413 && DEFAULT_ABI
!= ABI_V4
16414 && info
->vrsave_save_offset
< (TARGET_32BIT
? -220 : -288))
16416 rtx addr
, mem
, reg
;
16418 if (use_backchain_to_restore_sp
16419 && frame_reg_rtx
== sp_reg_rtx
)
16421 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
16422 emit_move_insn (frame_reg_rtx
,
16423 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
16427 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16428 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
16429 mem
= gen_frame_mem (SImode
, addr
);
16430 reg
= gen_rtx_REG (SImode
, 12);
16431 emit_move_insn (reg
, mem
);
16433 emit_insn (generate_set_vrsave (reg
, info
, 1));
16436 /* If we have a frame pointer, a call to alloca, or a large stack
16437 frame, restore the old stack pointer using the backchain. Otherwise,
16438 we know what size to update it with. */
16439 if (use_backchain_to_restore_sp
)
16441 if (frame_reg_rtx
!= sp_reg_rtx
)
16443 emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
16444 frame_reg_rtx
= sp_reg_rtx
;
16448 /* Under V.4, don't reset the stack pointer until after we're done
16449 loading the saved registers. */
16450 if (DEFAULT_ABI
== ABI_V4
)
16451 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
16453 emit_move_insn (frame_reg_rtx
,
16454 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
16458 else if (info
->push_p
16459 && DEFAULT_ABI
!= ABI_V4
16460 && !current_function_calls_eh_return
)
16462 emit_insn (TARGET_32BIT
16463 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
16464 GEN_INT (info
->total_size
))
16465 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
16466 GEN_INT (info
->total_size
)));
16470 /* Restore AltiVec registers if we have not done so already. */
16471 if (TARGET_ALTIVEC_ABI
16472 && info
->altivec_size
!= 0
16473 && (DEFAULT_ABI
== ABI_V4
16474 || info
->altivec_save_offset
>= (TARGET_32BIT
? -220 : -288)))
16478 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
16479 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
16481 rtx addr
, areg
, mem
;
16483 areg
= gen_rtx_REG (Pmode
, 0);
16485 (areg
, GEN_INT (info
->altivec_save_offset
16487 + 16 * (i
- info
->first_altivec_reg_save
)));
16489 /* AltiVec addressing mode is [reg+reg]. */
16490 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
16491 mem
= gen_frame_mem (V4SImode
, addr
);
16493 emit_move_insn (gen_rtx_REG (V4SImode
, i
), mem
);
16497 /* Restore VRSAVE if we have not done so already. */
16499 && TARGET_ALTIVEC_VRSAVE
16500 && info
->vrsave_mask
!= 0
16501 && (DEFAULT_ABI
== ABI_V4
16502 || info
->vrsave_save_offset
>= (TARGET_32BIT
? -220 : -288)))
16504 rtx addr
, mem
, reg
;
16506 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16507 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
16508 mem
= gen_frame_mem (SImode
, addr
);
16509 reg
= gen_rtx_REG (SImode
, 12);
16510 emit_move_insn (reg
, mem
);
16512 emit_insn (generate_set_vrsave (reg
, info
, 1));
16515 /* Get the old lr if we saved it. */
16516 if (info
->lr_save_p
)
16518 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
16519 info
->lr_save_offset
+ sp_offset
);
16521 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
16524 /* Get the old cr if we saved it. */
16525 if (info
->cr_save_p
)
16527 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16528 GEN_INT (info
->cr_save_offset
+ sp_offset
));
16529 rtx mem
= gen_frame_mem (SImode
, addr
);
16531 emit_move_insn (gen_rtx_REG (SImode
, 12), mem
);
16534 /* Set LR here to try to overlap restores below. */
16535 if (info
->lr_save_p
)
16536 emit_move_insn (gen_rtx_REG (Pmode
, LR_REGNO
),
16537 gen_rtx_REG (Pmode
, 0));
16539 /* Load exception handler data registers, if needed. */
16540 if (current_function_calls_eh_return
)
16542 unsigned int i
, regno
;
16546 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16547 GEN_INT (sp_offset
+ 5 * reg_size
));
16548 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16550 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
16557 regno
= EH_RETURN_DATA_REGNO (i
);
16558 if (regno
== INVALID_REGNUM
)
16561 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
16562 info
->ehrd_offset
+ sp_offset
16563 + reg_size
* (int) i
);
16565 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
16569 /* Restore GPRs. This is done as a PARALLEL if we are using
16570 the load-multiple instructions. */
16571 if (using_load_multiple
)
16574 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
16575 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16577 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16578 GEN_INT (info
->gp_save_offset
16581 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16584 gen_rtx_SET (VOIDmode
,
16585 gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
),
16588 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16590 else if (TARGET_SPE_ABI
16591 && info
->spe_64bit_regs_used
!= 0
16592 && info
->first_gp_reg_save
!= 32)
16594 /* Determine whether we can address all of the registers that need
16595 to be saved with an offset from the stack pointer that fits in
16596 the small const field for SPE memory instructions. */
16597 int spe_regs_addressable_via_sp
16598 = SPE_CONST_OFFSET_OK(info
->spe_gp_save_offset
+ sp_offset
16599 + (32 - info
->first_gp_reg_save
- 1) * reg_size
);
16602 if (spe_regs_addressable_via_sp
)
16603 spe_offset
= info
->spe_gp_save_offset
+ sp_offset
;
16606 rtx old_frame_reg_rtx
= frame_reg_rtx
;
16607 /* Make r11 point to the start of the SPE save area. We worried about
16608 not clobbering it when we were saving registers in the prologue.
16609 There's no need to worry here because the static chain is passed
16610 anew to every function. */
16611 if (frame_reg_rtx
== sp_reg_rtx
)
16612 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
16613 emit_insn (gen_addsi3 (frame_reg_rtx
, old_frame_reg_rtx
,
16614 GEN_INT (info
->spe_gp_save_offset
+ sp_offset
)));
16615 /* Keep the invariant that frame_reg_rtx + sp_offset points
16616 at the top of the stack frame. */
16617 sp_offset
= -info
->spe_gp_save_offset
;
16622 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16623 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
16625 rtx offset
, addr
, mem
;
16627 /* We're doing all this to ensure that the immediate offset
16628 fits into the immediate field of 'evldd'. */
16629 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset
+ reg_size
* i
));
16631 offset
= GEN_INT (spe_offset
+ reg_size
* i
);
16632 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, offset
);
16633 mem
= gen_rtx_MEM (V2SImode
, addr
);
16635 emit_move_insn (gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
),
16640 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
16641 if (rs6000_reg_live_or_pic_offset_p (info
->first_gp_reg_save
+ i
))
16643 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16644 GEN_INT (info
->gp_save_offset
16647 rtx mem
= gen_frame_mem (reg_mode
, addr
);
16649 emit_move_insn (gen_rtx_REG (reg_mode
,
16650 info
->first_gp_reg_save
+ i
), mem
);
16653 /* Restore fpr's if we need to do it without calling a function. */
16654 if (restoring_FPRs_inline
)
16655 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
16656 if ((df_regs_ever_live_p (info
->first_fp_reg_save
+i
)
16657 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
16660 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
16661 GEN_INT (info
->fp_save_offset
16664 mem
= gen_frame_mem (DFmode
, addr
);
16666 emit_move_insn (gen_rtx_REG (DFmode
,
16667 info
->first_fp_reg_save
+ i
),
16671 /* If we saved cr, restore it here. Just those that were used. */
16672 if (info
->cr_save_p
)
16674 rtx r12_rtx
= gen_rtx_REG (SImode
, 12);
16677 if (using_mtcr_multiple
)
16679 for (i
= 0; i
< 8; i
++)
16680 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
16682 gcc_assert (count
);
16685 if (using_mtcr_multiple
&& count
> 1)
16690 p
= rtvec_alloc (count
);
16693 for (i
= 0; i
< 8; i
++)
16694 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
16696 rtvec r
= rtvec_alloc (2);
16697 RTVEC_ELT (r
, 0) = r12_rtx
;
16698 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
16699 RTVEC_ELT (p
, ndx
) =
16700 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
16701 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
16704 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16705 gcc_assert (ndx
== count
);
16708 for (i
= 0; i
< 8; i
++)
16709 if (df_regs_ever_live_p (CR0_REGNO
+i
) && ! call_used_regs
[CR0_REGNO
+i
])
16711 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
16717 /* If this is V.4, unwind the stack pointer after all of the loads
16719 if (frame_reg_rtx
!= sp_reg_rtx
)
16721 /* This blockage is needed so that sched doesn't decide to move
16722 the sp change before the register restores. */
16723 rs6000_emit_stack_tie ();
16724 if (sp_offset
!= 0)
16725 emit_insn (gen_addsi3 (sp_reg_rtx
, frame_reg_rtx
,
16726 GEN_INT (sp_offset
)));
16728 emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
16730 else if (sp_offset
!= 0)
16731 emit_insn (TARGET_32BIT
16732 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
16733 GEN_INT (sp_offset
))
16734 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
16735 GEN_INT (sp_offset
)));
16737 if (current_function_calls_eh_return
)
16739 rtx sa
= EH_RETURN_STACKADJ_RTX
;
16740 emit_insn (TARGET_32BIT
16741 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
, sa
)
16742 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
, sa
));
16748 if (! restoring_FPRs_inline
)
16749 p
= rtvec_alloc (3 + 64 - info
->first_fp_reg_save
);
16751 p
= rtvec_alloc (2);
16753 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
16754 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
16755 gen_rtx_REG (Pmode
,
16758 /* If we have to restore more than two FP registers, branch to the
16759 restore function. It will return to our caller. */
16760 if (! restoring_FPRs_inline
)
16764 const char *alloc_rname
;
16766 sprintf (rname
, "%s%d%s", RESTORE_FP_PREFIX
,
16767 info
->first_fp_reg_save
- 32, RESTORE_FP_SUFFIX
);
16768 alloc_rname
= ggc_strdup (rname
);
16769 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
,
16770 gen_rtx_SYMBOL_REF (Pmode
,
16773 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
16776 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
16777 GEN_INT (info
->fp_save_offset
+ 8*i
));
16778 mem
= gen_frame_mem (DFmode
, addr
);
16780 RTVEC_ELT (p
, i
+3) =
16781 gen_rtx_SET (VOIDmode
,
16782 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
16787 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
16791 /* Write function epilogue. */
16794 rs6000_output_function_epilogue (FILE *file
,
16795 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
16797 if (! HAVE_epilogue
)
16799 rtx insn
= get_last_insn ();
16800 /* If the last insn was a BARRIER, we don't have to write anything except
16801 the trace table. */
16802 if (GET_CODE (insn
) == NOTE
)
16803 insn
= prev_nonnote_insn (insn
);
16804 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
16806 /* This is slightly ugly, but at least we don't have two
16807 copies of the epilogue-emitting code. */
16810 /* A NOTE_INSN_DELETED is supposed to be at the start
16811 and end of the "toplevel" insn chain. */
16812 emit_note (NOTE_INSN_DELETED
);
16813 rs6000_emit_epilogue (FALSE
);
16814 emit_note (NOTE_INSN_DELETED
);
16816 /* Expand INSN_ADDRESSES so final() doesn't crash. */
16820 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
16822 INSN_ADDRESSES_NEW (insn
, addr
);
16827 if (TARGET_DEBUG_STACK
)
16828 debug_rtx_list (get_insns (), 100);
16829 final (get_insns (), file
, FALSE
);
16835 macho_branch_islands ();
16836 /* Mach-O doesn't support labels at the end of objects, so if
16837 it looks like we might want one, insert a NOP. */
16839 rtx insn
= get_last_insn ();
16842 && NOTE_KIND (insn
) != NOTE_INSN_DELETED_LABEL
)
16843 insn
= PREV_INSN (insn
);
16847 && NOTE_KIND (insn
) == NOTE_INSN_DELETED_LABEL
)))
16848 fputs ("\tnop\n", file
);
16852 /* Output a traceback table here. See /usr/include/sys/debug.h for info
16855 We don't output a traceback table if -finhibit-size-directive was
16856 used. The documentation for -finhibit-size-directive reads
16857 ``don't output a @code{.size} assembler directive, or anything
16858 else that would cause trouble if the function is split in the
16859 middle, and the two halves are placed at locations far apart in
16860 memory.'' The traceback table has this property, since it
16861 includes the offset from the start of the function to the
16862 traceback table itself.
16864 System V.4 Powerpc's (and the embedded ABI derived from it) use a
16865 different traceback table. */
16866 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
16867 && rs6000_traceback
!= traceback_none
&& !current_function_is_thunk
)
16869 const char *fname
= NULL
;
16870 const char *language_string
= lang_hooks
.name
;
16871 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
16873 int optional_tbtab
;
16874 rs6000_stack_t
*info
= rs6000_stack_info ();
16876 if (rs6000_traceback
== traceback_full
)
16877 optional_tbtab
= 1;
16878 else if (rs6000_traceback
== traceback_part
)
16879 optional_tbtab
= 0;
16881 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
16883 if (optional_tbtab
)
16885 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
16886 while (*fname
== '.') /* V.4 encodes . in the name */
16889 /* Need label immediately before tbtab, so we can compute
16890 its offset from the function start. */
16891 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
16892 ASM_OUTPUT_LABEL (file
, fname
);
16895 /* The .tbtab pseudo-op can only be used for the first eight
16896 expressions, since it can't handle the possibly variable
16897 length fields that follow. However, if you omit the optional
16898 fields, the assembler outputs zeros for all optional fields
16899 anyways, giving each variable length field is minimum length
16900 (as defined in sys/debug.h). Thus we can not use the .tbtab
16901 pseudo-op at all. */
16903 /* An all-zero word flags the start of the tbtab, for debuggers
16904 that have to find it by searching forward from the entry
16905 point or from the current pc. */
16906 fputs ("\t.long 0\n", file
);
16908 /* Tbtab format type. Use format type 0. */
16909 fputs ("\t.byte 0,", file
);
16911 /* Language type. Unfortunately, there does not seem to be any
16912 official way to discover the language being compiled, so we
16913 use language_string.
16914 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
16915 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
16916 a number, so for now use 9. */
16917 if (! strcmp (language_string
, "GNU C"))
16919 else if (! strcmp (language_string
, "GNU F77")
16920 || ! strcmp (language_string
, "GNU Fortran"))
16922 else if (! strcmp (language_string
, "GNU Pascal"))
16924 else if (! strcmp (language_string
, "GNU Ada"))
16926 else if (! strcmp (language_string
, "GNU C++")
16927 || ! strcmp (language_string
, "GNU Objective-C++"))
16929 else if (! strcmp (language_string
, "GNU Java"))
16931 else if (! strcmp (language_string
, "GNU Objective-C"))
16934 gcc_unreachable ();
16935 fprintf (file
, "%d,", i
);
16937 /* 8 single bit fields: global linkage (not set for C extern linkage,
16938 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
16939 from start of procedure stored in tbtab, internal function, function
16940 has controlled storage, function has no toc, function uses fp,
16941 function logs/aborts fp operations. */
16942 /* Assume that fp operations are used if any fp reg must be saved. */
16943 fprintf (file
, "%d,",
16944 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
16946 /* 6 bitfields: function is interrupt handler, name present in
16947 proc table, function calls alloca, on condition directives
16948 (controls stack walks, 3 bits), saves condition reg, saves
16950 /* The `function calls alloca' bit seems to be set whenever reg 31 is
16951 set up as a frame pointer, even when there is no alloca call. */
16952 fprintf (file
, "%d,",
16953 ((optional_tbtab
<< 6)
16954 | ((optional_tbtab
& frame_pointer_needed
) << 5)
16955 | (info
->cr_save_p
<< 1)
16956 | (info
->lr_save_p
)));
16958 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
16960 fprintf (file
, "%d,",
16961 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
16963 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
16964 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
16966 if (optional_tbtab
)
16968 /* Compute the parameter info from the function decl argument
16971 int next_parm_info_bit
= 31;
16973 for (decl
= DECL_ARGUMENTS (current_function_decl
);
16974 decl
; decl
= TREE_CHAIN (decl
))
16976 rtx parameter
= DECL_INCOMING_RTL (decl
);
16977 enum machine_mode mode
= GET_MODE (parameter
);
16979 if (GET_CODE (parameter
) == REG
)
16981 if (SCALAR_FLOAT_MODE_P (mode
))
17002 gcc_unreachable ();
17005 /* If only one bit will fit, don't or in this entry. */
17006 if (next_parm_info_bit
> 0)
17007 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
17008 next_parm_info_bit
-= 2;
17012 fixed_parms
+= ((GET_MODE_SIZE (mode
)
17013 + (UNITS_PER_WORD
- 1))
17015 next_parm_info_bit
-= 1;
17021 /* Number of fixed point parameters. */
17022 /* This is actually the number of words of fixed point parameters; thus
17023 an 8 byte struct counts as 2; and thus the maximum value is 8. */
17024 fprintf (file
, "%d,", fixed_parms
);
17026 /* 2 bitfields: number of floating point parameters (7 bits), parameters
17028 /* This is actually the number of fp registers that hold parameters;
17029 and thus the maximum value is 13. */
17030 /* Set parameters on stack bit if parameters are not in their original
17031 registers, regardless of whether they are on the stack? Xlc
17032 seems to set the bit when not optimizing. */
17033 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
17035 if (! optional_tbtab
)
17038 /* Optional fields follow. Some are variable length. */
17040 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
17041 11 double float. */
17042 /* There is an entry for each parameter in a register, in the order that
17043 they occur in the parameter list. Any intervening arguments on the
17044 stack are ignored. If the list overflows a long (max possible length
17045 34 bits) then completely leave off all elements that don't fit. */
17046 /* Only emit this long if there was at least one parameter. */
17047 if (fixed_parms
|| float_parms
)
17048 fprintf (file
, "\t.long %d\n", parm_info
);
17050 /* Offset from start of code to tb table. */
17051 fputs ("\t.long ", file
);
17052 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
17054 RS6000_OUTPUT_BASENAME (file
, fname
);
17056 assemble_name (file
, fname
);
17058 rs6000_output_function_entry (file
, fname
);
17061 /* Interrupt handler mask. */
17062 /* Omit this long, since we never set the interrupt handler bit
17065 /* Number of CTL (controlled storage) anchors. */
17066 /* Omit this long, since the has_ctl bit is never set above. */
17068 /* Displacement into stack of each CTL anchor. */
17069 /* Omit this list of longs, because there are no CTL anchors. */
17071 /* Length of function name. */
17074 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
17076 /* Function name. */
17077 assemble_string (fname
, strlen (fname
));
17079 /* Register for alloca automatic storage; this is always reg 31.
17080 Only emit this if the alloca bit was set above. */
17081 if (frame_pointer_needed
)
17082 fputs ("\t.byte 31\n", file
);
17084 fputs ("\t.align 2\n", file
);
17088 /* A C compound statement that outputs the assembler code for a thunk
17089 function, used to implement C++ virtual function calls with
17090 multiple inheritance. The thunk acts as a wrapper around a virtual
17091 function, adjusting the implicit object parameter before handing
17092 control off to the real function.
17094 First, emit code to add the integer DELTA to the location that
17095 contains the incoming first argument. Assume that this argument
17096 contains a pointer, and is the one used to pass the `this' pointer
17097 in C++. This is the incoming argument *before* the function
17098 prologue, e.g. `%o0' on a sparc. The addition must preserve the
17099 values of all other incoming arguments.
17101 After the addition, emit code to jump to FUNCTION, which is a
17102 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
17103 not touch the return address. Hence returning from FUNCTION will
17104 return to whoever called the current `thunk'.
17106 The effect must be as if FUNCTION had been called directly with the
17107 adjusted first argument. This macro is responsible for emitting
17108 all of the code for a thunk function; output_function_prologue()
17109 and output_function_epilogue() are not invoked.
17111 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
17112 been extracted from it.) It might possibly be useful on some
17113 targets, but probably not.
17115 If you do not define this macro, the target-independent code in the
17116 C++ frontend will generate a less efficient heavyweight thunk that
17117 calls FUNCTION instead of jumping to it. The generic approach does
17118 not support varargs. */
17121 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
17122 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
17125 rtx
this, insn
, funexp
;
17127 reload_completed
= 1;
17128 epilogue_completed
= 1;
17130 /* Mark the end of the (empty) prologue. */
17131 emit_note (NOTE_INSN_PROLOGUE_END
);
17133 /* Find the "this" pointer. If the function returns a structure,
17134 the structure return pointer is in r3. */
17135 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
17136 this = gen_rtx_REG (Pmode
, 4);
17138 this = gen_rtx_REG (Pmode
, 3);
17140 /* Apply the constant offset, if required. */
17143 rtx delta_rtx
= GEN_INT (delta
);
17144 emit_insn (TARGET_32BIT
17145 ? gen_addsi3 (this, this, delta_rtx
)
17146 : gen_adddi3 (this, this, delta_rtx
));
17149 /* Apply the offset from the vtable, if required. */
17152 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
17153 rtx tmp
= gen_rtx_REG (Pmode
, 12);
17155 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this));
17156 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
17158 emit_insn (TARGET_32BIT
17159 ? gen_addsi3 (tmp
, tmp
, vcall_offset_rtx
)
17160 : gen_adddi3 (tmp
, tmp
, vcall_offset_rtx
));
17161 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
17165 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
17167 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
17169 emit_insn (TARGET_32BIT
17170 ? gen_addsi3 (this, this, tmp
)
17171 : gen_adddi3 (this, this, tmp
));
17174 /* Generate a tail call to the target function. */
17175 if (!TREE_USED (function
))
17177 assemble_external (function
);
17178 TREE_USED (function
) = 1;
17180 funexp
= XEXP (DECL_RTL (function
), 0);
17181 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
17184 if (MACHOPIC_INDIRECT
)
17185 funexp
= machopic_indirect_call_target (funexp
);
17188 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
17189 generate sibcall RTL explicitly. */
17190 insn
= emit_call_insn (
17191 gen_rtx_PARALLEL (VOIDmode
,
17193 gen_rtx_CALL (VOIDmode
,
17194 funexp
, const0_rtx
),
17195 gen_rtx_USE (VOIDmode
, const0_rtx
),
17196 gen_rtx_USE (VOIDmode
,
17197 gen_rtx_REG (SImode
,
17199 gen_rtx_RETURN (VOIDmode
))));
17200 SIBLING_CALL_P (insn
) = 1;
17203 /* Run just enough of rest_of_compilation to get the insns emitted.
17204 There's not really enough bulk here to make other passes such as
17205 instruction scheduling worth while. Note that use_thunk calls
17206 assemble_start_function and assemble_end_function. */
17207 insn
= get_insns ();
17208 insn_locators_alloc ();
17209 shorten_branches (insn
);
17210 final_start_function (insn
, file
, 1);
17211 final (insn
, file
, 1);
17212 final_end_function ();
17213 free_after_compilation (cfun
);
17215 reload_completed
= 0;
17216 epilogue_completed
= 0;
17219 /* A quick summary of the various types of 'constant-pool tables'
17222 Target Flags Name One table per
17223 AIX (none) AIX TOC object file
17224 AIX -mfull-toc AIX TOC object file
17225 AIX -mminimal-toc AIX minimal TOC translation unit
17226 SVR4/EABI (none) SVR4 SDATA object file
17227 SVR4/EABI -fpic SVR4 pic object file
17228 SVR4/EABI -fPIC SVR4 PIC translation unit
17229 SVR4/EABI -mrelocatable EABI TOC function
17230 SVR4/EABI -maix AIX TOC object file
17231 SVR4/EABI -maix -mminimal-toc
17232 AIX minimal TOC translation unit
17234 Name Reg. Set by entries contains:
17235 made by addrs? fp? sum?
17237 AIX TOC 2 crt0 as Y option option
17238 AIX minimal TOC 30 prolog gcc Y Y option
17239 SVR4 SDATA 13 crt0 gcc N Y N
17240 SVR4 pic 30 prolog ld Y not yet N
17241 SVR4 PIC 30 prolog gcc Y option option
17242 EABI TOC 30 prolog gcc Y option option
17246 /* Hash functions for the hash table. */
17249 rs6000_hash_constant (rtx k
)
17251 enum rtx_code code
= GET_CODE (k
);
17252 enum machine_mode mode
= GET_MODE (k
);
17253 unsigned result
= (code
<< 3) ^ mode
;
17254 const char *format
;
17257 format
= GET_RTX_FORMAT (code
);
17258 flen
= strlen (format
);
17264 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
17267 if (mode
!= VOIDmode
)
17268 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
17280 for (; fidx
< flen
; fidx
++)
17281 switch (format
[fidx
])
17286 const char *str
= XSTR (k
, fidx
);
17287 len
= strlen (str
);
17288 result
= result
* 613 + len
;
17289 for (i
= 0; i
< len
; i
++)
17290 result
= result
* 613 + (unsigned) str
[i
];
17295 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
17299 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
17302 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
17303 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
17307 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
17308 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
17315 gcc_unreachable ();
17322 toc_hash_function (const void *hash_entry
)
17324 const struct toc_hash_struct
*thc
=
17325 (const struct toc_hash_struct
*) hash_entry
;
17326 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
17329 /* Compare H1 and H2 for equivalence. */
17332 toc_hash_eq (const void *h1
, const void *h2
)
17334 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
17335 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
17337 if (((const struct toc_hash_struct
*) h1
)->key_mode
17338 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
17341 return rtx_equal_p (r1
, r2
);
17344 /* These are the names given by the C++ front-end to vtables, and
17345 vtable-like objects. Ideally, this logic should not be here;
17346 instead, there should be some programmatic way of inquiring as
17347 to whether or not an object is a vtable. */
17349 #define VTABLE_NAME_P(NAME) \
17350 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
17351 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
17352 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
17353 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
17354 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
17357 rs6000_output_symbol_ref (FILE *file
, rtx x
)
17359 /* Currently C++ toc references to vtables can be emitted before it
17360 is decided whether the vtable is public or private. If this is
17361 the case, then the linker will eventually complain that there is
17362 a reference to an unknown section. Thus, for vtables only,
17363 we emit the TOC reference to reference the symbol and not the
17365 const char *name
= XSTR (x
, 0);
17367 if (VTABLE_NAME_P (name
))
17369 RS6000_OUTPUT_BASENAME (file
, name
);
17372 assemble_name (file
, name
);
17375 /* Output a TOC entry. We derive the entry name from what is being
17379 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
17382 const char *name
= buf
;
17383 const char *real_name
;
17385 HOST_WIDE_INT offset
= 0;
17387 gcc_assert (!TARGET_NO_TOC
);
17389 /* When the linker won't eliminate them, don't output duplicate
17390 TOC entries (this happens on AIX if there is any kind of TOC,
17391 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
17393 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
17395 struct toc_hash_struct
*h
;
17398 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
17399 time because GGC is not initialized at that point. */
17400 if (toc_hash_table
== NULL
)
17401 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
17402 toc_hash_eq
, NULL
);
17404 h
= ggc_alloc (sizeof (*h
));
17406 h
->key_mode
= mode
;
17407 h
->labelno
= labelno
;
17409 found
= htab_find_slot (toc_hash_table
, h
, 1);
17410 if (*found
== NULL
)
17412 else /* This is indeed a duplicate.
17413 Set this label equal to that label. */
17415 fputs ("\t.set ", file
);
17416 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
17417 fprintf (file
, "%d,", labelno
);
17418 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
17419 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
17425 /* If we're going to put a double constant in the TOC, make sure it's
17426 aligned properly when strict alignment is on. */
17427 if (GET_CODE (x
) == CONST_DOUBLE
17428 && STRICT_ALIGNMENT
17429 && GET_MODE_BITSIZE (mode
) >= 64
17430 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
17431 ASM_OUTPUT_ALIGN (file
, 3);
17434 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
17436 /* Handle FP constants specially. Note that if we have a minimal
17437 TOC, things we put here aren't actually in the TOC, so we can allow
17439 if (GET_CODE (x
) == CONST_DOUBLE
&&
17440 (GET_MODE (x
) == TFmode
|| GET_MODE (x
) == TDmode
))
17442 REAL_VALUE_TYPE rv
;
17445 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
17446 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
17447 REAL_VALUE_TO_TARGET_DECIMAL128 (rv
, k
);
17449 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
17453 if (TARGET_MINIMAL_TOC
)
17454 fputs (DOUBLE_INT_ASM_OP
, file
);
17456 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
17457 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
17458 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
17459 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
17460 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
17461 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
17466 if (TARGET_MINIMAL_TOC
)
17467 fputs ("\t.long ", file
);
17469 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
17470 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
17471 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
17472 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
17473 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
17474 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
17478 else if (GET_CODE (x
) == CONST_DOUBLE
&&
17479 (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DDmode
))
17481 REAL_VALUE_TYPE rv
;
17484 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
17486 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
17487 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, k
);
17489 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
17493 if (TARGET_MINIMAL_TOC
)
17494 fputs (DOUBLE_INT_ASM_OP
, file
);
17496 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
17497 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
17498 fprintf (file
, "0x%lx%08lx\n",
17499 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
17504 if (TARGET_MINIMAL_TOC
)
17505 fputs ("\t.long ", file
);
17507 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
17508 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
17509 fprintf (file
, "0x%lx,0x%lx\n",
17510 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
17514 else if (GET_CODE (x
) == CONST_DOUBLE
&&
17515 (GET_MODE (x
) == SFmode
|| GET_MODE (x
) == SDmode
))
17517 REAL_VALUE_TYPE rv
;
17520 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
17521 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
17522 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
17524 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
17528 if (TARGET_MINIMAL_TOC
)
17529 fputs (DOUBLE_INT_ASM_OP
, file
);
17531 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
17532 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
17537 if (TARGET_MINIMAL_TOC
)
17538 fputs ("\t.long ", file
);
17540 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
17541 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
17545 else if (GET_MODE (x
) == VOIDmode
17546 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
17548 unsigned HOST_WIDE_INT low
;
17549 HOST_WIDE_INT high
;
17551 if (GET_CODE (x
) == CONST_DOUBLE
)
17553 low
= CONST_DOUBLE_LOW (x
);
17554 high
= CONST_DOUBLE_HIGH (x
);
17557 #if HOST_BITS_PER_WIDE_INT == 32
17560 high
= (low
& 0x80000000) ? ~0 : 0;
17564 low
= INTVAL (x
) & 0xffffffff;
17565 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
17569 /* TOC entries are always Pmode-sized, but since this
17570 is a bigendian machine then if we're putting smaller
17571 integer constants in the TOC we have to pad them.
17572 (This is still a win over putting the constants in
17573 a separate constant pool, because then we'd have
17574 to have both a TOC entry _and_ the actual constant.)
17576 For a 32-bit target, CONST_INT values are loaded and shifted
17577 entirely within `low' and can be stored in one TOC entry. */
17579 /* It would be easy to make this work, but it doesn't now. */
17580 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
17582 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
17584 #if HOST_BITS_PER_WIDE_INT == 32
17585 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
17586 POINTER_SIZE
, &low
, &high
, 0);
17589 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
17590 high
= (HOST_WIDE_INT
) low
>> 32;
17597 if (TARGET_MINIMAL_TOC
)
17598 fputs (DOUBLE_INT_ASM_OP
, file
);
17600 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
17601 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
17602 fprintf (file
, "0x%lx%08lx\n",
17603 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
17608 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
17610 if (TARGET_MINIMAL_TOC
)
17611 fputs ("\t.long ", file
);
17613 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
17614 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
17615 fprintf (file
, "0x%lx,0x%lx\n",
17616 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
17620 if (TARGET_MINIMAL_TOC
)
17621 fputs ("\t.long ", file
);
17623 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
17624 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
17630 if (GET_CODE (x
) == CONST
)
17632 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
);
17634 base
= XEXP (XEXP (x
, 0), 0);
17635 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
17638 switch (GET_CODE (base
))
17641 name
= XSTR (base
, 0);
17645 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
17646 CODE_LABEL_NUMBER (XEXP (base
, 0)));
17650 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
17654 gcc_unreachable ();
17657 real_name
= (*targetm
.strip_name_encoding
) (name
);
17658 if (TARGET_MINIMAL_TOC
)
17659 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
17662 fprintf (file
, "\t.tc %s", real_name
);
17665 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
17667 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
17669 fputs ("[TC],", file
);
17672 /* Currently C++ toc references to vtables can be emitted before it
17673 is decided whether the vtable is public or private. If this is
17674 the case, then the linker will eventually complain that there is
17675 a TOC reference to an unknown section. Thus, for vtables only,
17676 we emit the TOC reference to reference the symbol and not the
17678 if (VTABLE_NAME_P (name
))
17680 RS6000_OUTPUT_BASENAME (file
, name
);
17682 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
17683 else if (offset
> 0)
17684 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
17687 output_addr_const (file
, x
);
17691 /* Output an assembler pseudo-op to write an ASCII string of N characters
17692 starting at P to FILE.
17694 On the RS/6000, we have to do this using the .byte operation and
17695 write out special characters outside the quoted string.
17696 Also, the assembler is broken; very long strings are truncated,
17697 so we must artificially break them up early. */
17700 output_ascii (FILE *file
, const char *p
, int n
)
17703 int i
, count_string
;
17704 const char *for_string
= "\t.byte \"";
17705 const char *for_decimal
= "\t.byte ";
17706 const char *to_close
= NULL
;
17709 for (i
= 0; i
< n
; i
++)
17712 if (c
>= ' ' && c
< 0177)
17715 fputs (for_string
, file
);
17718 /* Write two quotes to get one. */
17726 for_decimal
= "\"\n\t.byte ";
17730 if (count_string
>= 512)
17732 fputs (to_close
, file
);
17734 for_string
= "\t.byte \"";
17735 for_decimal
= "\t.byte ";
17743 fputs (for_decimal
, file
);
17744 fprintf (file
, "%d", c
);
17746 for_string
= "\n\t.byte \"";
17747 for_decimal
= ", ";
17753 /* Now close the string if we have written one. Then end the line. */
17755 fputs (to_close
, file
);
17758 /* Generate a unique section name for FILENAME for a section type
17759 represented by SECTION_DESC. Output goes into BUF.
17761 SECTION_DESC can be any string, as long as it is different for each
17762 possible section type.
17764 We name the section in the same manner as xlc. The name begins with an
17765 underscore followed by the filename (after stripping any leading directory
17766 names) with the last period replaced by the string SECTION_DESC. If
17767 FILENAME does not contain a period, SECTION_DESC is appended to the end of
17771 rs6000_gen_section_name (char **buf
, const char *filename
,
17772 const char *section_desc
)
17774 const char *q
, *after_last_slash
, *last_period
= 0;
17778 after_last_slash
= filename
;
17779 for (q
= filename
; *q
; q
++)
17782 after_last_slash
= q
+ 1;
17783 else if (*q
== '.')
17787 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
17788 *buf
= (char *) xmalloc (len
);
17793 for (q
= after_last_slash
; *q
; q
++)
17795 if (q
== last_period
)
17797 strcpy (p
, section_desc
);
17798 p
+= strlen (section_desc
);
17802 else if (ISALNUM (*q
))
17806 if (last_period
== 0)
17807 strcpy (p
, section_desc
);
17812 /* Emit profile function. */
17815 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
17817 /* Non-standard profiling for kernels, which just saves LR then calls
17818 _mcount without worrying about arg saves. The idea is to change
17819 the function prologue as little as possible as it isn't easy to
17820 account for arg save/restore code added just for _mcount. */
17821 if (TARGET_PROFILE_KERNEL
)
17824 if (DEFAULT_ABI
== ABI_AIX
)
17826 #ifndef NO_PROFILE_COUNTERS
17827 # define NO_PROFILE_COUNTERS 0
17829 if (NO_PROFILE_COUNTERS
)
17830 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 0);
17834 const char *label_name
;
17837 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
17838 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
17839 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
17841 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 1,
17845 else if (DEFAULT_ABI
== ABI_DARWIN
)
17847 const char *mcount_name
= RS6000_MCOUNT
;
17848 int caller_addr_regno
= LR_REGNO
;
17850 /* Be conservative and always set this, at least for now. */
17851 current_function_uses_pic_offset_table
= 1;
17854 /* For PIC code, set up a stub and collect the caller's address
17855 from r0, which is where the prologue puts it. */
17856 if (MACHOPIC_INDIRECT
17857 && current_function_uses_pic_offset_table
)
17858 caller_addr_regno
= 0;
17860 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
17862 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
17866 /* Write function profiler code. */
17869 output_function_profiler (FILE *file
, int labelno
)
17873 switch (DEFAULT_ABI
)
17876 gcc_unreachable ();
17881 warning (0, "no profiling of 64-bit code for this ABI");
17884 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
17885 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
17886 if (NO_PROFILE_COUNTERS
)
17888 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
17889 reg_names
[0], reg_names
[1]);
17891 else if (TARGET_SECURE_PLT
&& flag_pic
)
17893 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
17894 reg_names
[0], reg_names
[1]);
17895 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
17896 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
17897 reg_names
[12], reg_names
[12]);
17898 assemble_name (file
, buf
);
17899 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
17900 assemble_name (file
, buf
);
17901 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
17903 else if (flag_pic
== 1)
17905 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
17906 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
17907 reg_names
[0], reg_names
[1]);
17908 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
17909 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
17910 assemble_name (file
, buf
);
17911 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
17913 else if (flag_pic
> 1)
17915 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
17916 reg_names
[0], reg_names
[1]);
17917 /* Now, we need to get the address of the label. */
17918 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
17919 assemble_name (file
, buf
);
17920 fputs ("-.\n1:", file
);
17921 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
17922 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
17923 reg_names
[0], reg_names
[11]);
17924 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
17925 reg_names
[0], reg_names
[0], reg_names
[11]);
17929 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
17930 assemble_name (file
, buf
);
17931 fputs ("@ha\n", file
);
17932 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
17933 reg_names
[0], reg_names
[1]);
17934 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
17935 assemble_name (file
, buf
);
17936 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
17939 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
17940 fprintf (file
, "\tbl %s%s\n",
17941 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
17946 if (!TARGET_PROFILE_KERNEL
)
17948 /* Don't do anything, done in output_profile_hook (). */
17952 gcc_assert (!TARGET_32BIT
);
17954 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
17955 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
17957 if (cfun
->static_chain_decl
!= NULL
)
17959 asm_fprintf (file
, "\tstd %s,24(%s)\n",
17960 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
17961 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
17962 asm_fprintf (file
, "\tld %s,24(%s)\n",
17963 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
17966 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
17974 /* The following variable value is the last issued insn. */
17976 static rtx last_scheduled_insn
;
17978 /* The following variable helps to balance issuing of load and
17979 store instructions */
17981 static int load_store_pendulum
;
17983 /* Power4 load update and store update instructions are cracked into a
17984 load or store and an integer insn which are executed in the same cycle.
17985 Branches have their own dispatch slot which does not count against the
17986 GCC issue rate, but it changes the program flow so there are no other
17987 instructions to issue in this cycle. */
17990 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED
,
17991 int verbose ATTRIBUTE_UNUSED
,
17992 rtx insn
, int more
)
17994 last_scheduled_insn
= insn
;
17995 if (GET_CODE (PATTERN (insn
)) == USE
17996 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
17998 cached_can_issue_more
= more
;
17999 return cached_can_issue_more
;
18002 if (insn_terminates_group_p (insn
, current_group
))
18004 cached_can_issue_more
= 0;
18005 return cached_can_issue_more
;
18008 /* If no reservation, but reach here */
18009 if (recog_memoized (insn
) < 0)
18012 if (rs6000_sched_groups
)
18014 if (is_microcoded_insn (insn
))
18015 cached_can_issue_more
= 0;
18016 else if (is_cracked_insn (insn
))
18017 cached_can_issue_more
= more
> 2 ? more
- 2 : 0;
18019 cached_can_issue_more
= more
- 1;
18021 return cached_can_issue_more
;
18024 if (rs6000_cpu_attr
== CPU_CELL
&& is_nonpipeline_insn (insn
))
18027 cached_can_issue_more
= more
- 1;
18028 return cached_can_issue_more
;
18031 /* Adjust the cost of a scheduling dependency. Return the new cost of
18032 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
18035 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
18037 enum attr_type attr_type
;
18039 if (! recog_memoized (insn
))
18042 switch (REG_NOTE_KIND (link
))
18046 /* Data dependency; DEP_INSN writes a register that INSN reads
18047 some cycles later. */
18049 /* Separate a load from a narrower, dependent store. */
18050 if (rs6000_sched_groups
18051 && GET_CODE (PATTERN (insn
)) == SET
18052 && GET_CODE (PATTERN (dep_insn
)) == SET
18053 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
18054 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
18055 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
18056 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
18059 attr_type
= get_attr_type (insn
);
18064 /* Tell the first scheduling pass about the latency between
18065 a mtctr and bctr (and mtlr and br/blr). The first
18066 scheduling pass will not know about this latency since
18067 the mtctr instruction, which has the latency associated
18068 to it, will be generated by reload. */
18069 return TARGET_POWER
? 5 : 4;
18071 /* Leave some extra cycles between a compare and its
18072 dependent branch, to inhibit expensive mispredicts. */
18073 if ((rs6000_cpu_attr
== CPU_PPC603
18074 || rs6000_cpu_attr
== CPU_PPC604
18075 || rs6000_cpu_attr
== CPU_PPC604E
18076 || rs6000_cpu_attr
== CPU_PPC620
18077 || rs6000_cpu_attr
== CPU_PPC630
18078 || rs6000_cpu_attr
== CPU_PPC750
18079 || rs6000_cpu_attr
== CPU_PPC7400
18080 || rs6000_cpu_attr
== CPU_PPC7450
18081 || rs6000_cpu_attr
== CPU_POWER4
18082 || rs6000_cpu_attr
== CPU_POWER5
18083 || rs6000_cpu_attr
== CPU_CELL
)
18084 && recog_memoized (dep_insn
)
18085 && (INSN_CODE (dep_insn
) >= 0))
18087 switch (get_attr_type (dep_insn
))
18091 case TYPE_DELAYED_COMPARE
:
18092 case TYPE_IMUL_COMPARE
:
18093 case TYPE_LMUL_COMPARE
:
18094 case TYPE_FPCOMPARE
:
18095 case TYPE_CR_LOGICAL
:
18096 case TYPE_DELAYED_CR
:
18105 case TYPE_STORE_UX
:
18107 case TYPE_FPSTORE_U
:
18108 case TYPE_FPSTORE_UX
:
18109 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18110 && recog_memoized (dep_insn
)
18111 && (INSN_CODE (dep_insn
) >= 0))
18114 if (GET_CODE (PATTERN (insn
)) != SET
)
18115 /* If this happens, we have to extend this to schedule
18116 optimally. Return default for now. */
18119 /* Adjust the cost for the case where the value written
18120 by a fixed point operation is used as the address
18121 gen value on a store. */
18122 switch (get_attr_type (dep_insn
))
18129 if (! store_data_bypass_p (dep_insn
, insn
))
18133 case TYPE_LOAD_EXT
:
18134 case TYPE_LOAD_EXT_U
:
18135 case TYPE_LOAD_EXT_UX
:
18136 case TYPE_VAR_SHIFT_ROTATE
:
18137 case TYPE_VAR_DELAYED_COMPARE
:
18139 if (! store_data_bypass_p (dep_insn
, insn
))
18145 case TYPE_FAST_COMPARE
:
18148 case TYPE_INSERT_WORD
:
18149 case TYPE_INSERT_DWORD
:
18150 case TYPE_FPLOAD_U
:
18151 case TYPE_FPLOAD_UX
:
18153 case TYPE_STORE_UX
:
18154 case TYPE_FPSTORE_U
:
18155 case TYPE_FPSTORE_UX
:
18157 if (! store_data_bypass_p (dep_insn
, insn
))
18165 case TYPE_IMUL_COMPARE
:
18166 case TYPE_LMUL_COMPARE
:
18168 if (! store_data_bypass_p (dep_insn
, insn
))
18174 if (! store_data_bypass_p (dep_insn
, insn
))
18180 if (! store_data_bypass_p (dep_insn
, insn
))
18193 case TYPE_LOAD_EXT
:
18194 case TYPE_LOAD_EXT_U
:
18195 case TYPE_LOAD_EXT_UX
:
18196 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18197 && recog_memoized (dep_insn
)
18198 && (INSN_CODE (dep_insn
) >= 0))
18201 /* Adjust the cost for the case where the value written
18202 by a fixed point instruction is used within the address
18203 gen portion of a subsequent load(u)(x) */
18204 switch (get_attr_type (dep_insn
))
18211 if (set_to_load_agen (dep_insn
, insn
))
18215 case TYPE_LOAD_EXT
:
18216 case TYPE_LOAD_EXT_U
:
18217 case TYPE_LOAD_EXT_UX
:
18218 case TYPE_VAR_SHIFT_ROTATE
:
18219 case TYPE_VAR_DELAYED_COMPARE
:
18221 if (set_to_load_agen (dep_insn
, insn
))
18227 case TYPE_FAST_COMPARE
:
18230 case TYPE_INSERT_WORD
:
18231 case TYPE_INSERT_DWORD
:
18232 case TYPE_FPLOAD_U
:
18233 case TYPE_FPLOAD_UX
:
18235 case TYPE_STORE_UX
:
18236 case TYPE_FPSTORE_U
:
18237 case TYPE_FPSTORE_UX
:
18239 if (set_to_load_agen (dep_insn
, insn
))
18247 case TYPE_IMUL_COMPARE
:
18248 case TYPE_LMUL_COMPARE
:
18250 if (set_to_load_agen (dep_insn
, insn
))
18256 if (set_to_load_agen (dep_insn
, insn
))
18262 if (set_to_load_agen (dep_insn
, insn
))
18273 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18274 && recog_memoized (dep_insn
)
18275 && (INSN_CODE (dep_insn
) >= 0)
18276 && (get_attr_type (dep_insn
) == TYPE_MFFGPR
))
18283 /* Fall out to return default cost. */
18287 case REG_DEP_OUTPUT
:
18288 /* Output dependency; DEP_INSN writes a register that INSN writes some
18290 if ((rs6000_cpu
== PROCESSOR_POWER6
)
18291 && recog_memoized (dep_insn
)
18292 && (INSN_CODE (dep_insn
) >= 0))
18294 attr_type
= get_attr_type (insn
);
18299 if (get_attr_type (dep_insn
) == TYPE_FP
)
18303 if (get_attr_type (dep_insn
) == TYPE_MFFGPR
)
18311 /* Anti dependency; DEP_INSN reads a register that INSN writes some
18316 gcc_unreachable ();
18322 /* The function returns a true if INSN is microcoded.
18323 Return false otherwise. */
18326 is_microcoded_insn (rtx insn
)
18328 if (!insn
|| !INSN_P (insn
)
18329 || GET_CODE (PATTERN (insn
)) == USE
18330 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18333 if (rs6000_cpu_attr
== CPU_CELL
)
18334 return get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
;
18336 if (rs6000_sched_groups
)
18338 enum attr_type type
= get_attr_type (insn
);
18339 if (type
== TYPE_LOAD_EXT_U
18340 || type
== TYPE_LOAD_EXT_UX
18341 || type
== TYPE_LOAD_UX
18342 || type
== TYPE_STORE_UX
18343 || type
== TYPE_MFCR
)
18350 /* The function returns true if INSN is cracked into 2 instructions
18351 by the processor (and therefore occupies 2 issue slots). */
18354 is_cracked_insn (rtx insn
)
18356 if (!insn
|| !INSN_P (insn
)
18357 || GET_CODE (PATTERN (insn
)) == USE
18358 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18361 if (rs6000_sched_groups
)
18363 enum attr_type type
= get_attr_type (insn
);
18364 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
18365 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
18366 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
18367 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
18368 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
18369 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
18370 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
18371 || type
== TYPE_INSERT_WORD
)
18378 /* The function returns true if INSN can be issued only from
18379 the branch slot. */
18382 is_branch_slot_insn (rtx insn
)
18384 if (!insn
|| !INSN_P (insn
)
18385 || GET_CODE (PATTERN (insn
)) == USE
18386 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18389 if (rs6000_sched_groups
)
18391 enum attr_type type
= get_attr_type (insn
);
18392 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
18400 /* The function returns true if out_inst sets a value that is
18401 used in the address generation computation of in_insn */
18403 set_to_load_agen (rtx out_insn
, rtx in_insn
)
18405 rtx out_set
, in_set
;
18407 /* For performance reasons, only handle the simple case where
18408 both loads are a single_set. */
18409 out_set
= single_set (out_insn
);
18412 in_set
= single_set (in_insn
);
18414 return reg_mentioned_p (SET_DEST (out_set
), SET_SRC (in_set
));
18420 /* The function returns true if the target storage location of
18421 out_insn is adjacent to the target storage location of in_insn */
18422 /* Return 1 if memory locations are adjacent. */
18425 adjacent_mem_locations (rtx insn1
, rtx insn2
)
18428 rtx a
= get_store_dest (PATTERN (insn1
));
18429 rtx b
= get_store_dest (PATTERN (insn2
));
18431 if ((GET_CODE (XEXP (a
, 0)) == REG
18432 || (GET_CODE (XEXP (a
, 0)) == PLUS
18433 && GET_CODE (XEXP (XEXP (a
, 0), 1)) == CONST_INT
))
18434 && (GET_CODE (XEXP (b
, 0)) == REG
18435 || (GET_CODE (XEXP (b
, 0)) == PLUS
18436 && GET_CODE (XEXP (XEXP (b
, 0), 1)) == CONST_INT
)))
18438 HOST_WIDE_INT val0
= 0, val1
= 0, val_diff
;
18441 if (GET_CODE (XEXP (a
, 0)) == PLUS
)
18443 reg0
= XEXP (XEXP (a
, 0), 0);
18444 val0
= INTVAL (XEXP (XEXP (a
, 0), 1));
18447 reg0
= XEXP (a
, 0);
18449 if (GET_CODE (XEXP (b
, 0)) == PLUS
)
18451 reg1
= XEXP (XEXP (b
, 0), 0);
18452 val1
= INTVAL (XEXP (XEXP (b
, 0), 1));
18455 reg1
= XEXP (b
, 0);
18457 val_diff
= val1
- val0
;
18459 return ((REGNO (reg0
) == REGNO (reg1
))
18460 && ((MEM_SIZE (a
) && val_diff
== INTVAL (MEM_SIZE (a
)))
18461 || (MEM_SIZE (b
) && val_diff
== -INTVAL (MEM_SIZE (b
)))));
18467 /* A C statement (sans semicolon) to update the integer scheduling
18468 priority INSN_PRIORITY (INSN). Increase the priority to execute the
18469 INSN earlier, reduce the priority to execute INSN later. Do not
18470 define this macro if you do not need to adjust the scheduling
18471 priorities of insns. */
18474 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
18476 /* On machines (like the 750) which have asymmetric integer units,
18477 where one integer unit can do multiply and divides and the other
18478 can't, reduce the priority of multiply/divide so it is scheduled
18479 before other integer operations. */
18482 if (! INSN_P (insn
))
18485 if (GET_CODE (PATTERN (insn
)) == USE
)
18488 switch (rs6000_cpu_attr
) {
18490 switch (get_attr_type (insn
))
18497 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
18498 priority
, priority
);
18499 if (priority
>= 0 && priority
< 0x01000000)
18506 if (insn_must_be_first_in_group (insn
)
18507 && reload_completed
18508 && current_sched_info
->sched_max_insns_priority
18509 && rs6000_sched_restricted_insns_priority
)
18512 /* Prioritize insns that can be dispatched only in the first
18514 if (rs6000_sched_restricted_insns_priority
== 1)
18515 /* Attach highest priority to insn. This means that in
18516 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
18517 precede 'priority' (critical path) considerations. */
18518 return current_sched_info
->sched_max_insns_priority
;
18519 else if (rs6000_sched_restricted_insns_priority
== 2)
18520 /* Increase priority of insn by a minimal amount. This means that in
18521 haifa-sched.c:ready_sort(), only 'priority' (critical path)
18522 considerations precede dispatch-slot restriction considerations. */
18523 return (priority
+ 1);
18526 if (rs6000_cpu
== PROCESSOR_POWER6
18527 && ((load_store_pendulum
== -2 && is_load_insn (insn
))
18528 || (load_store_pendulum
== 2 && is_store_insn (insn
))))
18529 /* Attach highest priority to insn if the scheduler has just issued two
18530 stores and this instruction is a load, or two loads and this instruction
18531 is a store. Power6 wants loads and stores scheduled alternately
18533 return current_sched_info
->sched_max_insns_priority
;
18538 /* Return true if the instruction is nonpipelined on the Cell. */
18540 is_nonpipeline_insn (rtx insn
)
18542 enum attr_type type
;
18543 if (!insn
|| !INSN_P (insn
)
18544 || GET_CODE (PATTERN (insn
)) == USE
18545 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18548 type
= get_attr_type (insn
);
18549 if (type
== TYPE_IMUL
18550 || type
== TYPE_IMUL2
18551 || type
== TYPE_IMUL3
18552 || type
== TYPE_LMUL
18553 || type
== TYPE_IDIV
18554 || type
== TYPE_LDIV
18555 || type
== TYPE_SDIV
18556 || type
== TYPE_DDIV
18557 || type
== TYPE_SSQRT
18558 || type
== TYPE_DSQRT
18559 || type
== TYPE_MFCR
18560 || type
== TYPE_MFCRF
18561 || type
== TYPE_MFJMPR
)
18569 /* Return how many instructions the machine can issue per cycle. */
18572 rs6000_issue_rate (void)
18574 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
18575 if (!reload_completed
)
18578 switch (rs6000_cpu_attr
) {
18579 case CPU_RIOS1
: /* ? */
18581 case CPU_PPC601
: /* ? */
18590 case CPU_PPCE300C2
:
18591 case CPU_PPCE300C3
:
18608 /* Return how many instructions to look ahead for better insn
18612 rs6000_use_sched_lookahead (void)
18614 if (rs6000_cpu_attr
== CPU_PPC8540
)
18616 if (rs6000_cpu_attr
== CPU_CELL
)
18617 return (reload_completed
? 8 : 0);
18621 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
18623 rs6000_use_sched_lookahead_guard (rtx insn
)
18625 if (rs6000_cpu_attr
!= CPU_CELL
)
18628 if (insn
== NULL_RTX
|| !INSN_P (insn
))
18631 if (!reload_completed
18632 || is_nonpipeline_insn (insn
)
18633 || is_microcoded_insn (insn
))
18639 /* Determine is PAT refers to memory. */
18642 is_mem_ref (rtx pat
)
18648 /* stack_tie does not produce any real memory traffic. */
18649 if (GET_CODE (pat
) == UNSPEC
18650 && XINT (pat
, 1) == UNSPEC_TIE
)
18653 if (GET_CODE (pat
) == MEM
)
18656 /* Recursively process the pattern. */
18657 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
18659 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
18662 ret
|= is_mem_ref (XEXP (pat
, i
));
18663 else if (fmt
[i
] == 'E')
18664 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
18665 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
18671 /* Determine if PAT is a PATTERN of a load insn. */
18674 is_load_insn1 (rtx pat
)
18676 if (!pat
|| pat
== NULL_RTX
)
18679 if (GET_CODE (pat
) == SET
)
18680 return is_mem_ref (SET_SRC (pat
));
18682 if (GET_CODE (pat
) == PARALLEL
)
18686 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
18687 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
18694 /* Determine if INSN loads from memory. */
18697 is_load_insn (rtx insn
)
18699 if (!insn
|| !INSN_P (insn
))
18702 if (GET_CODE (insn
) == CALL_INSN
)
18705 return is_load_insn1 (PATTERN (insn
));
18708 /* Determine if PAT is a PATTERN of a store insn. */
18711 is_store_insn1 (rtx pat
)
18713 if (!pat
|| pat
== NULL_RTX
)
18716 if (GET_CODE (pat
) == SET
)
18717 return is_mem_ref (SET_DEST (pat
));
18719 if (GET_CODE (pat
) == PARALLEL
)
18723 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
18724 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
18731 /* Determine if INSN stores to memory. */
18734 is_store_insn (rtx insn
)
18736 if (!insn
|| !INSN_P (insn
))
18739 return is_store_insn1 (PATTERN (insn
));
18742 /* Return the dest of a store insn. */
18745 get_store_dest (rtx pat
)
18747 gcc_assert (is_store_insn1 (pat
));
18749 if (GET_CODE (pat
) == SET
)
18750 return SET_DEST (pat
);
18751 else if (GET_CODE (pat
) == PARALLEL
)
18755 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
18757 rtx inner_pat
= XVECEXP (pat
, 0, i
);
18758 if (GET_CODE (inner_pat
) == SET
18759 && is_mem_ref (SET_DEST (inner_pat
)))
18763 /* We shouldn't get here, because we should have either a simple
18764 store insn or a store with update which are covered above. */
18768 /* Returns whether the dependence between INSN and NEXT is considered
18769 costly by the given target. */
18772 rs6000_is_costly_dependence (dep_t dep
, int cost
, int distance
)
18777 /* If the flag is not enabled - no dependence is considered costly;
18778 allow all dependent insns in the same group.
18779 This is the most aggressive option. */
18780 if (rs6000_sched_costly_dep
== no_dep_costly
)
18783 /* If the flag is set to 1 - a dependence is always considered costly;
18784 do not allow dependent instructions in the same group.
18785 This is the most conservative option. */
18786 if (rs6000_sched_costly_dep
== all_deps_costly
)
18789 insn
= DEP_PRO (dep
);
18790 next
= DEP_CON (dep
);
18792 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
18793 && is_load_insn (next
)
18794 && is_store_insn (insn
))
18795 /* Prevent load after store in the same group. */
18798 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
18799 && is_load_insn (next
)
18800 && is_store_insn (insn
)
18801 && DEP_TYPE (dep
) == REG_DEP_TRUE
)
18802 /* Prevent load after store in the same group if it is a true
18806 /* The flag is set to X; dependences with latency >= X are considered costly,
18807 and will not be scheduled in the same group. */
18808 if (rs6000_sched_costly_dep
<= max_dep_latency
18809 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
18815 /* Return the next insn after INSN that is found before TAIL is reached,
18816 skipping any "non-active" insns - insns that will not actually occupy
18817 an issue slot. Return NULL_RTX if such an insn is not found. */
18820 get_next_active_insn (rtx insn
, rtx tail
)
18822 if (insn
== NULL_RTX
|| insn
== tail
)
18827 insn
= NEXT_INSN (insn
);
18828 if (insn
== NULL_RTX
|| insn
== tail
)
18833 || (NONJUMP_INSN_P (insn
)
18834 && GET_CODE (PATTERN (insn
)) != USE
18835 && GET_CODE (PATTERN (insn
)) != CLOBBER
18836 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
18842 /* We are about to begin issuing insns for this clock cycle. */
18845 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED
, int sched_verbose
,
18846 rtx
*ready ATTRIBUTE_UNUSED
,
18847 int *pn_ready ATTRIBUTE_UNUSED
,
18848 int clock_var ATTRIBUTE_UNUSED
)
18850 int n_ready
= *pn_ready
;
18853 fprintf (dump
, "// rs6000_sched_reorder :\n");
18855 /* Reorder the ready list, if the second to last ready insn
18856 is a nonepipeline insn. */
18857 if (rs6000_cpu_attr
== CPU_CELL
&& n_ready
> 1)
18859 if (is_nonpipeline_insn (ready
[n_ready
- 1])
18860 && (recog_memoized (ready
[n_ready
- 2]) > 0))
18861 /* Simply swap first two insns. */
18863 rtx tmp
= ready
[n_ready
- 1];
18864 ready
[n_ready
- 1] = ready
[n_ready
- 2];
18865 ready
[n_ready
- 2] = tmp
;
18869 if (rs6000_cpu
== PROCESSOR_POWER6
)
18870 load_store_pendulum
= 0;
18872 return rs6000_issue_rate ();
18875 /* Like rs6000_sched_reorder, but called after issuing each insn. */
18878 rs6000_sched_reorder2 (FILE *dump
, int sched_verbose
, rtx
*ready
,
18879 int *pn_ready
, int clock_var ATTRIBUTE_UNUSED
)
18882 fprintf (dump
, "// rs6000_sched_reorder2 :\n");
18884 /* For Power6, we need to handle some special cases to try and keep the
18885 store queue from overflowing and triggering expensive flushes.
18887 This code monitors how load and store instructions are being issued
18888 and skews the ready list one way or the other to increase the likelihood
18889 that a desired instruction is issued at the proper time.
18891 A couple of things are done. First, we maintain a "load_store_pendulum"
18892 to track the current state of load/store issue.
18894 - If the pendulum is at zero, then no loads or stores have been
18895 issued in the current cycle so we do nothing.
18897 - If the pendulum is 1, then a single load has been issued in this
18898 cycle and we attempt to locate another load in the ready list to
18901 - If the pendulum is -2, then two stores have already been
18902 issued in this cycle, so we increase the priority of the first load
18903 in the ready list to increase it's likelihood of being chosen first
18906 - If the pendulum is -1, then a single store has been issued in this
18907 cycle and we attempt to locate another store in the ready list to
18908 issue with it, preferring a store to an adjacent memory location to
18909 facilitate store pairing in the store queue.
18911 - If the pendulum is 2, then two loads have already been
18912 issued in this cycle, so we increase the priority of the first store
18913 in the ready list to increase it's likelihood of being chosen first
18916 - If the pendulum < -2 or > 2, then do nothing.
18918 Note: This code covers the most common scenarios. There exist non
18919 load/store instructions which make use of the LSU and which
18920 would need to be accounted for to strictly model the behavior
18921 of the machine. Those instructions are currently unaccounted
18922 for to help minimize compile time overhead of this code.
18924 if (rs6000_cpu
== PROCESSOR_POWER6
&& last_scheduled_insn
)
18930 if (is_store_insn (last_scheduled_insn
))
18931 /* Issuing a store, swing the load_store_pendulum to the left */
18932 load_store_pendulum
--;
18933 else if (is_load_insn (last_scheduled_insn
))
18934 /* Issuing a load, swing the load_store_pendulum to the right */
18935 load_store_pendulum
++;
18937 return cached_can_issue_more
;
18939 /* If the pendulum is balanced, or there is only one instruction on
18940 the ready list, then all is well, so return. */
18941 if ((load_store_pendulum
== 0) || (*pn_ready
<= 1))
18942 return cached_can_issue_more
;
18944 if (load_store_pendulum
== 1)
18946 /* A load has been issued in this cycle. Scan the ready list
18947 for another load to issue with it */
18952 if (is_load_insn (ready
[pos
]))
18954 /* Found a load. Move it to the head of the ready list,
18955 and adjust it's priority so that it is more likely to
18958 for (i
=pos
; i
<*pn_ready
-1; i
++)
18959 ready
[i
] = ready
[i
+ 1];
18960 ready
[*pn_ready
-1] = tmp
;
18961 if INSN_PRIORITY_KNOWN (tmp
)
18962 INSN_PRIORITY (tmp
)++;
18968 else if (load_store_pendulum
== -2)
18970 /* Two stores have been issued in this cycle. Increase the
18971 priority of the first load in the ready list to favor it for
18972 issuing in the next cycle. */
18977 if (is_load_insn (ready
[pos
])
18978 && INSN_PRIORITY_KNOWN (ready
[pos
]))
18980 INSN_PRIORITY (ready
[pos
])++;
18982 /* Adjust the pendulum to account for the fact that a load
18983 was found and increased in priority. This is to prevent
18984 increasing the priority of multiple loads */
18985 load_store_pendulum
--;
18992 else if (load_store_pendulum
== -1)
18994 /* A store has been issued in this cycle. Scan the ready list for
18995 another store to issue with it, preferring a store to an adjacent
18997 int first_store_pos
= -1;
19003 if (is_store_insn (ready
[pos
]))
19005 /* Maintain the index of the first store found on the
19007 if (first_store_pos
== -1)
19008 first_store_pos
= pos
;
19010 if (is_store_insn (last_scheduled_insn
)
19011 && adjacent_mem_locations (last_scheduled_insn
,ready
[pos
]))
19013 /* Found an adjacent store. Move it to the head of the
19014 ready list, and adjust it's priority so that it is
19015 more likely to stay there */
19017 for (i
=pos
; i
<*pn_ready
-1; i
++)
19018 ready
[i
] = ready
[i
+ 1];
19019 ready
[*pn_ready
-1] = tmp
;
19020 if INSN_PRIORITY_KNOWN (tmp
)
19021 INSN_PRIORITY (tmp
)++;
19022 first_store_pos
= -1;
19030 if (first_store_pos
>= 0)
19032 /* An adjacent store wasn't found, but a non-adjacent store was,
19033 so move the non-adjacent store to the front of the ready
19034 list, and adjust its priority so that it is more likely to
19036 tmp
= ready
[first_store_pos
];
19037 for (i
=first_store_pos
; i
<*pn_ready
-1; i
++)
19038 ready
[i
] = ready
[i
+ 1];
19039 ready
[*pn_ready
-1] = tmp
;
19040 if INSN_PRIORITY_KNOWN (tmp
)
19041 INSN_PRIORITY (tmp
)++;
19044 else if (load_store_pendulum
== 2)
19046 /* Two loads have been issued in this cycle. Increase the priority
19047 of the first store in the ready list to favor it for issuing in
19053 if (is_store_insn (ready
[pos
])
19054 && INSN_PRIORITY_KNOWN (ready
[pos
]))
19056 INSN_PRIORITY (ready
[pos
])++;
19058 /* Adjust the pendulum to account for the fact that a store
19059 was found and increased in priority. This is to prevent
19060 increasing the priority of multiple stores */
19061 load_store_pendulum
++;
19070 return cached_can_issue_more
;
19073 /* Return whether the presence of INSN causes a dispatch group termination
19074 of group WHICH_GROUP.
19076 If WHICH_GROUP == current_group, this function will return true if INSN
19077 causes the termination of the current group (i.e, the dispatch group to
19078 which INSN belongs). This means that INSN will be the last insn in the
19079 group it belongs to.
19081 If WHICH_GROUP == previous_group, this function will return true if INSN
19082 causes the termination of the previous group (i.e, the dispatch group that
19083 precedes the group to which INSN belongs). This means that INSN will be
19084 the first insn in the group it belongs to). */
19087 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
19094 first
= insn_must_be_first_in_group (insn
);
19095 last
= insn_must_be_last_in_group (insn
);
19100 if (which_group
== current_group
)
19102 else if (which_group
== previous_group
)
19110 insn_must_be_first_in_group (rtx insn
)
19112 enum attr_type type
;
19115 || insn
== NULL_RTX
19116 || GET_CODE (insn
) == NOTE
19117 || GET_CODE (PATTERN (insn
)) == USE
19118 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19121 switch (rs6000_cpu
)
19123 case PROCESSOR_POWER5
:
19124 if (is_cracked_insn (insn
))
19126 case PROCESSOR_POWER4
:
19127 if (is_microcoded_insn (insn
))
19130 if (!rs6000_sched_groups
)
19133 type
= get_attr_type (insn
);
19140 case TYPE_DELAYED_CR
:
19141 case TYPE_CR_LOGICAL
:
19155 case PROCESSOR_POWER6
:
19156 type
= get_attr_type (insn
);
19160 case TYPE_INSERT_DWORD
:
19164 case TYPE_VAR_SHIFT_ROTATE
:
19171 case TYPE_INSERT_WORD
:
19172 case TYPE_DELAYED_COMPARE
:
19173 case TYPE_IMUL_COMPARE
:
19174 case TYPE_LMUL_COMPARE
:
19175 case TYPE_FPCOMPARE
:
19186 case TYPE_LOAD_EXT_UX
:
19188 case TYPE_STORE_UX
:
19189 case TYPE_FPLOAD_U
:
19190 case TYPE_FPLOAD_UX
:
19191 case TYPE_FPSTORE_U
:
19192 case TYPE_FPSTORE_UX
:
19206 insn_must_be_last_in_group (rtx insn
)
19208 enum attr_type type
;
19211 || insn
== NULL_RTX
19212 || GET_CODE (insn
) == NOTE
19213 || GET_CODE (PATTERN (insn
)) == USE
19214 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
19217 switch (rs6000_cpu
) {
19218 case PROCESSOR_POWER4
:
19219 case PROCESSOR_POWER5
:
19220 if (is_microcoded_insn (insn
))
19223 if (is_branch_slot_insn (insn
))
19227 case PROCESSOR_POWER6
:
19228 type
= get_attr_type (insn
);
19235 case TYPE_VAR_SHIFT_ROTATE
:
19242 case TYPE_DELAYED_COMPARE
:
19243 case TYPE_IMUL_COMPARE
:
19244 case TYPE_LMUL_COMPARE
:
19245 case TYPE_FPCOMPARE
:
19266 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
19267 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
19270 is_costly_group (rtx
*group_insns
, rtx next_insn
)
19273 int issue_rate
= rs6000_issue_rate ();
19275 for (i
= 0; i
< issue_rate
; i
++)
19277 sd_iterator_def sd_it
;
19279 rtx insn
= group_insns
[i
];
19284 FOR_EACH_DEP (insn
, SD_LIST_FORW
, sd_it
, dep
)
19286 rtx next
= DEP_CON (dep
);
19288 if (next
== next_insn
19289 && rs6000_is_costly_dependence (dep
, dep_cost (dep
), 0))
19297 /* Utility of the function redefine_groups.
19298 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
19299 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
19300 to keep it "far" (in a separate group) from GROUP_INSNS, following
19301 one of the following schemes, depending on the value of the flag
19302 -minsert_sched_nops = X:
19303 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
19304 in order to force NEXT_INSN into a separate group.
19305 (2) X < sched_finish_regroup_exact: insert exactly X nops.
19306 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
19307 insertion (has a group just ended, how many vacant issue slots remain in the
19308 last group, and how many dispatch groups were encountered so far). */
19311 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
19312 rtx next_insn
, bool *group_end
, int can_issue_more
,
19317 int issue_rate
= rs6000_issue_rate ();
19318 bool end
= *group_end
;
19321 if (next_insn
== NULL_RTX
)
19322 return can_issue_more
;
19324 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
19325 return can_issue_more
;
19327 force
= is_costly_group (group_insns
, next_insn
);
19329 return can_issue_more
;
19331 if (sched_verbose
> 6)
19332 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
19333 *group_count
,can_issue_more
);
19335 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
19338 can_issue_more
= 0;
19340 /* Since only a branch can be issued in the last issue_slot, it is
19341 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
19342 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
19343 in this case the last nop will start a new group and the branch
19344 will be forced to the new group. */
19345 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
19348 while (can_issue_more
> 0)
19351 emit_insn_before (nop
, next_insn
);
19359 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
19361 int n_nops
= rs6000_sched_insert_nops
;
19363 /* Nops can't be issued from the branch slot, so the effective
19364 issue_rate for nops is 'issue_rate - 1'. */
19365 if (can_issue_more
== 0)
19366 can_issue_more
= issue_rate
;
19368 if (can_issue_more
== 0)
19370 can_issue_more
= issue_rate
- 1;
19373 for (i
= 0; i
< issue_rate
; i
++)
19375 group_insns
[i
] = 0;
19382 emit_insn_before (nop
, next_insn
);
19383 if (can_issue_more
== issue_rate
- 1) /* new group begins */
19386 if (can_issue_more
== 0)
19388 can_issue_more
= issue_rate
- 1;
19391 for (i
= 0; i
< issue_rate
; i
++)
19393 group_insns
[i
] = 0;
19399 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
19402 /* Is next_insn going to start a new group? */
19405 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
19406 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
19407 || (can_issue_more
< issue_rate
&&
19408 insn_terminates_group_p (next_insn
, previous_group
)));
19409 if (*group_end
&& end
)
19412 if (sched_verbose
> 6)
19413 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
19414 *group_count
, can_issue_more
);
19415 return can_issue_more
;
19418 return can_issue_more
;
19421 /* This function tries to synch the dispatch groups that the compiler "sees"
19422 with the dispatch groups that the processor dispatcher is expected to
19423 form in practice. It tries to achieve this synchronization by forcing the
19424 estimated processor grouping on the compiler (as opposed to the function
19425 'pad_goups' which tries to force the scheduler's grouping on the processor).
19427 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
19428 examines the (estimated) dispatch groups that will be formed by the processor
19429 dispatcher. It marks these group boundaries to reflect the estimated
19430 processor grouping, overriding the grouping that the scheduler had marked.
19431 Depending on the value of the flag '-minsert-sched-nops' this function can
19432 force certain insns into separate groups or force a certain distance between
19433 them by inserting nops, for example, if there exists a "costly dependence"
19436 The function estimates the group boundaries that the processor will form as
19437 follows: It keeps track of how many vacant issue slots are available after
19438 each insn. A subsequent insn will start a new group if one of the following
19440 - no more vacant issue slots remain in the current dispatch group.
19441 - only the last issue slot, which is the branch slot, is vacant, but the next
19442 insn is not a branch.
19443 - only the last 2 or less issue slots, including the branch slot, are vacant,
19444 which means that a cracked insn (which occupies two issue slots) can't be
19445 issued in this group.
19446 - less than 'issue_rate' slots are vacant, and the next insn always needs to
19447 start a new group. */
19450 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
19452 rtx insn
, next_insn
;
19454 int can_issue_more
;
19457 int group_count
= 0;
19461 issue_rate
= rs6000_issue_rate ();
19462 group_insns
= alloca (issue_rate
* sizeof (rtx
));
19463 for (i
= 0; i
< issue_rate
; i
++)
19465 group_insns
[i
] = 0;
19467 can_issue_more
= issue_rate
;
19469 insn
= get_next_active_insn (prev_head_insn
, tail
);
19472 while (insn
!= NULL_RTX
)
19474 slot
= (issue_rate
- can_issue_more
);
19475 group_insns
[slot
] = insn
;
19477 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
19478 if (insn_terminates_group_p (insn
, current_group
))
19479 can_issue_more
= 0;
19481 next_insn
= get_next_active_insn (insn
, tail
);
19482 if (next_insn
== NULL_RTX
)
19483 return group_count
+ 1;
19485 /* Is next_insn going to start a new group? */
19487 = (can_issue_more
== 0
19488 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
19489 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
19490 || (can_issue_more
< issue_rate
&&
19491 insn_terminates_group_p (next_insn
, previous_group
)));
19493 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
19494 next_insn
, &group_end
, can_issue_more
,
19500 can_issue_more
= 0;
19501 for (i
= 0; i
< issue_rate
; i
++)
19503 group_insns
[i
] = 0;
19507 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
19508 PUT_MODE (next_insn
, VOIDmode
);
19509 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
19510 PUT_MODE (next_insn
, TImode
);
19513 if (can_issue_more
== 0)
19514 can_issue_more
= issue_rate
;
19517 return group_count
;
19520 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
19521 dispatch group boundaries that the scheduler had marked. Pad with nops
19522 any dispatch groups which have vacant issue slots, in order to force the
19523 scheduler's grouping on the processor dispatcher. The function
19524 returns the number of dispatch groups found. */
19527 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
19529 rtx insn
, next_insn
;
19532 int can_issue_more
;
19534 int group_count
= 0;
19536 /* Initialize issue_rate. */
19537 issue_rate
= rs6000_issue_rate ();
19538 can_issue_more
= issue_rate
;
19540 insn
= get_next_active_insn (prev_head_insn
, tail
);
19541 next_insn
= get_next_active_insn (insn
, tail
);
19543 while (insn
!= NULL_RTX
)
19546 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
19548 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
19550 if (next_insn
== NULL_RTX
)
19555 /* If the scheduler had marked group termination at this location
19556 (between insn and next_indn), and neither insn nor next_insn will
19557 force group termination, pad the group with nops to force group
19560 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
19561 && !insn_terminates_group_p (insn
, current_group
)
19562 && !insn_terminates_group_p (next_insn
, previous_group
))
19564 if (!is_branch_slot_insn (next_insn
))
19567 while (can_issue_more
)
19570 emit_insn_before (nop
, next_insn
);
19575 can_issue_more
= issue_rate
;
19580 next_insn
= get_next_active_insn (insn
, tail
);
19583 return group_count
;
19586 /* We're beginning a new block. Initialize data structures as necessary. */
19589 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED
,
19590 int sched_verbose ATTRIBUTE_UNUSED
,
19591 int max_ready ATTRIBUTE_UNUSED
)
19593 last_scheduled_insn
= NULL_RTX
;
19594 load_store_pendulum
= 0;
19597 /* The following function is called at the end of scheduling BB.
19598 After reload, it inserts nops at insn group bundling. */
19601 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
19606 fprintf (dump
, "=== Finishing schedule.\n");
19608 if (reload_completed
&& rs6000_sched_groups
)
19610 if (rs6000_sched_insert_nops
== sched_finish_none
)
19613 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
19614 n_groups
= pad_groups (dump
, sched_verbose
,
19615 current_sched_info
->prev_head
,
19616 current_sched_info
->next_tail
);
19618 n_groups
= redefine_groups (dump
, sched_verbose
,
19619 current_sched_info
->prev_head
,
19620 current_sched_info
->next_tail
);
19622 if (sched_verbose
>= 6)
19624 fprintf (dump
, "ngroups = %d\n", n_groups
);
19625 print_rtl (dump
, current_sched_info
->prev_head
);
19626 fprintf (dump
, "Done finish_sched\n");
19631 /* Length in units of the trampoline for entering a nested function. */
19634 rs6000_trampoline_size (void)
19638 switch (DEFAULT_ABI
)
19641 gcc_unreachable ();
19644 ret
= (TARGET_32BIT
) ? 12 : 24;
19649 ret
= (TARGET_32BIT
) ? 40 : 48;
19656 /* Emit RTL insns to initialize the variable parts of a trampoline.
19657 FNADDR is an RTX for the address of the function's pure code.
19658 CXT is an RTX for the static chain value for the function. */
19661 rs6000_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
19663 int regsize
= (TARGET_32BIT
) ? 4 : 8;
19664 rtx ctx_reg
= force_reg (Pmode
, cxt
);
19666 switch (DEFAULT_ABI
)
19669 gcc_unreachable ();
19671 /* Macros to shorten the code expansions below. */
19672 #define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
19673 #define MEM_PLUS(addr,offset) \
19674 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
19676 /* Under AIX, just build the 3 word function descriptor */
19679 rtx fn_reg
= gen_reg_rtx (Pmode
);
19680 rtx toc_reg
= gen_reg_rtx (Pmode
);
19681 emit_move_insn (fn_reg
, MEM_DEREF (fnaddr
));
19682 emit_move_insn (toc_reg
, MEM_PLUS (fnaddr
, regsize
));
19683 emit_move_insn (MEM_DEREF (addr
), fn_reg
);
19684 emit_move_insn (MEM_PLUS (addr
, regsize
), toc_reg
);
19685 emit_move_insn (MEM_PLUS (addr
, 2*regsize
), ctx_reg
);
19689 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
19692 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__trampoline_setup"),
19693 FALSE
, VOIDmode
, 4,
19695 GEN_INT (rs6000_trampoline_size ()), SImode
,
19705 /* Table of valid machine attributes. */
19707 const struct attribute_spec rs6000_attribute_table
[] =
19709 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
19710 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
},
19711 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
19712 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
19713 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
19714 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
19715 #ifdef SUBTARGET_ATTRIBUTE_TABLE
19716 SUBTARGET_ATTRIBUTE_TABLE
,
19718 { NULL
, 0, 0, false, false, false, NULL
}
19721 /* Handle the "altivec" attribute. The attribute may have
19722 arguments as follows:
19724 __attribute__((altivec(vector__)))
19725 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
19726 __attribute__((altivec(bool__))) (always followed by 'unsigned')
19728 and may appear more than once (e.g., 'vector bool char') in a
19729 given declaration. */
19732 rs6000_handle_altivec_attribute (tree
*node
,
19733 tree name ATTRIBUTE_UNUSED
,
19735 int flags ATTRIBUTE_UNUSED
,
19736 bool *no_add_attrs
)
19738 tree type
= *node
, result
= NULL_TREE
;
19739 enum machine_mode mode
;
19742 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
19743 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
19744 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
19747 while (POINTER_TYPE_P (type
)
19748 || TREE_CODE (type
) == FUNCTION_TYPE
19749 || TREE_CODE (type
) == METHOD_TYPE
19750 || TREE_CODE (type
) == ARRAY_TYPE
)
19751 type
= TREE_TYPE (type
);
19753 mode
= TYPE_MODE (type
);
19755 /* Check for invalid AltiVec type qualifiers. */
19756 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
19759 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
19760 else if (rs6000_warn_altivec_long
)
19761 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
19763 else if (type
== long_long_unsigned_type_node
19764 || type
== long_long_integer_type_node
)
19765 error ("use of %<long long%> in AltiVec types is invalid");
19766 else if (type
== double_type_node
)
19767 error ("use of %<double%> in AltiVec types is invalid");
19768 else if (type
== long_double_type_node
)
19769 error ("use of %<long double%> in AltiVec types is invalid");
19770 else if (type
== boolean_type_node
)
19771 error ("use of boolean types in AltiVec types is invalid");
19772 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
19773 error ("use of %<complex%> in AltiVec types is invalid");
19774 else if (DECIMAL_FLOAT_MODE_P (mode
))
19775 error ("use of decimal floating point types in AltiVec types is invalid");
19777 switch (altivec_type
)
19780 unsigned_p
= TYPE_UNSIGNED (type
);
19784 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
19787 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
19790 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
19792 case SFmode
: result
= V4SF_type_node
; break;
19793 /* If the user says 'vector int bool', we may be handed the 'bool'
19794 attribute _before_ the 'vector' attribute, and so select the
19795 proper type in the 'b' case below. */
19796 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
19804 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
19805 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
19806 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
19813 case V8HImode
: result
= pixel_V8HI_type_node
;
19819 if (result
&& result
!= type
&& TYPE_READONLY (type
))
19820 result
= build_qualified_type (result
, TYPE_QUAL_CONST
);
19822 *no_add_attrs
= true; /* No need to hang on to the attribute. */
19825 *node
= reconstruct_complex_type (*node
, result
);
19830 /* AltiVec defines four built-in scalar types that serve as vector
19831 elements; we must teach the compiler how to mangle them. */
19833 static const char *
19834 rs6000_mangle_type (const_tree type
)
19836 type
= TYPE_MAIN_VARIANT (type
);
19838 if (TREE_CODE (type
) != VOID_TYPE
&& TREE_CODE (type
) != BOOLEAN_TYPE
19839 && TREE_CODE (type
) != INTEGER_TYPE
&& TREE_CODE (type
) != REAL_TYPE
)
19842 if (type
== bool_char_type_node
) return "U6__boolc";
19843 if (type
== bool_short_type_node
) return "U6__bools";
19844 if (type
== pixel_type_node
) return "u7__pixel";
19845 if (type
== bool_int_type_node
) return "U6__booli";
19847 /* Mangle IBM extended float long double as `g' (__float128) on
19848 powerpc*-linux where long-double-64 previously was the default. */
19849 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
19851 && TARGET_LONG_DOUBLE_128
19852 && !TARGET_IEEEQUAD
)
19855 /* For all other types, use normal C++ mangling. */
19859 /* Handle a "longcall" or "shortcall" attribute; arguments as in
19860 struct attribute_spec.handler. */
19863 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
19864 tree args ATTRIBUTE_UNUSED
,
19865 int flags ATTRIBUTE_UNUSED
,
19866 bool *no_add_attrs
)
19868 if (TREE_CODE (*node
) != FUNCTION_TYPE
19869 && TREE_CODE (*node
) != FIELD_DECL
19870 && TREE_CODE (*node
) != TYPE_DECL
)
19872 warning (OPT_Wattributes
, "%qs attribute only applies to functions",
19873 IDENTIFIER_POINTER (name
));
19874 *no_add_attrs
= true;
19880 /* Set longcall attributes on all functions declared when
19881 rs6000_default_long_calls is true. */
19883 rs6000_set_default_type_attributes (tree type
)
19885 if (rs6000_default_long_calls
19886 && (TREE_CODE (type
) == FUNCTION_TYPE
19887 || TREE_CODE (type
) == METHOD_TYPE
))
19888 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
19890 TYPE_ATTRIBUTES (type
));
19893 darwin_set_default_type_attributes (type
);
19897 /* Return a reference suitable for calling a function with the
19898 longcall attribute. */
19901 rs6000_longcall_ref (rtx call_ref
)
19903 const char *call_name
;
19906 if (GET_CODE (call_ref
) != SYMBOL_REF
)
19909 /* System V adds '.' to the internal name, so skip them. */
19910 call_name
= XSTR (call_ref
, 0);
19911 if (*call_name
== '.')
19913 while (*call_name
== '.')
19916 node
= get_identifier (call_name
);
19917 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
19920 return force_reg (Pmode
, call_ref
);
19923 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
19924 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
19927 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
19928 struct attribute_spec.handler. */
19930 rs6000_handle_struct_attribute (tree
*node
, tree name
,
19931 tree args ATTRIBUTE_UNUSED
,
19932 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
19935 if (DECL_P (*node
))
19937 if (TREE_CODE (*node
) == TYPE_DECL
)
19938 type
= &TREE_TYPE (*node
);
19943 if (!(type
&& (TREE_CODE (*type
) == RECORD_TYPE
19944 || TREE_CODE (*type
) == UNION_TYPE
)))
19946 warning (OPT_Wattributes
, "%qs attribute ignored", IDENTIFIER_POINTER (name
));
19947 *no_add_attrs
= true;
19950 else if ((is_attribute_p ("ms_struct", name
)
19951 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type
)))
19952 || ((is_attribute_p ("gcc_struct", name
)
19953 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type
)))))
19955 warning (OPT_Wattributes
, "%qs incompatible attribute ignored",
19956 IDENTIFIER_POINTER (name
));
19957 *no_add_attrs
= true;
19964 rs6000_ms_bitfield_layout_p (const_tree record_type
)
19966 return (TARGET_USE_MS_BITFIELD_LAYOUT
&&
19967 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type
)))
19968 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type
));
19971 #ifdef USING_ELFOS_H
19973 /* A get_unnamed_section callback, used for switching to toc_section. */
19976 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
19978 if (DEFAULT_ABI
== ABI_AIX
19979 && TARGET_MINIMAL_TOC
19980 && !TARGET_RELOCATABLE
)
19982 if (!toc_initialized
)
19984 toc_initialized
= 1;
19985 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
19986 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LCTOC", 0);
19987 fprintf (asm_out_file
, "\t.tc ");
19988 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1[TC],");
19989 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
19990 fprintf (asm_out_file
, "\n");
19992 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
19993 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
19994 fprintf (asm_out_file
, " = .+32768\n");
19997 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
19999 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_RELOCATABLE
)
20000 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
20003 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
20004 if (!toc_initialized
)
20006 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
20007 fprintf (asm_out_file
, " = .+32768\n");
20008 toc_initialized
= 1;
20013 /* Implement TARGET_ASM_INIT_SECTIONS. */
20016 rs6000_elf_asm_init_sections (void)
20019 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op
, NULL
);
20022 = get_unnamed_section (SECTION_WRITE
, output_section_asm_op
,
20023 SDATA2_SECTION_ASM_OP
);
20026 /* Implement TARGET_SELECT_RTX_SECTION. */
20029 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
20030 unsigned HOST_WIDE_INT align
)
20032 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
20033 return toc_section
;
20035 return default_elf_select_rtx_section (mode
, x
, align
);
20038 /* For a SYMBOL_REF, set generic flags and then perform some
20039 target-specific processing.
20041 When the AIX ABI is requested on a non-AIX system, replace the
20042 function name with the real name (with a leading .) rather than the
20043 function descriptor name. This saves a lot of overriding code to
20044 read the prefixes. */
20047 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
20049 default_encode_section_info (decl
, rtl
, first
);
20052 && TREE_CODE (decl
) == FUNCTION_DECL
20054 && DEFAULT_ABI
== ABI_AIX
)
20056 rtx sym_ref
= XEXP (rtl
, 0);
20057 size_t len
= strlen (XSTR (sym_ref
, 0));
20058 char *str
= alloca (len
+ 2);
20060 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
20061 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
20066 compare_section_name (const char *section
, const char *template)
20070 len
= strlen (template);
20071 return (strncmp (section
, template, len
) == 0
20072 && (section
[len
] == 0 || section
[len
] == '.'));
20076 rs6000_elf_in_small_data_p (const_tree decl
)
20078 if (rs6000_sdata
== SDATA_NONE
)
20081 /* We want to merge strings, so we never consider them small data. */
20082 if (TREE_CODE (decl
) == STRING_CST
)
20085 /* Functions are never in the small data area. */
20086 if (TREE_CODE (decl
) == FUNCTION_DECL
)
20089 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
20091 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
20092 if (compare_section_name (section
, ".sdata")
20093 || compare_section_name (section
, ".sdata2")
20094 || compare_section_name (section
, ".gnu.linkonce.s")
20095 || compare_section_name (section
, ".sbss")
20096 || compare_section_name (section
, ".sbss2")
20097 || compare_section_name (section
, ".gnu.linkonce.sb")
20098 || strcmp (section
, ".PPC.EMB.sdata0") == 0
20099 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
20104 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
20107 && (unsigned HOST_WIDE_INT
) size
<= g_switch_value
20108 /* If it's not public, and we're not going to reference it there,
20109 there's no need to put it in the small data section. */
20110 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
20117 #endif /* USING_ELFOS_H */
20119 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
20122 rs6000_use_blocks_for_constant_p (enum machine_mode mode
, const_rtx x
)
20124 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
);
20127 /* Return a REG that occurs in ADDR with coefficient 1.
20128 ADDR can be effectively incremented by incrementing REG.
20130 r0 is special and we must not select it as an address
20131 register by this routine since our caller will try to
20132 increment the returned register via an "la" instruction. */
20135 find_addr_reg (rtx addr
)
20137 while (GET_CODE (addr
) == PLUS
)
20139 if (GET_CODE (XEXP (addr
, 0)) == REG
20140 && REGNO (XEXP (addr
, 0)) != 0)
20141 addr
= XEXP (addr
, 0);
20142 else if (GET_CODE (XEXP (addr
, 1)) == REG
20143 && REGNO (XEXP (addr
, 1)) != 0)
20144 addr
= XEXP (addr
, 1);
20145 else if (CONSTANT_P (XEXP (addr
, 0)))
20146 addr
= XEXP (addr
, 1);
20147 else if (CONSTANT_P (XEXP (addr
, 1)))
20148 addr
= XEXP (addr
, 0);
20150 gcc_unreachable ();
20152 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
20157 rs6000_fatal_bad_address (rtx op
)
20159 fatal_insn ("bad address", op
);
20164 static tree branch_island_list
= 0;
20166 /* Remember to generate a branch island for far calls to the given
20170 add_compiler_branch_island (tree label_name
, tree function_name
,
20173 tree branch_island
= build_tree_list (function_name
, label_name
);
20174 TREE_TYPE (branch_island
) = build_int_cst (NULL_TREE
, line_number
);
20175 TREE_CHAIN (branch_island
) = branch_island_list
;
20176 branch_island_list
= branch_island
;
20179 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
20180 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
20181 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
20182 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
20184 /* Generate far-jump branch islands for everything on the
20185 branch_island_list. Invoked immediately after the last instruction
20186 of the epilogue has been emitted; the branch-islands must be
20187 appended to, and contiguous with, the function body. Mach-O stubs
20188 are generated in machopic_output_stub(). */
20191 macho_branch_islands (void)
20194 tree branch_island
;
20196 for (branch_island
= branch_island_list
;
20198 branch_island
= TREE_CHAIN (branch_island
))
20200 const char *label
=
20201 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island
));
20203 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island
));
20204 char name_buf
[512];
20205 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
20206 if (name
[0] == '*' || name
[0] == '&')
20207 strcpy (name_buf
, name
+1);
20211 strcpy (name_buf
+1, name
);
20213 strcpy (tmp_buf
, "\n");
20214 strcat (tmp_buf
, label
);
20215 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
20216 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
20217 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
20218 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
20221 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
20222 strcat (tmp_buf
, label
);
20223 strcat (tmp_buf
, "_pic\n");
20224 strcat (tmp_buf
, label
);
20225 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
20227 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
20228 strcat (tmp_buf
, name_buf
);
20229 strcat (tmp_buf
, " - ");
20230 strcat (tmp_buf
, label
);
20231 strcat (tmp_buf
, "_pic)\n");
20233 strcat (tmp_buf
, "\tmtlr r0\n");
20235 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
20236 strcat (tmp_buf
, name_buf
);
20237 strcat (tmp_buf
, " - ");
20238 strcat (tmp_buf
, label
);
20239 strcat (tmp_buf
, "_pic)\n");
20241 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
20245 strcat (tmp_buf
, ":\nlis r12,hi16(");
20246 strcat (tmp_buf
, name_buf
);
20247 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
20248 strcat (tmp_buf
, name_buf
);
20249 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
20251 output_asm_insn (tmp_buf
, 0);
20252 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
20253 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
20254 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
20255 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
20258 branch_island_list
= 0;
20261 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
20262 already there or not. */
20265 no_previous_def (tree function_name
)
20267 tree branch_island
;
20268 for (branch_island
= branch_island_list
;
20270 branch_island
= TREE_CHAIN (branch_island
))
20271 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
20276 /* GET_PREV_LABEL gets the label name from the previous definition of
20280 get_prev_label (tree function_name
)
20282 tree branch_island
;
20283 for (branch_island
= branch_island_list
;
20285 branch_island
= TREE_CHAIN (branch_island
))
20286 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
20287 return BRANCH_ISLAND_LABEL_NAME (branch_island
);
20291 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
20292 #define DARWIN_LINKER_GENERATES_ISLANDS 0
20295 /* KEXTs still need branch islands. */
20296 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
20297 || flag_mkernel || flag_apple_kext)
20299 /* INSN is either a function call or a millicode call. It may have an
20300 unconditional jump in its delay slot.
20302 CALL_DEST is the routine we are calling. */
20305 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
20306 int cookie_operand_number
)
20308 static char buf
[256];
20309 if (DARWIN_GENERATE_ISLANDS
20310 && GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
20311 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
20314 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
20316 if (no_previous_def (funname
))
20318 rtx label_rtx
= gen_label_rtx ();
20319 char *label_buf
, temp_buf
[256];
20320 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
20321 CODE_LABEL_NUMBER (label_rtx
));
20322 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
20323 labelname
= get_identifier (label_buf
);
20324 add_compiler_branch_island (labelname
, funname
, insn_line (insn
));
20327 labelname
= get_prev_label (funname
);
20329 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
20330 instruction will reach 'foo', otherwise link as 'bl L42'".
20331 "L42" should be a 'branch island', that will do a far jump to
20332 'foo'. Branch islands are generated in
20333 macho_branch_islands(). */
20334 sprintf (buf
, "jbsr %%z%d,%.246s",
20335 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
20338 sprintf (buf
, "bl %%z%d", dest_operand_number
);
20342 /* Generate PIC and indirect symbol stubs. */
20345 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
20347 unsigned int length
;
20348 char *symbol_name
, *lazy_ptr_name
;
20349 char *local_label_0
;
20350 static int label
= 0;
20352 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
20353 symb
= (*targetm
.strip_name_encoding
) (symb
);
20356 length
= strlen (symb
);
20357 symbol_name
= alloca (length
+ 32);
20358 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
20360 lazy_ptr_name
= alloca (length
+ 32);
20361 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
20364 switch_to_section (darwin_sections
[machopic_picsymbol_stub1_section
]);
20366 switch_to_section (darwin_sections
[machopic_symbol_stub1_section
]);
20370 fprintf (file
, "\t.align 5\n");
20372 fprintf (file
, "%s:\n", stub
);
20373 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
20376 local_label_0
= alloca (sizeof ("\"L00000000000$spb\""));
20377 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
20379 fprintf (file
, "\tmflr r0\n");
20380 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
20381 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
20382 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
20383 lazy_ptr_name
, local_label_0
);
20384 fprintf (file
, "\tmtlr r0\n");
20385 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
20386 (TARGET_64BIT
? "ldu" : "lwzu"),
20387 lazy_ptr_name
, local_label_0
);
20388 fprintf (file
, "\tmtctr r12\n");
20389 fprintf (file
, "\tbctr\n");
20393 fprintf (file
, "\t.align 4\n");
20395 fprintf (file
, "%s:\n", stub
);
20396 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
20398 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
20399 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
20400 (TARGET_64BIT
? "ldu" : "lwzu"),
20402 fprintf (file
, "\tmtctr r12\n");
20403 fprintf (file
, "\tbctr\n");
20406 switch_to_section (darwin_sections
[machopic_lazy_symbol_ptr_section
]);
20407 fprintf (file
, "%s:\n", lazy_ptr_name
);
20408 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
20409 fprintf (file
, "%sdyld_stub_binding_helper\n",
20410 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
20413 /* Legitimize PIC addresses. If the address is already
20414 position-independent, we return ORIG. Newly generated
20415 position-independent addresses go into a reg. This is REG if non
20416 zero, otherwise we allocate register(s) as necessary. */
20418 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
20421 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
20426 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
20427 reg
= gen_reg_rtx (Pmode
);
20429 if (GET_CODE (orig
) == CONST
)
20433 if (GET_CODE (XEXP (orig
, 0)) == PLUS
20434 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
20437 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
20439 /* Use a different reg for the intermediate value, as
20440 it will be marked UNCHANGING. */
20441 reg_temp
= !can_create_pseudo_p () ? reg
: gen_reg_rtx (Pmode
);
20442 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
20445 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
20448 if (GET_CODE (offset
) == CONST_INT
)
20450 if (SMALL_INT (offset
))
20451 return plus_constant (base
, INTVAL (offset
));
20452 else if (! reload_in_progress
&& ! reload_completed
)
20453 offset
= force_reg (Pmode
, offset
);
20456 rtx mem
= force_const_mem (Pmode
, orig
);
20457 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
20460 return gen_rtx_PLUS (Pmode
, base
, offset
);
20463 /* Fall back on generic machopic code. */
20464 return machopic_legitimize_pic_address (orig
, mode
, reg
);
20467 /* Output a .machine directive for the Darwin assembler, and call
20468 the generic start_file routine. */
20471 rs6000_darwin_file_start (void)
20473 static const struct
20479 { "ppc64", "ppc64", MASK_64BIT
},
20480 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
20481 { "power4", "ppc970", 0 },
20482 { "G5", "ppc970", 0 },
20483 { "7450", "ppc7450", 0 },
20484 { "7400", "ppc7400", MASK_ALTIVEC
},
20485 { "G4", "ppc7400", 0 },
20486 { "750", "ppc750", 0 },
20487 { "740", "ppc750", 0 },
20488 { "G3", "ppc750", 0 },
20489 { "604e", "ppc604e", 0 },
20490 { "604", "ppc604", 0 },
20491 { "603e", "ppc603", 0 },
20492 { "603", "ppc603", 0 },
20493 { "601", "ppc601", 0 },
20494 { NULL
, "ppc", 0 } };
20495 const char *cpu_id
= "";
20498 rs6000_file_start ();
20499 darwin_file_start ();
20501 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
20502 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
20503 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
20504 && rs6000_select
[i
].string
[0] != '\0')
20505 cpu_id
= rs6000_select
[i
].string
;
20507 /* Look through the mapping array. Pick the first name that either
20508 matches the argument, has a bit set in IF_SET that is also set
20509 in the target flags, or has a NULL name. */
20512 while (mapping
[i
].arg
!= NULL
20513 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
20514 && (mapping
[i
].if_set
& target_flags
) == 0)
20517 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
20520 #endif /* TARGET_MACHO */
20524 rs6000_elf_reloc_rw_mask (void)
20528 else if (DEFAULT_ABI
== ABI_AIX
)
20534 /* Record an element in the table of global constructors. SYMBOL is
20535 a SYMBOL_REF of the function to be called; PRIORITY is a number
20536 between 0 and MAX_INIT_PRIORITY.
20538 This differs from default_named_section_asm_out_constructor in
20539 that we have special handling for -mrelocatable. */
20542 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
20544 const char *section
= ".ctors";
20547 if (priority
!= DEFAULT_INIT_PRIORITY
)
20549 sprintf (buf
, ".ctors.%.5u",
20550 /* Invert the numbering so the linker puts us in the proper
20551 order; constructors are run from right to left, and the
20552 linker sorts in increasing order. */
20553 MAX_INIT_PRIORITY
- priority
);
20557 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
20558 assemble_align (POINTER_SIZE
);
20560 if (TARGET_RELOCATABLE
)
20562 fputs ("\t.long (", asm_out_file
);
20563 output_addr_const (asm_out_file
, symbol
);
20564 fputs (")@fixup\n", asm_out_file
);
20567 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
20571 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
20573 const char *section
= ".dtors";
20576 if (priority
!= DEFAULT_INIT_PRIORITY
)
20578 sprintf (buf
, ".dtors.%.5u",
20579 /* Invert the numbering so the linker puts us in the proper
20580 order; constructors are run from right to left, and the
20581 linker sorts in increasing order. */
20582 MAX_INIT_PRIORITY
- priority
);
20586 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
20587 assemble_align (POINTER_SIZE
);
20589 if (TARGET_RELOCATABLE
)
20591 fputs ("\t.long (", asm_out_file
);
20592 output_addr_const (asm_out_file
, symbol
);
20593 fputs (")@fixup\n", asm_out_file
);
20596 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
20600 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
20604 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
20605 ASM_OUTPUT_LABEL (file
, name
);
20606 fputs (DOUBLE_INT_ASM_OP
, file
);
20607 rs6000_output_function_entry (file
, name
);
20608 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
20611 fputs ("\t.size\t", file
);
20612 assemble_name (file
, name
);
20613 fputs (",24\n\t.type\t.", file
);
20614 assemble_name (file
, name
);
20615 fputs (",@function\n", file
);
20616 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
20618 fputs ("\t.globl\t.", file
);
20619 assemble_name (file
, name
);
20624 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
20625 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
20626 rs6000_output_function_entry (file
, name
);
20627 fputs (":\n", file
);
20631 if (TARGET_RELOCATABLE
20632 && !TARGET_SECURE_PLT
20633 && (get_pool_size () != 0 || current_function_profile
)
20638 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
20640 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
20641 fprintf (file
, "\t.long ");
20642 assemble_name (file
, buf
);
20644 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
20645 assemble_name (file
, buf
);
20649 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
20650 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
20652 if (DEFAULT_ABI
== ABI_AIX
)
20654 const char *desc_name
, *orig_name
;
20656 orig_name
= (*targetm
.strip_name_encoding
) (name
);
20657 desc_name
= orig_name
;
20658 while (*desc_name
== '.')
20661 if (TREE_PUBLIC (decl
))
20662 fprintf (file
, "\t.globl %s\n", desc_name
);
20664 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
20665 fprintf (file
, "%s:\n", desc_name
);
20666 fprintf (file
, "\t.long %s\n", orig_name
);
20667 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
20668 if (DEFAULT_ABI
== ABI_AIX
)
20669 fputs ("\t.long 0\n", file
);
20670 fprintf (file
, "\t.previous\n");
20672 ASM_OUTPUT_LABEL (file
, name
);
20676 rs6000_elf_end_indicate_exec_stack (void)
20679 file_end_indicate_exec_stack ();
20685 rs6000_xcoff_asm_output_anchor (rtx symbol
)
20689 sprintf (buffer
, "$ + " HOST_WIDE_INT_PRINT_DEC
,
20690 SYMBOL_REF_BLOCK_OFFSET (symbol
));
20691 ASM_OUTPUT_DEF (asm_out_file
, XSTR (symbol
, 0), buffer
);
20695 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
20697 fputs (GLOBAL_ASM_OP
, stream
);
20698 RS6000_OUTPUT_BASENAME (stream
, name
);
20699 putc ('\n', stream
);
20702 /* A get_unnamed_decl callback, used for read-only sections. PTR
20703 points to the section string variable. */
20706 rs6000_xcoff_output_readonly_section_asm_op (const void *directive
)
20708 fprintf (asm_out_file
, "\t.csect %s[RO],%s\n",
20709 *(const char *const *) directive
,
20710 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
20713 /* Likewise for read-write sections. */
20716 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive
)
20718 fprintf (asm_out_file
, "\t.csect %s[RW],%s\n",
20719 *(const char *const *) directive
,
20720 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
);
20723 /* A get_unnamed_section callback, used for switching to toc_section. */
20726 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
20728 if (TARGET_MINIMAL_TOC
)
20730 /* toc_section is always selected at least once from
20731 rs6000_xcoff_file_start, so this is guaranteed to
20732 always be defined once and only once in each file. */
20733 if (!toc_initialized
)
20735 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file
);
20736 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file
);
20737 toc_initialized
= 1;
20739 fprintf (asm_out_file
, "\t.csect toc_table[RW]%s\n",
20740 (TARGET_32BIT
? "" : ",3"));
20743 fputs ("\t.toc\n", asm_out_file
);
20746 /* Implement TARGET_ASM_INIT_SECTIONS. */
20749 rs6000_xcoff_asm_init_sections (void)
20751 read_only_data_section
20752 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
20753 &xcoff_read_only_section_name
);
20755 private_data_section
20756 = get_unnamed_section (SECTION_WRITE
,
20757 rs6000_xcoff_output_readwrite_section_asm_op
,
20758 &xcoff_private_data_section_name
);
20760 read_only_private_data_section
20761 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
20762 &xcoff_private_data_section_name
);
20765 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op
, NULL
);
20767 readonly_data_section
= read_only_data_section
;
20768 exception_section
= data_section
;
20772 rs6000_xcoff_reloc_rw_mask (void)
20778 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
20779 tree decl ATTRIBUTE_UNUSED
)
20782 static const char * const suffix
[3] = { "PR", "RO", "RW" };
20784 if (flags
& SECTION_CODE
)
20786 else if (flags
& SECTION_WRITE
)
20791 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
20792 (flags
& SECTION_CODE
) ? "." : "",
20793 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
20797 rs6000_xcoff_select_section (tree decl
, int reloc
,
20798 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
20800 if (decl_readonly_section (decl
, reloc
))
20802 if (TREE_PUBLIC (decl
))
20803 return read_only_data_section
;
20805 return read_only_private_data_section
;
20809 if (TREE_PUBLIC (decl
))
20810 return data_section
;
20812 return private_data_section
;
20817 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
20821 /* Use select_section for private and uninitialized data. */
20822 if (!TREE_PUBLIC (decl
)
20823 || DECL_COMMON (decl
)
20824 || DECL_INITIAL (decl
) == NULL_TREE
20825 || DECL_INITIAL (decl
) == error_mark_node
20826 || (flag_zero_initialized_in_bss
20827 && initializer_zerop (DECL_INITIAL (decl
))))
20830 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
20831 name
= (*targetm
.strip_name_encoding
) (name
);
20832 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
20835 /* Select section for constant in constant pool.
20837 On RS/6000, all constants are in the private read-only data area.
20838 However, if this is being placed in the TOC it must be output as a
20842 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
20843 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
20845 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
20846 return toc_section
;
20848 return read_only_private_data_section
;
20851 /* Remove any trailing [DS] or the like from the symbol name. */
20853 static const char *
20854 rs6000_xcoff_strip_name_encoding (const char *name
)
20859 len
= strlen (name
);
20860 if (name
[len
- 1] == ']')
20861 return ggc_alloc_string (name
, len
- 4);
20866 /* Section attributes. AIX is always PIC. */
20868 static unsigned int
20869 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
20871 unsigned int align
;
20872 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
20874 /* Align to at least UNIT size. */
20875 if (flags
& SECTION_CODE
)
20876 align
= MIN_UNITS_PER_WORD
;
20878 /* Increase alignment of large objects if not already stricter. */
20879 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
20880 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
20881 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
20883 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
20886 /* Output at beginning of assembler file.
20888 Initialize the section names for the RS/6000 at this point.
20890 Specify filename, including full path, to assembler.
20892 We want to go into the TOC section so at least one .toc will be emitted.
20893 Also, in order to output proper .bs/.es pairs, we need at least one static
20894 [RW] section emitted.
20896 Finally, declare mcount when profiling to make the assembler happy. */
20899 rs6000_xcoff_file_start (void)
20901 rs6000_gen_section_name (&xcoff_bss_section_name
,
20902 main_input_filename
, ".bss_");
20903 rs6000_gen_section_name (&xcoff_private_data_section_name
,
20904 main_input_filename
, ".rw_");
20905 rs6000_gen_section_name (&xcoff_read_only_section_name
,
20906 main_input_filename
, ".ro_");
20908 fputs ("\t.file\t", asm_out_file
);
20909 output_quoted_string (asm_out_file
, main_input_filename
);
20910 fputc ('\n', asm_out_file
);
20911 if (write_symbols
!= NO_DEBUG
)
20912 switch_to_section (private_data_section
);
20913 switch_to_section (text_section
);
20915 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
20916 rs6000_file_start ();
20919 /* Output at end of assembler file.
20920 On the RS/6000, referencing data should automatically pull in text. */
20923 rs6000_xcoff_file_end (void)
20925 switch_to_section (text_section
);
20926 fputs ("_section_.text:\n", asm_out_file
);
20927 switch_to_section (data_section
);
20928 fputs (TARGET_32BIT
20929 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
20932 #endif /* TARGET_XCOFF */
20934 /* Compute a (partial) cost for rtx X. Return true if the complete
20935 cost has been computed, and false if subexpressions should be
20936 scanned. In either case, *TOTAL contains the cost result. */
20939 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
20941 enum machine_mode mode
= GET_MODE (x
);
20945 /* On the RS/6000, if it is valid in the insn, it is free. */
20947 if (((outer_code
== SET
20948 || outer_code
== PLUS
20949 || outer_code
== MINUS
)
20950 && (satisfies_constraint_I (x
)
20951 || satisfies_constraint_L (x
)))
20952 || (outer_code
== AND
20953 && (satisfies_constraint_K (x
)
20955 ? satisfies_constraint_L (x
)
20956 : satisfies_constraint_J (x
))
20957 || mask_operand (x
, mode
)
20959 && mask64_operand (x
, DImode
))))
20960 || ((outer_code
== IOR
|| outer_code
== XOR
)
20961 && (satisfies_constraint_K (x
)
20963 ? satisfies_constraint_L (x
)
20964 : satisfies_constraint_J (x
))))
20965 || outer_code
== ASHIFT
20966 || outer_code
== ASHIFTRT
20967 || outer_code
== LSHIFTRT
20968 || outer_code
== ROTATE
20969 || outer_code
== ROTATERT
20970 || outer_code
== ZERO_EXTRACT
20971 || (outer_code
== MULT
20972 && satisfies_constraint_I (x
))
20973 || ((outer_code
== DIV
|| outer_code
== UDIV
20974 || outer_code
== MOD
|| outer_code
== UMOD
)
20975 && exact_log2 (INTVAL (x
)) >= 0)
20976 || (outer_code
== COMPARE
20977 && (satisfies_constraint_I (x
)
20978 || satisfies_constraint_K (x
)))
20979 || (outer_code
== EQ
20980 && (satisfies_constraint_I (x
)
20981 || satisfies_constraint_K (x
)
20983 ? satisfies_constraint_L (x
)
20984 : satisfies_constraint_J (x
))))
20985 || (outer_code
== GTU
20986 && satisfies_constraint_I (x
))
20987 || (outer_code
== LTU
20988 && satisfies_constraint_P (x
)))
20993 else if ((outer_code
== PLUS
20994 && reg_or_add_cint_operand (x
, VOIDmode
))
20995 || (outer_code
== MINUS
20996 && reg_or_sub_cint_operand (x
, VOIDmode
))
20997 || ((outer_code
== SET
20998 || outer_code
== IOR
20999 || outer_code
== XOR
)
21001 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
21003 *total
= COSTS_N_INSNS (1);
21009 if (mode
== DImode
&& code
== CONST_DOUBLE
)
21011 if ((outer_code
== IOR
|| outer_code
== XOR
)
21012 && CONST_DOUBLE_HIGH (x
) == 0
21013 && (CONST_DOUBLE_LOW (x
)
21014 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)
21019 else if ((outer_code
== AND
&& and64_2_operand (x
, DImode
))
21020 || ((outer_code
== SET
21021 || outer_code
== IOR
21022 || outer_code
== XOR
)
21023 && CONST_DOUBLE_HIGH (x
) == 0))
21025 *total
= COSTS_N_INSNS (1);
21035 /* When optimizing for size, MEM should be slightly more expensive
21036 than generating address, e.g., (plus (reg) (const)).
21037 L1 cache latency is about two instructions. */
21038 *total
= optimize_size
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
21046 if (mode
== DFmode
)
21048 if (GET_CODE (XEXP (x
, 0)) == MULT
)
21050 /* FNMA accounted in outer NEG. */
21051 if (outer_code
== NEG
)
21052 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
21054 *total
= rs6000_cost
->dmul
;
21057 *total
= rs6000_cost
->fp
;
21059 else if (mode
== SFmode
)
21061 /* FNMA accounted in outer NEG. */
21062 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
21065 *total
= rs6000_cost
->fp
;
21068 *total
= COSTS_N_INSNS (1);
21072 if (mode
== DFmode
)
21074 if (GET_CODE (XEXP (x
, 0)) == MULT
21075 || GET_CODE (XEXP (x
, 1)) == MULT
)
21077 /* FNMA accounted in outer NEG. */
21078 if (outer_code
== NEG
)
21079 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
21081 *total
= rs6000_cost
->dmul
;
21084 *total
= rs6000_cost
->fp
;
21086 else if (mode
== SFmode
)
21088 /* FNMA accounted in outer NEG. */
21089 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
21092 *total
= rs6000_cost
->fp
;
21095 *total
= COSTS_N_INSNS (1);
21099 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
21100 && satisfies_constraint_I (XEXP (x
, 1)))
21102 if (INTVAL (XEXP (x
, 1)) >= -256
21103 && INTVAL (XEXP (x
, 1)) <= 255)
21104 *total
= rs6000_cost
->mulsi_const9
;
21106 *total
= rs6000_cost
->mulsi_const
;
21108 /* FMA accounted in outer PLUS/MINUS. */
21109 else if ((mode
== DFmode
|| mode
== SFmode
)
21110 && (outer_code
== PLUS
|| outer_code
== MINUS
))
21112 else if (mode
== DFmode
)
21113 *total
= rs6000_cost
->dmul
;
21114 else if (mode
== SFmode
)
21115 *total
= rs6000_cost
->fp
;
21116 else if (mode
== DImode
)
21117 *total
= rs6000_cost
->muldi
;
21119 *total
= rs6000_cost
->mulsi
;
21124 if (FLOAT_MODE_P (mode
))
21126 *total
= mode
== DFmode
? rs6000_cost
->ddiv
21127 : rs6000_cost
->sdiv
;
21134 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
21135 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
21137 if (code
== DIV
|| code
== MOD
)
21139 *total
= COSTS_N_INSNS (2);
21142 *total
= COSTS_N_INSNS (1);
21146 if (GET_MODE (XEXP (x
, 1)) == DImode
)
21147 *total
= rs6000_cost
->divdi
;
21149 *total
= rs6000_cost
->divsi
;
21151 /* Add in shift and subtract for MOD. */
21152 if (code
== MOD
|| code
== UMOD
)
21153 *total
+= COSTS_N_INSNS (2);
21158 *total
= COSTS_N_INSNS (4);
21162 *total
= COSTS_N_INSNS (6);
21166 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
21178 *total
= COSTS_N_INSNS (1);
21186 /* Handle mul_highpart. */
21187 if (outer_code
== TRUNCATE
21188 && GET_CODE (XEXP (x
, 0)) == MULT
)
21190 if (mode
== DImode
)
21191 *total
= rs6000_cost
->muldi
;
21193 *total
= rs6000_cost
->mulsi
;
21196 else if (outer_code
== AND
)
21199 *total
= COSTS_N_INSNS (1);
21204 if (GET_CODE (XEXP (x
, 0)) == MEM
)
21207 *total
= COSTS_N_INSNS (1);
21213 if (!FLOAT_MODE_P (mode
))
21215 *total
= COSTS_N_INSNS (1);
21221 case UNSIGNED_FLOAT
:
21224 case FLOAT_TRUNCATE
:
21225 *total
= rs6000_cost
->fp
;
21229 if (mode
== DFmode
)
21232 *total
= rs6000_cost
->fp
;
21236 switch (XINT (x
, 1))
21239 *total
= rs6000_cost
->fp
;
21251 *total
= COSTS_N_INSNS (1);
21254 else if (FLOAT_MODE_P (mode
)
21255 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
21257 *total
= rs6000_cost
->fp
;
21265 /* Carry bit requires mode == Pmode.
21266 NEG or PLUS already counted so only add one. */
21268 && (outer_code
== NEG
|| outer_code
== PLUS
))
21270 *total
= COSTS_N_INSNS (1);
21273 if (outer_code
== SET
)
21275 if (XEXP (x
, 1) == const0_rtx
)
21277 *total
= COSTS_N_INSNS (2);
21280 else if (mode
== Pmode
)
21282 *total
= COSTS_N_INSNS (3);
21291 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
21293 *total
= COSTS_N_INSNS (2);
21297 if (outer_code
== COMPARE
)
21311 /* A C expression returning the cost of moving data from a register of class
21312 CLASS1 to one of CLASS2. */
21315 rs6000_register_move_cost (enum machine_mode mode
,
21316 enum reg_class from
, enum reg_class to
)
21318 /* Moves from/to GENERAL_REGS. */
21319 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
21320 || reg_classes_intersect_p (from
, GENERAL_REGS
))
21322 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
21325 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
)
21326 return (rs6000_memory_move_cost (mode
, from
, 0)
21327 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, 0));
21329 /* It's more expensive to move CR_REGS than CR0_REGS because of the
21331 else if (from
== CR_REGS
)
21335 /* A move will cost one instruction per GPR moved. */
21336 return 2 * hard_regno_nregs
[0][mode
];
21339 /* Moving between two similar registers is just one instruction. */
21340 else if (reg_classes_intersect_p (to
, from
))
21341 return (mode
== TFmode
|| mode
== TDmode
) ? 4 : 2;
21343 /* Everything else has to go through GENERAL_REGS. */
21345 return (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
21346 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
21349 /* A C expressions returning the cost of moving data of MODE from a register to
21353 rs6000_memory_move_cost (enum machine_mode mode
, enum reg_class
class,
21354 int in ATTRIBUTE_UNUSED
)
21356 if (reg_classes_intersect_p (class, GENERAL_REGS
))
21357 return 4 * hard_regno_nregs
[0][mode
];
21358 else if (reg_classes_intersect_p (class, FLOAT_REGS
))
21359 return 4 * hard_regno_nregs
[32][mode
];
21360 else if (reg_classes_intersect_p (class, ALTIVEC_REGS
))
21361 return 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
21363 return 4 + rs6000_register_move_cost (mode
, class, GENERAL_REGS
);
21366 /* Returns a code for a target-specific builtin that implements
21367 reciprocal of the function, or NULL_TREE if not available. */
21370 rs6000_builtin_reciprocal (unsigned int fn
, bool md_fn
,
21371 bool sqrt ATTRIBUTE_UNUSED
)
21373 if (! (TARGET_RECIP
&& TARGET_PPC_GFXOPT
&& !optimize_size
21374 && flag_finite_math_only
&& !flag_trapping_math
21375 && flag_unsafe_math_optimizations
))
21383 case BUILT_IN_SQRTF
:
21384 return rs6000_builtin_decls
[RS6000_BUILTIN_RSQRTF
];
21391 /* Newton-Raphson approximation of single-precision floating point divide n/d.
21392 Assumes no trapping math and finite arguments. */
21395 rs6000_emit_swdivsf (rtx dst
, rtx n
, rtx d
)
21397 rtx x0
, e0
, e1
, y1
, u0
, v0
, one
;
21399 x0
= gen_reg_rtx (SFmode
);
21400 e0
= gen_reg_rtx (SFmode
);
21401 e1
= gen_reg_rtx (SFmode
);
21402 y1
= gen_reg_rtx (SFmode
);
21403 u0
= gen_reg_rtx (SFmode
);
21404 v0
= gen_reg_rtx (SFmode
);
21405 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
21407 /* x0 = 1./d estimate */
21408 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
21409 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, d
),
21411 /* e0 = 1. - d * x0 */
21412 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
21413 gen_rtx_MINUS (SFmode
, one
,
21414 gen_rtx_MULT (SFmode
, d
, x0
))));
21415 /* e1 = e0 + e0 * e0 */
21416 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
21417 gen_rtx_PLUS (SFmode
,
21418 gen_rtx_MULT (SFmode
, e0
, e0
), e0
)));
21419 /* y1 = x0 + e1 * x0 */
21420 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
21421 gen_rtx_PLUS (SFmode
,
21422 gen_rtx_MULT (SFmode
, e1
, x0
), x0
)));
21424 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
21425 gen_rtx_MULT (SFmode
, n
, y1
)));
21426 /* v0 = n - d * u0 */
21427 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
21428 gen_rtx_MINUS (SFmode
, n
,
21429 gen_rtx_MULT (SFmode
, d
, u0
))));
21430 /* dst = u0 + v0 * y1 */
21431 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
21432 gen_rtx_PLUS (SFmode
,
21433 gen_rtx_MULT (SFmode
, v0
, y1
), u0
)));
21436 /* Newton-Raphson approximation of double-precision floating point divide n/d.
21437 Assumes no trapping math and finite arguments. */
21440 rs6000_emit_swdivdf (rtx dst
, rtx n
, rtx d
)
21442 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
21444 x0
= gen_reg_rtx (DFmode
);
21445 e0
= gen_reg_rtx (DFmode
);
21446 e1
= gen_reg_rtx (DFmode
);
21447 e2
= gen_reg_rtx (DFmode
);
21448 y1
= gen_reg_rtx (DFmode
);
21449 y2
= gen_reg_rtx (DFmode
);
21450 y3
= gen_reg_rtx (DFmode
);
21451 u0
= gen_reg_rtx (DFmode
);
21452 v0
= gen_reg_rtx (DFmode
);
21453 one
= force_reg (DFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, DFmode
));
21455 /* x0 = 1./d estimate */
21456 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
21457 gen_rtx_UNSPEC (DFmode
, gen_rtvec (1, d
),
21459 /* e0 = 1. - d * x0 */
21460 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
21461 gen_rtx_MINUS (DFmode
, one
,
21462 gen_rtx_MULT (SFmode
, d
, x0
))));
21463 /* y1 = x0 + e0 * x0 */
21464 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
21465 gen_rtx_PLUS (DFmode
,
21466 gen_rtx_MULT (DFmode
, e0
, x0
), x0
)));
21468 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
21469 gen_rtx_MULT (DFmode
, e0
, e0
)));
21470 /* y2 = y1 + e1 * y1 */
21471 emit_insn (gen_rtx_SET (VOIDmode
, y2
,
21472 gen_rtx_PLUS (DFmode
,
21473 gen_rtx_MULT (DFmode
, e1
, y1
), y1
)));
21475 emit_insn (gen_rtx_SET (VOIDmode
, e2
,
21476 gen_rtx_MULT (DFmode
, e1
, e1
)));
21477 /* y3 = y2 + e2 * y2 */
21478 emit_insn (gen_rtx_SET (VOIDmode
, y3
,
21479 gen_rtx_PLUS (DFmode
,
21480 gen_rtx_MULT (DFmode
, e2
, y2
), y2
)));
21482 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
21483 gen_rtx_MULT (DFmode
, n
, y3
)));
21484 /* v0 = n - d * u0 */
21485 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
21486 gen_rtx_MINUS (DFmode
, n
,
21487 gen_rtx_MULT (DFmode
, d
, u0
))));
21488 /* dst = u0 + v0 * y3 */
21489 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
21490 gen_rtx_PLUS (DFmode
,
21491 gen_rtx_MULT (DFmode
, v0
, y3
), u0
)));
21495 /* Newton-Raphson approximation of single-precision floating point rsqrt.
21496 Assumes no trapping math and finite arguments. */
21499 rs6000_emit_swrsqrtsf (rtx dst
, rtx src
)
21501 rtx x0
, x1
, x2
, y1
, u0
, u1
, u2
, v0
, v1
, v2
, t0
,
21502 half
, one
, halfthree
, c1
, cond
, label
;
21504 x0
= gen_reg_rtx (SFmode
);
21505 x1
= gen_reg_rtx (SFmode
);
21506 x2
= gen_reg_rtx (SFmode
);
21507 y1
= gen_reg_rtx (SFmode
);
21508 u0
= gen_reg_rtx (SFmode
);
21509 u1
= gen_reg_rtx (SFmode
);
21510 u2
= gen_reg_rtx (SFmode
);
21511 v0
= gen_reg_rtx (SFmode
);
21512 v1
= gen_reg_rtx (SFmode
);
21513 v2
= gen_reg_rtx (SFmode
);
21514 t0
= gen_reg_rtx (SFmode
);
21515 halfthree
= gen_reg_rtx (SFmode
);
21516 cond
= gen_rtx_REG (CCFPmode
, CR1_REGNO
);
21517 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
21519 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
21520 emit_insn (gen_rtx_SET (VOIDmode
, t0
,
21521 gen_rtx_MULT (SFmode
, src
, src
)));
21523 emit_insn (gen_rtx_SET (VOIDmode
, cond
,
21524 gen_rtx_COMPARE (CCFPmode
, t0
, src
)));
21525 c1
= gen_rtx_EQ (VOIDmode
, cond
, const0_rtx
);
21526 emit_unlikely_jump (c1
, label
);
21528 half
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf
, SFmode
));
21529 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
21531 /* halfthree = 1.5 = 1.0 + 0.5 */
21532 emit_insn (gen_rtx_SET (VOIDmode
, halfthree
,
21533 gen_rtx_PLUS (SFmode
, one
, half
)));
21535 /* x0 = rsqrt estimate */
21536 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
21537 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, src
),
21540 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
21541 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
21542 gen_rtx_MINUS (SFmode
,
21543 gen_rtx_MULT (SFmode
, src
, halfthree
),
21546 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
21547 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
21548 gen_rtx_MULT (SFmode
, x0
, x0
)));
21549 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
21550 gen_rtx_MINUS (SFmode
,
21552 gen_rtx_MULT (SFmode
, y1
, u0
))));
21553 emit_insn (gen_rtx_SET (VOIDmode
, x1
,
21554 gen_rtx_MULT (SFmode
, x0
, v0
)));
21556 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
21557 emit_insn (gen_rtx_SET (VOIDmode
, u1
,
21558 gen_rtx_MULT (SFmode
, x1
, x1
)));
21559 emit_insn (gen_rtx_SET (VOIDmode
, v1
,
21560 gen_rtx_MINUS (SFmode
,
21562 gen_rtx_MULT (SFmode
, y1
, u1
))));
21563 emit_insn (gen_rtx_SET (VOIDmode
, x2
,
21564 gen_rtx_MULT (SFmode
, x1
, v1
)));
21566 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
21567 emit_insn (gen_rtx_SET (VOIDmode
, u2
,
21568 gen_rtx_MULT (SFmode
, x2
, x2
)));
21569 emit_insn (gen_rtx_SET (VOIDmode
, v2
,
21570 gen_rtx_MINUS (SFmode
,
21572 gen_rtx_MULT (SFmode
, y1
, u2
))));
21573 emit_insn (gen_rtx_SET (VOIDmode
, dst
,
21574 gen_rtx_MULT (SFmode
, x2
, v2
)));
21576 emit_label (XEXP (label
, 0));
21579 /* Emit popcount intrinsic on TARGET_POPCNTB targets. DST is the
21580 target, and SRC is the argument operand. */
21583 rs6000_emit_popcount (rtx dst
, rtx src
)
21585 enum machine_mode mode
= GET_MODE (dst
);
21588 tmp1
= gen_reg_rtx (mode
);
21590 if (mode
== SImode
)
21592 emit_insn (gen_popcntbsi2 (tmp1
, src
));
21593 tmp2
= expand_mult (SImode
, tmp1
, GEN_INT (0x01010101),
21595 tmp2
= force_reg (SImode
, tmp2
);
21596 emit_insn (gen_lshrsi3 (dst
, tmp2
, GEN_INT (24)));
21600 emit_insn (gen_popcntbdi2 (tmp1
, src
));
21601 tmp2
= expand_mult (DImode
, tmp1
,
21602 GEN_INT ((HOST_WIDE_INT
)
21603 0x01010101 << 32 | 0x01010101),
21605 tmp2
= force_reg (DImode
, tmp2
);
21606 emit_insn (gen_lshrdi3 (dst
, tmp2
, GEN_INT (56)));
21611 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
21612 target, and SRC is the argument operand. */
21615 rs6000_emit_parity (rtx dst
, rtx src
)
21617 enum machine_mode mode
= GET_MODE (dst
);
21620 tmp
= gen_reg_rtx (mode
);
21621 if (mode
== SImode
)
21623 /* Is mult+shift >= shift+xor+shift+xor? */
21624 if (rs6000_cost
->mulsi_const
>= COSTS_N_INSNS (3))
21626 rtx tmp1
, tmp2
, tmp3
, tmp4
;
21628 tmp1
= gen_reg_rtx (SImode
);
21629 emit_insn (gen_popcntbsi2 (tmp1
, src
));
21631 tmp2
= gen_reg_rtx (SImode
);
21632 emit_insn (gen_lshrsi3 (tmp2
, tmp1
, GEN_INT (16)));
21633 tmp3
= gen_reg_rtx (SImode
);
21634 emit_insn (gen_xorsi3 (tmp3
, tmp1
, tmp2
));
21636 tmp4
= gen_reg_rtx (SImode
);
21637 emit_insn (gen_lshrsi3 (tmp4
, tmp3
, GEN_INT (8)));
21638 emit_insn (gen_xorsi3 (tmp
, tmp3
, tmp4
));
21641 rs6000_emit_popcount (tmp
, src
);
21642 emit_insn (gen_andsi3 (dst
, tmp
, const1_rtx
));
21646 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
21647 if (rs6000_cost
->muldi
>= COSTS_N_INSNS (5))
21649 rtx tmp1
, tmp2
, tmp3
, tmp4
, tmp5
, tmp6
;
21651 tmp1
= gen_reg_rtx (DImode
);
21652 emit_insn (gen_popcntbdi2 (tmp1
, src
));
21654 tmp2
= gen_reg_rtx (DImode
);
21655 emit_insn (gen_lshrdi3 (tmp2
, tmp1
, GEN_INT (32)));
21656 tmp3
= gen_reg_rtx (DImode
);
21657 emit_insn (gen_xordi3 (tmp3
, tmp1
, tmp2
));
21659 tmp4
= gen_reg_rtx (DImode
);
21660 emit_insn (gen_lshrdi3 (tmp4
, tmp3
, GEN_INT (16)));
21661 tmp5
= gen_reg_rtx (DImode
);
21662 emit_insn (gen_xordi3 (tmp5
, tmp3
, tmp4
));
21664 tmp6
= gen_reg_rtx (DImode
);
21665 emit_insn (gen_lshrdi3 (tmp6
, tmp5
, GEN_INT (8)));
21666 emit_insn (gen_xordi3 (tmp
, tmp5
, tmp6
));
21669 rs6000_emit_popcount (tmp
, src
);
21670 emit_insn (gen_anddi3 (dst
, tmp
, const1_rtx
));
21674 /* Return an RTX representing where to find the function value of a
21675 function returning MODE. */
21677 rs6000_complex_function_value (enum machine_mode mode
)
21679 unsigned int regno
;
21681 enum machine_mode inner
= GET_MODE_INNER (mode
);
21682 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
21684 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
21685 regno
= FP_ARG_RETURN
;
21688 regno
= GP_ARG_RETURN
;
21690 /* 32-bit is OK since it'll go in r3/r4. */
21691 if (TARGET_32BIT
&& inner_bytes
>= 4)
21692 return gen_rtx_REG (mode
, regno
);
21695 if (inner_bytes
>= 8)
21696 return gen_rtx_REG (mode
, regno
);
21698 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
21700 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
21701 GEN_INT (inner_bytes
));
21702 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
21705 /* Define how to find the value returned by a function.
21706 VALTYPE is the data type of the value (as a tree).
21707 If the precise function being called is known, FUNC is its FUNCTION_DECL;
21708 otherwise, FUNC is 0.
21710 On the SPE, both FPs and vectors are returned in r3.
21712 On RS/6000 an integer value is in r3 and a floating-point value is in
21713 fp1, unless -msoft-float. */
21716 rs6000_function_value (const_tree valtype
, const_tree func ATTRIBUTE_UNUSED
)
21718 enum machine_mode mode
;
21719 unsigned int regno
;
21721 /* Special handling for structs in darwin64. */
21722 if (rs6000_darwin64_abi
21723 && TYPE_MODE (valtype
) == BLKmode
21724 && TREE_CODE (valtype
) == RECORD_TYPE
21725 && int_size_in_bytes (valtype
) > 0)
21727 CUMULATIVE_ARGS valcum
;
21731 valcum
.fregno
= FP_ARG_MIN_REG
;
21732 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
21733 /* Do a trial code generation as if this were going to be passed as
21734 an argument; if any part goes in memory, we return NULL. */
21735 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, 1, true);
21738 /* Otherwise fall through to standard ABI rules. */
21741 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
21743 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
21744 return gen_rtx_PARALLEL (DImode
,
21746 gen_rtx_EXPR_LIST (VOIDmode
,
21747 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
21749 gen_rtx_EXPR_LIST (VOIDmode
,
21750 gen_rtx_REG (SImode
,
21751 GP_ARG_RETURN
+ 1),
21754 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
21756 return gen_rtx_PARALLEL (DCmode
,
21758 gen_rtx_EXPR_LIST (VOIDmode
,
21759 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
21761 gen_rtx_EXPR_LIST (VOIDmode
,
21762 gen_rtx_REG (SImode
,
21763 GP_ARG_RETURN
+ 1),
21765 gen_rtx_EXPR_LIST (VOIDmode
,
21766 gen_rtx_REG (SImode
,
21767 GP_ARG_RETURN
+ 2),
21769 gen_rtx_EXPR_LIST (VOIDmode
,
21770 gen_rtx_REG (SImode
,
21771 GP_ARG_RETURN
+ 3),
21775 mode
= TYPE_MODE (valtype
);
21776 if ((INTEGRAL_TYPE_P (valtype
) && GET_MODE_BITSIZE (mode
) < BITS_PER_WORD
)
21777 || POINTER_TYPE_P (valtype
))
21778 mode
= TARGET_32BIT
? SImode
: DImode
;
21780 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
21781 /* _Decimal128 must use an even/odd register pair. */
21782 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
21783 else if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
21784 regno
= FP_ARG_RETURN
;
21785 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
21786 && targetm
.calls
.split_complex_arg
)
21787 return rs6000_complex_function_value (mode
);
21788 else if (TREE_CODE (valtype
) == VECTOR_TYPE
21789 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
21790 && ALTIVEC_VECTOR_MODE (mode
))
21791 regno
= ALTIVEC_ARG_RETURN
;
21792 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
21793 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DCmode
21794 || mode
== TFmode
|| mode
== TDmode
|| mode
== TCmode
))
21795 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
21797 regno
= GP_ARG_RETURN
;
21799 return gen_rtx_REG (mode
, regno
);
21802 /* Define how to find the value returned by a library function
21803 assuming the value has mode MODE. */
21805 rs6000_libcall_value (enum machine_mode mode
)
21807 unsigned int regno
;
21809 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
21811 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
21812 return gen_rtx_PARALLEL (DImode
,
21814 gen_rtx_EXPR_LIST (VOIDmode
,
21815 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
21817 gen_rtx_EXPR_LIST (VOIDmode
,
21818 gen_rtx_REG (SImode
,
21819 GP_ARG_RETURN
+ 1),
21823 if (DECIMAL_FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
21824 /* _Decimal128 must use an even/odd register pair. */
21825 regno
= (mode
== TDmode
) ? FP_ARG_RETURN
+ 1 : FP_ARG_RETURN
;
21826 else if (SCALAR_FLOAT_MODE_P (mode
)
21827 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
21828 regno
= FP_ARG_RETURN
;
21829 else if (ALTIVEC_VECTOR_MODE (mode
)
21830 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
21831 regno
= ALTIVEC_ARG_RETURN
;
21832 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
21833 return rs6000_complex_function_value (mode
);
21834 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
21835 && (mode
== DFmode
|| mode
== DDmode
|| mode
== DCmode
21836 || mode
== TFmode
|| mode
== TDmode
|| mode
== TCmode
))
21837 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
21839 regno
= GP_ARG_RETURN
;
21841 return gen_rtx_REG (mode
, regno
);
21844 /* Define the offset between two registers, FROM to be eliminated and its
21845 replacement TO, at the start of a routine. */
21847 rs6000_initial_elimination_offset (int from
, int to
)
21849 rs6000_stack_t
*info
= rs6000_stack_info ();
21850 HOST_WIDE_INT offset
;
21852 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
21853 offset
= info
->push_p
? 0 : -info
->total_size
;
21854 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
21856 offset
= info
->push_p
? 0 : -info
->total_size
;
21857 if (FRAME_GROWS_DOWNWARD
)
21858 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
21860 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
21861 offset
= FRAME_GROWS_DOWNWARD
21862 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
21864 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
21865 offset
= info
->total_size
;
21866 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
21867 offset
= info
->push_p
? info
->total_size
: 0;
21868 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
21871 gcc_unreachable ();
21876 /* Return true if TYPE is a SPE or AltiVec opaque type. */
21879 rs6000_is_opaque_type (const_tree type
)
21881 return (type
== opaque_V2SI_type_node
21882 || type
== opaque_V2SF_type_node
21883 || type
== opaque_p_V2SI_type_node
21884 || type
== opaque_V4SI_type_node
);
21888 rs6000_dwarf_register_span (rtx reg
)
21893 && (SPE_VECTOR_MODE (GET_MODE (reg
))
21894 || (TARGET_E500_DOUBLE
21895 && (GET_MODE (reg
) == DFmode
|| GET_MODE (reg
) == DDmode
))))
21900 regno
= REGNO (reg
);
21902 /* The duality of the SPE register size wreaks all kinds of havoc.
21903 This is a way of distinguishing r0 in 32-bits from r0 in
21906 gen_rtx_PARALLEL (VOIDmode
,
21909 gen_rtx_REG (SImode
, regno
+ 1200),
21910 gen_rtx_REG (SImode
, regno
))
21912 gen_rtx_REG (SImode
, regno
),
21913 gen_rtx_REG (SImode
, regno
+ 1200)));
21916 /* Fill in sizes for SPE register high parts in table used by unwinder. */
21919 rs6000_init_dwarf_reg_sizes_extra (tree address
)
21924 enum machine_mode mode
= TYPE_MODE (char_type_node
);
21925 rtx addr
= expand_expr (address
, NULL_RTX
, VOIDmode
, 0);
21926 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
21927 rtx value
= gen_int_mode (4, mode
);
21929 for (i
= 1201; i
< 1232; i
++)
21931 int column
= DWARF_REG_TO_UNWIND_COLUMN (i
);
21932 HOST_WIDE_INT offset
21933 = DWARF_FRAME_REGNUM (column
) * GET_MODE_SIZE (mode
);
21935 emit_move_insn (adjust_address (mem
, mode
, offset
), value
);
21940 /* Map internal gcc register numbers to DWARF2 register numbers. */
21943 rs6000_dbx_register_number (unsigned int regno
)
21945 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
21947 if (regno
== MQ_REGNO
)
21949 if (regno
== LR_REGNO
)
21951 if (regno
== CTR_REGNO
)
21953 if (CR_REGNO_P (regno
))
21954 return regno
- CR0_REGNO
+ 86;
21955 if (regno
== XER_REGNO
)
21957 if (ALTIVEC_REGNO_P (regno
))
21958 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
21959 if (regno
== VRSAVE_REGNO
)
21961 if (regno
== VSCR_REGNO
)
21963 if (regno
== SPE_ACC_REGNO
)
21965 if (regno
== SPEFSCR_REGNO
)
21967 /* SPE high reg number. We get these values of regno from
21968 rs6000_dwarf_register_span. */
21969 gcc_assert (regno
>= 1200 && regno
< 1232);
21973 /* target hook eh_return_filter_mode */
21974 static enum machine_mode
21975 rs6000_eh_return_filter_mode (void)
21977 return TARGET_32BIT
? SImode
: word_mode
;
21980 /* Target hook for scalar_mode_supported_p. */
21982 rs6000_scalar_mode_supported_p (enum machine_mode mode
)
21984 if (DECIMAL_FLOAT_MODE_P (mode
))
21987 return default_scalar_mode_supported_p (mode
);
21990 /* Target hook for vector_mode_supported_p. */
21992 rs6000_vector_mode_supported_p (enum machine_mode mode
)
21995 if (TARGET_PAIRED_FLOAT
&& PAIRED_VECTOR_MODE (mode
))
21998 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
22001 else if (TARGET_ALTIVEC
&& ALTIVEC_VECTOR_MODE (mode
))
22008 /* Target hook for invalid_arg_for_unprototyped_fn. */
22009 static const char *
22010 invalid_arg_for_unprototyped_fn (const_tree typelist
, const_tree funcdecl
, const_tree val
)
22012 return (!rs6000_darwin64_abi
22014 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
22015 && (funcdecl
== NULL_TREE
22016 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
22017 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
22018 ? N_("AltiVec argument passed to unprototyped function")
22022 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
22023 setup by using __stack_chk_fail_local hidden function instead of
22024 calling __stack_chk_fail directly. Otherwise it is better to call
22025 __stack_chk_fail directly. */
22028 rs6000_stack_protect_fail (void)
22030 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
22031 ? default_hidden_stack_protect_fail ()
22032 : default_external_stack_protect_fail ();
22035 #include "gt-rs6000.h"